網站首頁 編程語言 正文
為什么需要構建工具?
- 處理其他類型文件使其能被瀏覽器正常加載 —— 許多其他類型的文件需要編譯處理為 ES6 模塊才能被瀏覽器正常加載(JSX、Vue、TS、CSS、Image 等)。
- 解決引用路徑的問題 —— 許多第三方依賴包在通過第三方 URL 引用時,不僅過程煩瑣,而且往往難以進行靈活的版本控制與更新,因此需要構建工具來解決這類問題。
- 為開發提供輔助工具 —— 對于現實中的項目開發而言,一些便利的輔助開發技術,例如熱更新、sourceMap 等還是需要由構建工具來提供。
什么是無包構建
它的構建方式是:
- 在構建時只需處理模塊的編譯而無須打包,把模塊間的相互依賴關系完全交給瀏覽器來處理。
- 瀏覽器會加載入口模塊,分析依賴后,再通過網絡請求加載被依賴的模塊。
這種通過瀏覽器原生的模塊進行解析的方式又稱為 Native-ESM(Native ES Module)。
//./src/index.html ... <!-- 注意: type="module" --> <script type="module" src="./modules/foo.js"></script> ... //.src/modules/foo.js import { bar } from './bar.js' import { appendHTML } from './common.js' ... import('https://cdn.jsdelivr.net/npm/lodash-es@4.17.15/slice.js').then((module) => {...})
基于瀏覽器的 JS 模塊加載功能
HTML 中的 Script 引用注意點:
- 入口模塊文件在頁面中引用時需要帶上 type="module" 屬性。
- 帶有 type="module" 屬性的 script在瀏覽器中通過 defer 的方式異步執行(異步下載,不阻塞 HTML,順次執行),即使是行內的 script 代碼也遵循這一原則(而普通的行內 script 代碼則忽略 defer 屬性)。
- 帶有 type="module" 屬性且帶有 async 屬性的 script,在瀏覽器中通過 async 的方式異步執行(異步下載,不阻塞 HTML,按該模塊和所依賴的模塊下載完成的先后順序執行,無視 DOM 中的加載順序),即使是行內的 script 代碼,也遵循這一原則(而普通的行內 script 代碼則忽略 async 屬性)。
- 即使多次加載相同模塊,也只會執行一次。
模塊內依賴的引用
- 只能使用 import ... from '...' 的 ES6 風格的模塊導入方式,或者使用 import(...).then(...) 的 ES6 動態導入方式,不支持其他模塊化規范的引用方式(例如 require、define 等)。
- 導入的模塊只支持使用相對路徑('/xxx', './xxx', '../xxx')和 URL 方式('
https://xxx
', 'http://xxx
')進行引用,不支持直接使用包名開頭的方式('xxxx', 'xxx/xxx')。 - 只支持引用MIME Type為 text/javascript 方式的模塊,不支持其他類型文件的加載(例如 CSS 等)。
無包構建工具的介紹:
Vite
Vite 是 Vue 框架的作者尤雨溪最新推出的基于 Native-ESM 的 Web 構建工具。
在開發環境下基于 Native-ESM 處理構建過程,只編譯不打包,在生產環境下則基于 Rollup 打包。
Vite對導入模塊的解析
對 HTML 文件的預處理
啟動 Vite 時,會通過 serverPluginHtml.ts 注入 /vite/client 運行時的依賴模塊,該模塊用于處理熱更新,以及提供更新 CSS 的方法 updateStyle。
對外部依賴包的解析
- resolver.ts 負責找到對應在 node_modules 中的真實依賴包代碼(Vite 會在啟動服務時對項目 package.json 中的 dependencies 做預處理讀取并存入緩存目錄 node_modules/.vite_opt_cache 中)。
- serverPluginModuleRewrite.ts 負責把源碼中的 bare modules 加上 /@module/ 前綴。
- serverPluginModuleResolve.ts 負責解析加上前綴后的模塊。
對 Vue文件的解析
對 Vue 文件的解析是通過 serverPluginVue.ts 處理的,分離出 Vue 代碼中的 script/template/style 代碼片段,并分別轉換為 JS 模塊,然后將 template/style 模塊的 import寫到script 模塊代碼的頭部。
對 CSS 文件的解析
對 CSS 文件的解析是通過 serverPluginCSS.ts 處理的,解析過程主要是將 CSS 文件的內容轉換為下面的 JS 代碼模塊,其中的 updateStyle 由注入 HTML 中的 /vite/client 模塊提供
import { updateStyle } from "/vite/client" const css = "..." updateStyle(""..."", css) // id, cssContent export default css
Vite 中的其他輔助功能
- 多框架:除了在默認的 Vue 中使用外,還支持在 React 和 Preact 項目中使用。
- 熱更新(HMR) :默認提供的 3 種框架的腳手架模板中都內置了 HMR 功能,同時也提供了 HMR 的 API 供第三方插件或項目代碼使用。
- 自定義配置文件:支持使用自定義配置文件來細化構建配置,配置項功能參考 config.ts。
- HTTPS 與 HTTP/2:支持使用 --https 啟動參數來開啟使用 HTTPS 和 HTTP/2 協議的開發服務器。
- 服務代理:在自定義配置中支持配置代理,將部分請求代理到第三方服務。
- 模式與環境變量:支持通過 mode 來指定構建模式為 development 或 production。相應模式下自動讀取 dotenv 類型的環境變量配置文件(例如 .env.production.local)。
- 生產環境打包:生產環境使用 Rollup 進行打包,支持傳入自定義配置,配置項功能參考 build/index.ts。
Vite 的使用限制
- 面向支持 ES6 的現代瀏覽器,在生產環境下,編譯目標參數 esBuildTarget 的默認值為 es2019,最低支持版本為 es2015(因為內部會使用 esbuild 處理編譯壓縮,用來獲得最快的構建速度)。
- 對 Vue 框架的支持目前僅限于最新的 Vue 3 版本,不兼容更低版本。
Snowpack
- 從整體功能來說和上述 Vite工具提供的功能大致相同。
- Snowpack 在生產環境下默認使用無包構建而非打包模式。
與 Vite 相同的功能點
兩者都支持各種代碼轉換加載器、熱更新、環境變量(需要安裝 dotenv 插件)、服務代理、HTTPS 與 HTTP/2 等。
與 Vite 的差異點
- 相同的功能,實現細節不同: 例如對 Bare Module 的處理,除了轉換后前綴名稱不同外(Vite 使用 /@module/ 前綴,而 Snowpack 使用 /web_modules/ 前綴)
- 工具穩定性
- 插件體系: 除了版本差異外,Snowpack 提供了較完善的插件體系,支持用戶和社區發布自定義插件。
- 打包工具:在生產環境下,Vite 使用 Rollup 作為打包工具,而 Snowpack 則需要引入插件來實現打包功能,官方支持的打包插件有 @snowpack/plugin-webpack 和 @snowpack/plugin-parcel,暫未提供 Rollup 對應的插件。
- 特殊優化:Vite 中內置了對 Vue 的大量構建優化,因此對 Vue 項目而言,選擇 Vite 通常可以獲得更好的開發體驗。
無包構建 VS 打包構建
無包構建的優點
- 初次構建啟動快: 無包構建流程中,模塊依賴分析與編譯都是在瀏覽器渲染頁面時異步處理的
- 按需編譯:在瀏覽器渲染時,根據入口模塊分析加載所需模塊,編譯過程按需處理,因此相比之下處理內容更少,速度也會更快。
- 增量構建速度快:rebuild 過程中,只需處理編譯單個模塊。
無包構建的缺點
- 瀏覽器網絡請求數量劇增: 無包構建最主要面對的問題是,它的運行模式決定了在一般項目里,渲染頁面所需發起的請求數遠比打包構建要多得多,使得打開頁面會產生瀑布式的大量網絡請求,將對頁面的渲染造成延遲。這也是 Vite 在開發環境下才使用無包構建,在生產環境下則仍舊使用打包構建的原因吧。
- 瀏覽器的兼容性:
原文鏈接:https://juejin.cn/post/7132120567410327566
相關推薦
- 2022-11-01 使用react在修改state中的數組和對象數據的時候(setState)_React
- 2023-07-02 python中編寫config文件并及時更新的方法_python
- 2023-02-09 sql?IDENTITY_INSERT對標識列的作用和使用_MsSql
- 2022-10-16 Python3列表刪除的三種方式實現_python
- 2022-03-21 windows設置開機自動運行批處理的方法_DOS/BAT
- 2021-12-05 密碼學之apache部署https介紹_Linux
- 2023-04-01 Python使用pptx實現復制頁面到其他PPT中_python
- 2022-03-20 docker中容器數據卷volume介紹_docker
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支