Webpack 屬於在項目中配置一次就不多改動的那種工具,但這樣就致使新項目再配置 Webpack 時會有些生疏,因此將 Webpack 核心概念及經常使用配置記錄以下。css
Webpack 4.x 以前的核心概念有四個:entry,output,loaders,plugins,4.x 以後增長了 mode。含義以下:html
module
對象下面,由於 loaders 處理後返回的是有效 modules。Loaders 將特定文件轉換爲有效 module,而 plugin 擴展性更強vue
development
、production
、none
三個值,通常指定爲前兩個值的一種,webpack 內部針對不一樣環境作優化。下面介紹的配置都是module.exports
的直接屬性,好比:node
module.exports = { |
同時,文件頭引入相應依賴的過程省略了,實際開發中請自行引入。jquery
Entry 指定哪些文件做爲 webpack 打包入口,能夠有一個或者多個:webpack
entry: { |
Output 指明 Webpack 處理完成後的 bundles 輸入位置及文件 name:git
output: { |
Output 配置相對複雜:es6
即輸出文件目錄,推薦使用絕對路徑,其中__dirname
在 Node 的 path 模塊中表示當前目錄(即 webpack.config.js 的目錄)的絕對路徑,resolve
方法能夠拼接兩個目錄;github
後一個目錄能夠加
/
也能夠不加,此處無差異web
表示輸出文件名稱,這裏注意,[]
中是變量,其中name
由在 entry 中定義的文件名決定,而且,有多少個輸入文件,對應有多少個輸出文件,後面的contenthash:8
表示 chunk 的 hash 值,後文介紹;
實際輸出文件通常多於輸入文件,由於提取公共代碼、設置 sourcemap 都會單獨生成輸出文件
這個配置想最爲複雜,它的做用是配合 loaders 或 plugins 中設置的資源路徑,指定靜態文件(css、js、img)插入 html 中的引用路徑,簡單講,就是 對輸出的靜態資源進行目錄管理。這裏直接使用 詳解 Webpack2 的那些路徑的描述,只稍做說明。
靜態資源最終引用路徑計算公式:
html 靜態資源路徑 = output.publicPath + loaders/plugins 中設置的資源路徑
好比:
// publicPath 設置 |
咱們上述指定publicPath
爲絕對路徑,實際上,也支持相對路徑,相對於index.html
,用的比較少。
publicPath
默認爲空字符串,但爲了使輸出目錄更加條理,推薦使用publicPath
對靜態資源進行目錄管理。
Loaders 的配置寫在module
對象中,如前所述,由於 loaders 最終返回的是有效 modules,故使用了module
命名,注意是單數。這節介紹 loaders 配置及經常使用 loaders 兩部份內容。
loaders 規則寫在 module.rules
裏面(不知道爲何不直接寫在 module
中),其中 rules
是個數組,可接受一個或多個 loader 配置。兩點須要注意:
1)若是某類型須要多個 loader 進行處理,在 use
中按 從右往左 的順序流式處理;
2)每一個 loader 能夠進行額外配置。
module: { |
postcss 自己支持插件擴展,經常使用的有 autoprefixer、cssnano、postcss-sprites,更多參考官網介紹
要在 css-loader 以前處理 css:use: [MiniCssExtractPlugin.loader, 'css-loader', 'postcss-loader']
Vue 相關
同 loaders 同樣,分配置和經常使用 plugins 兩部分
Plugins 使用相對簡單,配置項寫在plugins
(複數)數組中,元素爲插件的實例(經過new
調用),生成實例的時候可接收參數,具體看相應插件文檔。見下面代碼及註釋:
plugins: [ |
module
代理 style-loader 處理 css);
style-loader 先把 css 嵌入 js 使其變成有效 module,這個插件將 css 從 js 中分離出來。這個過程不矛盾,由於最開始 webpack 沒法處理 css 文件,因此須要 css-loader, style-loader 處理,嵌入到 js 中的 css mini-css-extract-plugin 能夠識別並提出。這個插件是 webpack 4.x 新引入,代替 extract-text-webpack-plugin。
$
符號調用 jq
若是不是經過 npm 安裝,而是直接在項目中引入,須要配合
resolve
的別名使用,否則找不到
接受development
、production
、none
三個值,通常取前兩個值之一,指定構建環境,webpack 自己會作相應優化(配合optimization使用,下文會有更多介紹),同時省去在命令行中指定構建環境的過程。
// 至關於 webpack --mode=production |
上述配置對應 Webpack 核心概念,除此以外,還有下面配置項很經常使用。
這個選項是在 Webpack 4.x 中引入的,最經常使用的配置是代替CommonsChunkPlugin提取公共代碼。下面直介紹提取公共 JS 代碼的配置:
optimization: { |
devtool
最經常使用功能是配置 sourcemap,生產和開發環境通常使用不一樣的 sourcemap,配置以下:
// 生產環境 |
關於各配置項的含義可參考Devtool和這片文章Webpack 的 devtool 和 source maps。
sourcemap 是構建後的代碼 map 到源代碼的映射表,便於定位 bug,具體的映射關係存儲在構建後的
.map
文件中。
NOTE: 這裏咱們在生產環境使用的是 source-map
選項而不是其餘,是由於目前 webpack 在開啓 uglifyjs-webpack-plugin 優化代碼後,其餘模式下的 sourcemap 選項無效,官網對此也有說明。雖然使用source-map
選項生成的映射表比較大,但只有開啓開發者工具的時候.map
文件纔會加載,這意味着 映射表文件的大小不影響正經常使用戶的訪問體驗,可是否壓縮 js 文件對正經常使用戶有直接影響,故,現階段,生產環境 devtool 使用 source-map
選項。
開發環境爲了更好的開發體驗,能夠開啓熱更新等功能,在devServer
中配置:
devServer: { |
須要在插件中進行下面配置:
plugins: [ |
NOTE:若是傳統多頁面項目,在入口文件後面添加下面代碼,配合熱更新:
// 配合 webpack 配置實現熱更新 |
多頁面目前只有在 JS 或者 CSS 文件改變的時候實現了熱更新,若是是模版(html)文件改變,沒有實現熱更新(能夠實現自動刷新頁面,但感受很雞肋,若是改動了模版文件,手動刷新)。
devServer 還能夠設置反向代理,後續填坑。
resolve
選項能夠指定如何解析 modules,更可能是經過設置 alias 告訴 webpack 去哪找文件解析。好比,若是在項目中經過文件的形式引入的 jq,那在使用 ProvidePlugin
對 jq 進行解析的時候,就須要經過設置別名的形式告訴 webpack 去哪找 jq 源文件。
resolve: { |
下面記錄針對具體需求的完整代碼描述。
好比,jq,zepto 等,若是經過 CDN 能夠在項目中直接使用 $
符號,但若是是經過 npm 安裝到本地,甚至直接將第三方庫源文件寫在項目中,那是沒法直接使用 $
符號這種調用方式的,須要使用上文介紹的 ProvidePlugin
插件。固然,還有細節須要注意,見下面詳細代碼。
相對於直接引入,使用 npm 能夠省去咱們手動指定 module 路徑的麻煩,已 zepto 爲例:
使用 zepto 時,直接使用 ProvidePlugin 會報錯,具體參考這片文章如何在 webpack 中引入未模塊化的庫,如 Zepto
// 處理 zepto 模塊化問題,須要安裝 exports-loader 和 script-loader |
同 npm 不一樣之處在於咱們須要手動指定 zepto 的路徑,以下
// 設置別名 |
爲了能將 css 從 js 中提取出來,須要在 module
中將 style-loader 替換爲 MiniCssExtractPlugin.loader,見下面代碼:
module: { |
主要一下幾個方面:
contenthash
(使用 mini-css-extract-plugin
);contenthash
,使用 webpack 自帶 splitChunks 提取;contenthash
,使用 webpack 自帶 splitChunks 提取;hash
(圖片文件添加 hash 並不同,也不會隨每次構建改變,還不知原理,反正能夠工做,待填坑)。