webpack相關(guān)概念:
-
asset
: 用于圖片渣慕、字體、媒體聂喇,還有一些其他類型的文件舟奠;這些文件通常最終在輸出(output ) 中成為單個文件;或使用style-loader 等進(jìn)行內(nèi)聯(lián) -
bundle
: 由多個module組成鞍恢,“index.bundle.js” -
bundles
: 早已經(jīng)過加載和編譯的最終源文件版本 -
Chunk
: bundle由chunk 組成傻粘,chunk 包括入口chunk與子chunk每窖, chunk 會對應(yīng)輸出的bundle,但通過配置弦悉,也可不一一對應(yīng) -
entry
: 是構(gòu)建依賴圖的開始窒典,想要多個依賴文件一起注入,并且將它們的依賴導(dǎo)向到一個“chunk”時稽莉,則傳入數(shù)組瀑志; Key稱為 entryChunkName, 常見 - app:表示應(yīng)用程序。- vendor: 表示第三方庫 只有一個應(yīng)用程序入口起點(不包括vendor)的適合于 SPA應(yīng)用污秆。在多頁應(yīng)用中劈猪,使用多個應(yīng)用程序入口起點。 -
output
: 入口可以指定多個混狠,但是出口只能指定一個 -
module
: 離散功能塊岸霹,更好的抽象與封裝 -
plugins
: 在webpack 編譯時使用,類似于事件綁定;包括:打包優(yōu)化将饺、資源管理和注入環(huán)境變量 -
loader
: 在加載文件前贡避,預(yù)先處理文件,類似于任務(wù)處理器;(webpack 自身只支持 JavaScript予弧,而 loader 能夠讓 webpack 處理那些非 JavaScript 文件刮吧,并且先將它們轉(zhuǎn)換為有效 模塊,然后添加到依賴圖中掖蛤。) -
runtime
: 在瀏覽器運行時杀捻,webpack 用來連接模塊化的應(yīng)用程序的所有代碼。runtime 包含:在模塊交互時蚓庭,連接模塊所需的加載和解析邏輯致讥。包括瀏覽器中的已加載模塊的連接,以及懶加載模塊的執(zhí)行邏輯器赞。 -
manifest
: 當(dāng)編譯器(compiler)開始執(zhí)行垢袱、解析和映射應(yīng)用程序時,它會保留所有模塊的詳細(xì)要點港柜,通過使用 manifest 中的數(shù)據(jù)请契,runtime 將能夠查詢模塊標(biāo)識符,檢索出背后對應(yīng)的模塊夏醉。
總結(jié)webpack 運行過程如下:
Webpack 運行機(jī)制中的運行機(jī)制:
資料:
一:是什么
webpack 是一個模塊打包器(module bundler), 而不是執(zhí)行器(task runner)畔柔,任務(wù)執(zhí)行器就是用來自動化處理常見的開發(fā)任務(wù)氯夷,例如項目的檢查(lint)、構(gòu)建(build)靶擦、測試(test)肠槽。相對于打包器(bundler)擎淤,任務(wù)執(zhí)行器則聚焦在偏重上層的問題上面。你可以得益于秸仙,使用上層的工具,而將打包部分的問題留給 webpack桩盲。
打包器(bundler)幫助你取得準(zhǔn)備用于部署的 JavaScript 和樣式表寂纪,將它們轉(zhuǎn)換為適合瀏覽器的可用格式。例如赌结,JavaScript 可以壓縮捞蛋、拆分 chunk 和懶加載,以提高性能柬姚。
雖然有一些功能重復(fù)拟杉,但如果以正確的方式處理,任務(wù)運行器和模塊打包器能夠一起協(xié)同工作量承。
webpack 這樣的工具搬设,將動態(tài)打包(dynamically bundle)所有依賴項(創(chuàng)建所謂的依賴圖(dependency graph)),這使得在每個模塊都可以_明確表述它自身的依賴撕捍,我們將避免打包未使用的模塊拿穴。
- 使用webpack,需要瀏覽器支持Promise(需要使用polyfill)忧风。
多數(shù)瀏覽器已支持import 默色, webpack 也對import 進(jìn)行轉(zhuǎn)譯
二: assset management 資源管理
資源 | 對應(yīng)loader |
---|---|
css | Css-loader style-loader |
css 中的圖片 | css-loader |
css 中的自定義字體 | file-loader 和 url-loader 可以接收并加載任何文件,然后將其輸出到構(gòu)建目錄狮腿。 |
Js中圖片 | file-loader |
JSON | 內(nèi)置 |
XML | xml-loader |
CSV | Css-loader |
開啟css modules:
{
loader: "css-loader",
options: {
modules: true, // 指定啟用css modules
localIdentName: '[name]__[local]--[hash:base64:5]' // 指定css的類名格式
}
三:管理輸出
“__dirname”是node.js中的一個全局變量腿宰,它指向當(dāng)前執(zhí)行腳本所在的目錄。
plugin | 作用 |
---|---|
html-webpack-plugin | 默認(rèn)生成 index.html 文件 , 根據(jù)entry 與output將文件插入在index.html 中 |
clean-webpack-plugin | 在每次構(gòu)建前清理 /dist 文件 |
UglifyJSPlugin | 壓縮缘厢,打開sourceMap |
ExtractTextPlugin | 分離CSS 和JS |
四: 開發(fā)
Source map : 將編譯后的代碼映射回原始源代碼
-
devtool: 'source map'
source map.png
source map.png
會額外生成一個單獨 Source Map 文件吃度,并且會在 JavaScript 文件末尾追加 //# sourceMappingURL=bundle.js.map
-
devtool: 'hidden-source-map'
hidden-source-map.pnghidden-source-map.png
hidden-source-map 和 source-map 類似钦听,但不會在 JavaScript 文件末尾追加 //# sourceMappingURL=bundle.js.map 這樣瀏覽器就不會自動加載 Source Map心赶;
自動編譯改動文件: 3種方式
觀察模式 : "watch": "webpack --watch",
需要手動刷新瀏覽器webpack-dev-server. : 指定文件/dist
在 localhost:8080 下建立服務(wù),將 dist 目錄下的文件鹦筹,作為可訪問文件夜畴。-
webpack-dev-middleware 是一個容器(wrapper)拖刃,它可以把 webpack 處理后的文件傳遞給一個服務(wù)器(server)。 webpack-dev-server 在內(nèi)部使用了它贪绘,同時兑牡,它也可以作為一個單獨的包來使用,以便進(jìn)行更多自定義設(shè)置來實現(xiàn)更多的需求 運行一個簡單的開發(fā)服務(wù)器(development server)
publicPath : 設(shè)置的訪問靜態(tài)文件的路徑 /a/index.html
五: HMR (模塊熱替換)
模塊熱替換(HMR - Hot Module Replacement)功能一個修改税灌、添加或刪除模塊(modules)的過程均函,而正在運行中的應(yīng)用程序無需重載加載整個頁面亿虽。只適合在開發(fā)時使用。
1. new webpack.HotModuleReplacementPlugin() 是webpack 內(nèi)置的功能
直接啟用 hot: true 即可以使用苞也, 但是會出現(xiàn)很多問題洛勉。
六: tree shaking
tree shaking 用于描述移除 JavaScript 上下文中的未引用代碼(dead-code)。它依賴于 ES2015 模塊系統(tǒng)中的靜態(tài)結(jié)構(gòu)特性如迟,例如 import 和 export
將文件標(biāo)記為無副作用(side-effect-free)
在package.json 中 標(biāo)記"sideEffects": false
mode: "production”收毫, 配置選項輕松切換到壓縮輸出, 來啟用 UglifyJSPlugin 插件
七: 開發(fā)環(huán)境的構(gòu)建
將公共設(shè)置提出使用webpack-merge 庫
修改npm script - - config
指定環(huán)境—使用webpack 中內(nèi)置的DefinePlugin
new webpack.DefinePlugin({
'process.env.NODE_ENV': JSON.stringify('production')
})
八: 代碼分離
- 入口起點:使用 entry 配置手動地分離代碼殷勘。(重復(fù)打包)
- 防止重復(fù):使用 SplitChunks 去重和分離 chunk此再。
- 動態(tài)導(dǎo)入:通過模塊的內(nèi)聯(lián)函數(shù)調(diào)用來分離代碼。
推薦使用import() 語法玲销。import(/* webpackChunkName: "lodash" */ 'lodash')
bundle 分析 输拇,webpack 提供了官方分析工具,還有社區(qū)支持的工具贤斜,用以檢測bundle所占空間等策吠;
output.chunkFilename,它決定非入口 chunk 的名稱
九: 懶加載
在用戶交互時進(jìn)行懶加載蠢古, 實際是采用import() 的動態(tài)導(dǎo)入的方式實現(xiàn)
button.onclick = e => **import**(/* webpackChunkName: "print" */ './print').then(module => {
var print = module.default;
print();
});
十:緩存
只要 /dist 目錄中的內(nèi)容部署到服務(wù)器上奴曙,客戶端(通常是瀏覽器)就能夠訪問網(wǎng)站此服務(wù)器的網(wǎng)站及其資源。而最后一步獲取資源是比較耗費時間的草讶,這就是為什么瀏覽器使用緩存 技術(shù)洽糟。可以通過命中緩存堕战,以降低網(wǎng)絡(luò)流量坤溃,使網(wǎng)站加載速度更快,然而嘱丢,如果我們在部署新版本時不更改資源的文件名薪介,瀏覽器可能會認(rèn)為它沒有被更新,就會使用它的緩存版本越驻。
通過必要的配置汁政,以確保 webpack 編譯生成的文件能夠被客戶端緩存,而在文件內(nèi)容變化后缀旁,能夠請求到新的文件记劈。
部署一致性(deploying consistent)和資源可緩存(cachable assets)方面
output.filename 進(jìn)行文件名替換,可以確保瀏覽器獲取到修改后的文件并巍, [hash] 替換可以用于在文件名中包含一個構(gòu)建相關(guān)(build-specific)的 hash目木,但是更好的方式是使用 [chunkhash] 替換,在文件名中包含一個 chunk 相關(guān)(chunk-specific)的哈希懊渡。
這種情況刽射,不更改文件军拟,重新構(gòu)建,hash 仍會變化誓禁, 是由于某些樣板代碼的原因-
提取模板(Extracting Boilerplate) 創(chuàng)建單個運行時的bundle
通過 optimization.splitChunks 添加如下 cacheGroups 參數(shù)懈息,將第三方庫(library)(例如 lodash 或 react)提取到單獨的 vendor chunk 文件中
這種情況,當(dāng)只有src中文件發(fā)生變化時现横,重新構(gòu)建漓拾,發(fā)現(xiàn)vendor 文件也發(fā)生變化 2的情況通過webpack.HashedModuleIdsPlugin 進(jìn)行解決
十三:漸進(jìn)式網(wǎng)絡(luò)應(yīng)用程序(PWA)
漸進(jìn)式網(wǎng)絡(luò)應(yīng)用程序(Progressive Web Application - PWA),是一種可以提供類似于原生應(yīng)用程序(native app)體驗的網(wǎng)絡(luò)應(yīng)用程序(web app)戒祠。PWA 可以用來做很多事。其中最重要的是速种,在離線(offline)時應(yīng)用程序能夠繼續(xù)運行功能姜盈。這是通過使用名為 Service Workers 的網(wǎng)絡(luò)技術(shù)來實現(xiàn)的
通過使用workbox-webpack-plugin 插件
十四: 使用環(huán)境變量
使用env 可進(jìn)行環(huán)境變量的配置,但必須將 module.exports 轉(zhuǎn)換成一個函數(shù)
十九: 公共路徑
為項目中的所有資源指定一個基礎(chǔ)路徑配阵,成為公共路徑(publicPath)馏颂。