最終鼓起勇氣把公司五年的webpack老專案改成了vite

語言: CN / TW / HK

theme: awesome-green

一.【 升級原因 】

工程現狀:

1. 專案較早 + 程式碼量大 + 外掛類庫版本低 + 各個節點優化空間逐漸變小

2. 為接下來Pro工程瘦身做準備;

造成的困擾:

PS:在以上問題的基礎上,webpack已經變得非常不好用了

開發環境服務的不穩定性,嚴重影響開發效率和心情;

打包後輸出檔案過大,導致執行環境速度慢、系統性能低;

改造目標:

1. webpack 升級 為 vite;

2. node版本調整;

3. sass 版本升級;

二.【 改造思路 】

版本庫描述:

1. 整體保持[email protected]核心基礎庫不動

2. 使用[email protected]替換[email protected]

3. NodeJs版本v14.19.1升級到v18.7.0(後因版本過高,降回原版本v14.19.1)

4. Npm版本v6.14.16升級到v8.15.0

5. 升級[email protected][email protected](後因版本過高,降回原版本v4.7.2)

6. 使用[email protected]

7. 升級[email protected][email protected]

8. 引用[email protected]使vue2支援vite

思路描述:

按需調整和配置,修改編譯環境和執行環境的錯誤,最終經過測試階段,程式碼推送線上

分支保全方案:

origin/dev    dev環境原始碼

origin/propre2  pre環境原始碼

origin/pro    線上環境原始碼

origin/config_vite_nyz_221108  vite配置測試分支

origin/config_webpack_backup_nyz_221109  webpack配置備份分支(拉取自pro分支)

三.【 升級報告 】

| 類目 | webpack(升級前) | vite(升級後) | | --------- | ------------ | ---------- | | 本地服務啟動時長 | 230 秒 | 3 秒 | | 修改後熱更新時長 | 23 秒 | 1 秒 | | 本地服務效能 | 更新慢 & 服務經常崩潰 | 更新快 & 服務穩定 | | 執行打包任務時長 | 300秒 | 55 秒 | | 打包後輸出檔案大小 | 37.0 MB | 19.8 MB | | 打包後輸出檔案個數 | 1372 個 | 787 個 | | 依賴包優化後個數 | 103 個 | 82 個 | | 執行環境相容性驗證 | -- | -- |

四.【 執行過程 】
  1. 初始化一個vite專案

// 注意:這裡vite的版本採用2.8.0的,最新的版本建立後續會出現問題 // 要選擇vanilla原生專案 , 因為選擇vue會預設走vue3,造成與當前版本不匹配 npm init [email protected]

  1. 將原專案的src資料夾和其他用到的檔案/資料夾移入新專案
  1. 合併package.json的依賴項,script命令拋棄webpack,保留vite的兩條指令

"scripts": { "serve": "cross-env NODE_ENV=development vite", "build": "cross-env NODE_ENV=production vite build" },

  1. 刪除外層初始化的main.js,移入或保留原專案的main.js到src下
  1. index.html修改入口引入方式

    <script type="module" src="src/main.js"></script>

  1. main.js修改根的掛載方式

    ``` // // 原始碼 // new Vue({ // el: '#app', // router, // store, // render: h => h(App) // })

    // 目的碼 new Vue({ router, store, render: h => h(App) }).$mount('#app') ```

  1. 使用cnpm快速下載相關依賴包

    cnpm install

  1. NodeJs版本不一致,導致[node-sass]找不到並報錯,直接拉取latest版本

    cnpm install --save-dev sass sass-loader node-sass

  1. 啟動本地服務報錯:require is not defined

    原因:vite預設使用es6標準的 import 的匯入方式,不支援require引入

    // 下載 cnpm install vite-plugin-require-transform

    // vite.config.js 引入 import requireTransform from 'vite-plugin-require-transform' // vite.config.js 使用 defineConfig({ plugins: [ createVuePlugin(), requireTransform({ fileRegex: /.vue$|.js$|.json$|.ts$|.tsx$/ }) ] })

  1. 服務編譯的時候,頭部註釋資訊報錯 , 如下圖,

    原因:語法編譯不通過

    解決:涉及檔案較多,全部找出來注掉就可以了

  1. 編譯報錯:Failed to fetch dynamically imported module

    原因:vue檔案引入錯誤,構建過程無法補全檔案字尾並讀取

    解決:把vue和js相關引入程式碼全部加上字尾 ( 涉及程式碼較多,找出來全部改掉 )

  1. 樣式的deep語法報錯,找出來全部替換掉

    /deep/ 替換為 ::v-deep

  1. 編譯報錯:process is not defined

    // vite.config.js define: { 'process.env': {} }

  1. 專案中使用的環境變數報錯

    解決:webpack升級vite後,需要建立環境變數檔案並使用vite的環境變數

    process.env // webpack import.meta.env // vite

  1. 編譯報錯:Module “path” has been externalized for brower compatibility and cannot be accesed in client code

    原因:path模組無法在客戶端程式碼中使用 , webpack自動幫我們處理了node內建模組 , vite沒有

    解決:安裝 path-browserify 代替 path 模組

    cnpm install path-browserify

    import path from 'path' 改為 import path from 'path-browserify'

  1. require相容配置,某些三方包中的require語法,在開發環境正常,打包環境報錯

    // vite.config.js build:{ commonjsOptions: { transformMixedEsModules: true } }

  1. 打包報錯:[commonjs] Identifier '_vite_plugin_require_transform_Component' has already

    原因:錯誤所指的意思是echarts 庫中宣告的變數已存在,還有再宣告的必要嗎?

    解決:實則該變數並沒有重複宣告,所以改動CDN引入的方案,並刪掉頁面import引入語句

    注意:CDN要引入對應的版本

    jsdelivr相關庫檔案的CDN地址:http://www.jsdelivr.com/package/npm/echarts

    // echart主入口和單獨引入的功能 改為cdn引入 // index.html 引入以下程式碼 <script src="http://cdn.jsdelivr.net/npm/[email protected]/dist/echarts.min.js"></script> <script src="http://cdn.jsdelivr.net/npm/[email protected]/map/js/china.js"></script>

  1. 打包報錯:'default' is not exported by node_modules/[email protected]@core-js

    解決:rollup本身是不支援CommonJS的,使用了這個外掛,就可以解析CommonJS模組了

    rollup.js相關配置資料:http://rollupjs.org/guide/en/#outputentryfilenames

    cnpm install @rollup/plugin-commonjs -D

    // vite.config.js import commonjs from '@rollup/plugin-commonjs'; plugins: [ commonjs() ]

  1. 打包報錯:Error: 'default' is not exported by node_modules/[email protected]

    原因:該程式碼中的防抖節流方法沒有預設丟擲

    解決:使用自定義封裝方法或工具庫平替即可

  1. 打包成功後部署至測試環境:Uncaught TypeError: Illegal invocation,報錯如下圖

    原因:檢視報錯位置,可能是因為程式碼編譯轉換過程產生的錯誤

    解決:故調整庫版本和引入方式

    ``` 1. es6-promise 引入方式調整

    // require引入方式去掉 require('es6-promise').polyfill()

    改為

    // index.html 引入