webpack是乙個js打包工具,不乙個完整的前端構建工具。它的流行得益於模組化和單頁應用的流行。
webpack提供擴充套件機制,在龐大的社群支援下各種場景基本它都可找到解決方案。本文的目的是教會你用webpack解決實戰中常見的問題。
在深入實戰前先要知道webpack的執行原理
從啟動webpack構建到輸出結果經歷了一系列過程,它們是:
解析webpack配置引數,合併從shell傳入和webpack.config.js
檔案裡配置的引數,生產最後的配置結果。
註冊所有配置的外掛程式,好讓外掛程式監聽webpack構建生命週期的事件節點,以做出對應的反應。
從配置的entry
入口檔案開始解析檔案構建ast語法樹,找出每個檔案所依賴的檔案,遞迴下去。
在解析檔案遞迴的過程中根據檔案型別和loader配置找出合適的loader用來對檔案進行轉換。
遞迴完後得到每個檔案的最終結果,根據entry
配置生成**塊chunk
。
輸出所有chunk
到檔案系統。
需要注意的是,在構建生命週期中有一系列外掛程式在合適的時機做了合適的事情,比如uglifyjsplugin
會在loader轉換遞迴完後對結果再使用uglifyjs
壓縮覆蓋之前的結果。
通過各種場景和對應的解決方案讓你深入掌握webpack
demo redemo 乙個單頁應用需要配置乙個entry
指明執行入口,webpack會為entry
生成乙個包含這個入口所有依賴檔案的chunk
,但要讓它在瀏覽器裡跑起來還需要乙個html檔案來載入chunk
生成的js檔案,如果提取出了css還需要讓html檔案引入提取出的css。web-webpack-plugin裡的webplugin
可以自動的完成這些工作。
webpack配置檔案
const = require('web-webpack-plugin');module.exports =,
plugins: [
//乙個webplugin對應生成乙個html檔案
newwebplugin(),
],};
requires: ['doc']
指明這個html依賴哪些entry
,entry
生成的js和css會自動注入到html裡。 你還可以配置這些資源的注入方式,支援如下屬性:
要設定這些屬性可以通過在js裡配置
newwebplugin(
},}),
或者在模版裡設定,使用模版的好處是靈活的控制資源注入點。
newwebplugin(),
一般專案裡會包含多個單頁應用,雖然多個單頁應用也可以合併成乙個但是這樣做會導致使用者沒訪問的部分也載入了。如果專案裡有很多個單頁應用,為每個單頁應用配置乙個entry
和webplugin
?如果專案又新增了乙個單頁應用,又去新增webpack配置?這樣做太麻煩了,web-webpack-plugin裡的autowebplugin
可以方便的解決這些問題。
module.exports =;
autowebplugin
會把./src/
目錄下所有每個資料夾作為乙個單頁頁面的入口,自動為所有的頁面入口配置乙個webplugin輸出對應的html。要新增乙個頁面就在./src/
下新建乙個資料夾包含這個單頁應用所依賴的**,autowebplugin
自動生成乙個名叫資料夾名稱的html檔案。autowebplugin
的更多功能見文件。
乙個好的**分割對瀏覽器首屏效果提公升很大。比如對於最常見的react體系你可以
1.先抽出基礎庫react
react-dom
redux
//vender.js 檔案抽離基礎庫到單獨的乙個檔案裡防止跟隨業務**被重新整理
//所有頁面都依賴的第三方庫
//react基礎
import 'react';
import 'react-dom';
import 'react-redux';
//redux基礎
import 'redux';
import 'redux-thunk';
//webpack配置
,}
demo remd 除了構建可執行的web應用,webpack也可用來構建發布到npm上去的給別人呼叫的js庫。
const nodeexternals = require('webpack-node-externals');module.exports =,
externals: [nodeexternals()],
target: 'node',
output: ,
};
這裡有幾個區別於web應用不同的地方:
服務端渲染的**要執行在nodejs環境,和瀏覽器不同的是,服務端渲染**需要採用commonjs規範同時不應該包含除js之外的檔案比如css。webpack配置如下:
module.exports =,output: ,
module: ,,]
},};
其中幾個關鍵的地方在於:
fis3和webpack有相似的地方也有不同的地方。相似在於他們都採用commonjs規範,不同在於匯入css這些非js資源的方式。fis3通過// @require './index.scss'
而webpack通過require('./index.scss')
。如果想從fis3平滑遷移到webpack可以使用comment-require-loader。比如你想在webpack構建是使用採用了fis3方式的imui
模組,配置如下:
loaders:
如果你在社群找不到你的應用場景的解決方案,那就需要自己動手了寫loader或者plugin了。 在你編寫自定義webpack擴充套件前你需要想明白到底是要做乙個loader
還是plugin
呢?可以這樣判斷:
如果你的擴充套件是想對乙個個單獨的檔案進行轉換那麼就編寫loader剩下的都是plugin。
其中對檔案進行轉換可以是像:
demo comment-require-loader 編寫loader
非常簡單,以comment-require-loader為例:
module.exports = function(content) ;
loader
的入口需要匯出乙個函式,這個函式要幹的事情就是轉換乙個檔案的內容。 函式接收的引數content
是乙個檔案在轉換前的字串形式內容,需要返回乙個新的字串形式內容作為轉換後的結果,所有通過模組化倒入的檔案都會經過loader
。從這裡可以看出loader
只能處理乙個個單獨的檔案而不能處理**塊。想編寫更複雜的loader可參考官方文件
demo end-webpack-pluginplugin
應用場景廣泛,所以稍微複雜點。以end-webpack-plugin為例:
class endwebpackplugin//監聽webpack生命週期裡的事件,做相應的處理
compiler.plugin('done', (stats) =>);
compiler.plugin('failed', (err) =>);
}}module.exports = endwebpackplugin;
compiler
和compilation
都會廣播一系列事件。 webpack生命週期裡有非常多的事件可以在event-hooks和compilation里查到。以上只是乙個最簡單的demo,更複雜的可以檢視 how to write a plugin或參考web-webpack-plugin。
webpack其實很簡單,可以用一句話涵蓋它的本質:
webpack是乙個打包模組化js的工具,可以通過loader轉換檔案,通過plugin擴充套件功能。如果webpack讓你感到複雜,一定是各種loader和plugin的原因。 希望本文能讓你明白webpack的原理與本質讓你可以在實戰中靈活應用webpack。
webpack原理與實戰
webpack是乙個js打包工具,不乙個完整的前端構建工具。它的流行得益於模組化和單頁應用的流行。webpack提供擴充套件機制,在龐大的社群支援下各種場景基本它都可找到解決方案。本文的目的是教會你用webpack解決實戰中常見的問題。在深入實戰前先要知道webpack的執行原理 從啟動webpac...
LightGBM介紹 原理與實戰
官網鏈結 中文 鏈結 微軟官方介紹 先安裝cmake和gcc,安裝過的直接跳過前兩步 brew install cmake brew install gcc git clone recursive cd lightgbm 在cmake之前有一步新增環境變數 export cxx g 8 cc gcc...
專案實戰 webpack的搭建
webpack是乙個模組的打包工具,這裡有他的官方文件,打包工具需要的條件 乙個輸入的檔案和輸出檔案,webpack的組成主要是四元素 entry.output,loader,plugin entry就是輸入檔案 output就是輸出檔案 loader是用於載入某些資源檔案,由於webpack本身只...