天天看點

webpack 項目接入Vite的通用方案介紹(上)

webpack 項目接入Vite的通用方案介紹(上)

通過本文,能給讀者提供一個存/增量項目接入Vite的點子,起抛磚引玉的作用,減少這方面能力的建設成本

希望通過本文,能給讀者提供一個存/增量項目接入Vite的點子,起抛磚引玉的作用,減少這方面能力的建設成本

在闡述過程中同時也會逐漸完善webpack-vite-serve這個工具

讀者可直接fork這個工具倉庫,針對個人/公司項目場景進行定制化的二次開發

在當下的業務開發中處處可見webpack的身影,大部分的業務項目采用的建構工具也都是它。

随着時間的推移,存量老項目體積越來越大,開發啟動(dev)/建構(build) 需要的時間越來越長。針對webpack的優化手段越來越有限。

于是乎某些場景出現了用其它語言寫的工具,幫助建構/開發提效。如SWC(Rust),esbuild(Go)

當然上述工具并不是一個完整的建構工具,不能取代webpack直接使用,隻是通過plugin,為webpack工作提效

當下另一種火熱的方案是<code>bundleless</code>,利用浏覽器原生支援<code>ES Module</code>的特性,讓浏覽器接管"打包"工作,工具隻負責對浏覽器請求的資源進行相應的轉換,進而極大的減少服務的啟動時間,提升開發體驗與開發幸福感

比較出名的兩個産品就是snowpack與Vite

本文的主角就是<code>Vite</code>:下一代前端開發與建構工具

由于<code>Vite</code>的周邊還處于建設期,要完全替代webpack,還需要一定時日,為了保證存量線上項目的穩定性,<code>Vite</code>作為一個開發時可選的能力接入是比較推薦的一個做法。

為webpack項目開發環境提供最簡單的Vite接入方案

待接入項目隻需要做極小的變動就能享受到<code>Vite</code>帶來的開發樂趣

做一個CLI工具,封裝Vite啟動項目的能力

将Vite相關的配置全部收斂于插件内,自動将webpack配置轉化為Vite配置

對外提供一些可選參數,用于手動指定配置檔案的位置

webpack 項目接入Vite的通用方案介紹(上)
webpack 項目接入Vite的通用方案介紹(上)

在最簡單的Demo工程中,Vite的啟動/HMR速度也是明顯比webpack快不少的

其它常見項目類型的demo也會逐漸的完善到源碼倉庫中

完整的工程結構移步倉庫

注冊一個啟動方法<code>start</code>

<code>src/bin.ts</code>

<code>package.json</code>中添加指令

其中<code>wvs</code>為自定義的指令

<code>npm run dev</code>:利用<code>typescript</code>依賴提供的指令,監聽檔案變動,自動将其轉換<code>js</code>檔案

項目根目錄執行<code>npm link</code>,注冊指令

測試

webpack 項目接入Vite的通用方案介紹(上)

緊接着我們用Vue-CLI和Create React App分别建立兩個webpack的SPA應用進行接下來的實驗

webpack 項目接入Vite的通用方案介紹(上)

<code>Vite</code>的啟動比較簡單,隻需要執行<code>vite</code>這個指令就行s

webpack 項目接入Vite的通用方案介紹(上)

在我們的CLI工具裡使用spawn建立子程序啟動<code>Vite</code>

其中<code>cwd</code>用于指定子程序的工作目錄

stdio:子程序的标準輸入輸出配置

這裡為了友善調試,咱們全局安裝一下<code>Vite</code>

在啟動模闆<code>public/index.html</code>裡添加一個<code>&lt;h1&gt;Hello Vite&lt;/h1&gt;</code>

在demo項目裡運作<code>wvs start</code>

webpack 項目接入Vite的通用方案介紹(上)

打開對應位址

得到了如下的結果,提示找不到頁面(意料之中)

webpack 項目接入Vite的通用方案介紹(上)

通過文檔得知,Vite會預設尋找<code>index.html</code>作為項目的入口檔案

webpack 項目接入Vite的通用方案介紹(上)

這就帶來了第一個要處理的問題,多頁應用下可能有多個模闆檔案

如何根據通路路由動态的指定這個<code>x.html</code>的入口?

在解決問題之前,咱們再簡單完善一下啟動指令,為其指定一個vite.config.js 配置檔案

通過<code>vite --help</code>,可以看到通過<code>--config</code>參數指定配置檔案位置

webpack 項目接入Vite的通用方案介紹(上)

這裡指向配置檔案的絕對路徑

config/vite.ts

拓展Vite的能力就是定制各種的插件,根據插件文檔

編寫一個簡單的<code>plugin</code>,利用<code>configServer</code>鈎子,讀取浏覽器發起的資源請求

在上述的配置檔案中引入

再次啟動服務觀察

通路<code>http://localhost:3000</code>,終端中輸出<code>/</code>

通路<code>http://localhost:3000/path1/path2</code>,終端中輸出<code>/path1/path2</code>

通路<code>http://localhost:3000/path1/path2?param1=123</code>,終端中輸出<code>/path1/path2?param1=123</code>

在 devTools面闆内容中可以看到,第一個資源請求頭上的<code>Accept</code>字段中帶有<code>text/html,application/xhtml+xml</code>等内容,咱們就以這個字段表明請求的是<code>html</code>文檔

webpack 項目接入Vite的通用方案介紹(上)

再次修改一下處理資源請求的代碼

再次在demo中啟動服務,通路就能正确看到<code>Hello Vite</code>

在終端中會發現一個報錯

打開模闆可以發現是由于有一些其它的内容,裡面包含一些變量,這部分在webpack中是由 html-webpack-plugin插件處理

這裡編寫一個簡單的方法對模闆先做一些簡單處理(這個方法隻處理了目前遇到的這種情況)

如果模闆中還有複雜的ejs文法可以使用 <code>ejs</code> 庫做進一步處理

當然如果還有其它未考慮到的case,可根據特定情況,再對模闆做進一步的處理

下面将上述編寫的方法內建到插件中

到此再次在demo中運作,頁面跑起來了,終端中也無報錯,頁面的模闆到此算是處理完畢

有了初始的模闆,就意味着我們已經為<code>Vite</code>提供了頁面的入口,但其中還沒有處理的<code>js/ts</code>的依賴即 <code>entry</code>

下面将介紹往模闆中插入entry

入口檔案名(entryName)通常為<code>(main|index).js|ts|jsx|tsx</code>

單頁應用(SPA)中entryBase通常為:<code>src</code>

多頁應用(MPA)中entryBase通常為:<code>src/pages/${pageName}</code>

利用<code>transformIndexHtml</code>鈎子往模闆中插入<code>&lt;script type="module" src="entryFile"&gt;&lt;/script&gt;</code>

這裡以SPA為例

<code>getEntryFullPath</code> 實作如下

先判斷目錄是否存在

讀取目錄,周遊檔案利用正則<code>/(index|main)\.[jt]sx?$/</code>判斷檔案是否為目标檔案

将這個插件加入到配置裡

啟動demo檢視效果,抛出了一堆錯誤

下面是針對架構特定的處理

React: the content contains invalid JS syntax

React中将帶有jsx文法的js檔案字尾改為jsx,關于直接在js中使用jsx文法的處理方案,見文章:解決Vite-React項目中.js使用jsx文法報錯的問題

Uncaught ReferenceError: React is not defined

在 react元件頂部引入<code>React</code>,或引入<code>@vitejs/plugin-react</code>插件,同下3處理方案

HMR支援

引入@vitejs/plugin-react插件

需要添加插件處理.vue檔案

引入@vitejs/plugin-vue插件

同時 <code>@vitejs/plugin-vue</code> 需要 <code>vue</code> (&gt;=3.2.13)

由于前面采用的是<code>npm link</code>建立軟連接配接進行的調試,配置檔案中會在開發目錄下去查找Vue依賴,不會在指令運作目錄下查找,會不斷的抛出上述問題

這裡在demo項目裡本地安裝我們的依賴,然後在package.json添加相關指令

<code>Vue</code>項目中并沒有<code>React</code>相關依賴,是以在Vue項目中不能引入<code>@vitejs/plugin-react</code>插件

可以在指令入口添加架構相關參數判斷處理一下,隻引入對應架構的插件

到此最關鍵的兩個步驟就算完成了

目前針對webpack常見的能力,社群已經有了許多插件和方案,下面隻做簡單介紹

這些插件當然也有些場景可能處理不了,還是期望廣大開發者,勇于實驗,然後向插件作者送出PR/issues

Sass/Less:在依賴中安裝<code>Sass/Less</code>即可

元件庫按需引入:vite-plugin-style-import

process.env:vite-plugin-env-compatible

window.xx/xx undefined:使用<code>transformIndexHtml</code>鈎子開發插件,在模闆中提前引入這個方法的<code>polyfill</code>或者兜底處理

...

企業:大部分是擁有自己的研發架構,在研發架構中隻需要加入一個Vite啟動的CLI指令,這樣對接入方的影響與使用成本是最小的

個人:喜歡折騰/不想改動原來的代碼,可以按上述流程自己接一下,新項目可以直接使用Vite官方模闆開發

總之:開發中使用<code>Vite</code>還是很香的

由于篇幅與時間都有限,文中部分地方隻介紹了實作思路,并沒粘貼完整代碼,完整代碼可在源碼倉庫中檢視,也可<code>fork</code>直接進行二次開發

<code>webpack</code>向<code>vite</code>配置的轉換這部分的内容将放在下期做介紹

"你的指尖,擁有改變世界的力量! "

歡迎關注我的個人部落格:https://sugarat.top

繼續閱讀