webpack4
webpack 核心概念
- Entry: 入口:Webpack 執行架構的第一步将從 Entry 開始,可以抽象成輸入(入口)。
- Module: 子產品:在 Webpack 裡一切都是子產品,一個子產品對應着一個檔案,Webpack 會從配置的 Entry 開始遞歸找出所有的依賴子產品。
- Chunk: 代碼塊:一個 Chunk 由多個子產品組合而成,用于代碼合并與分割。
- Loader: 子產品轉換器:用于把子產品原内容按照需求轉化成新内容。
- Plugins: 擴充插件:在 Webpack 建構流程中的特定時機注入擴充邏輯來改變架構結果或做你需要做的事情。
- Output: 輸出結果:在 webpack 經過一系列處理并得出最終想要的代碼後的輸出結果。
其他常用的一些參數
- mode: 環境 環境有三種 development production none
- devtool: 工具 有none source-map module-source-map cheap-source-map…
- context: 上下文,指名webpack的上下文路徑
- watch: 監聽 boolean,是否監聽檔案變化重新打包
- watchOptions: 監聽時的選項,當watch為true的時候開啟
- optimization: 優化, webpack進行優化的選項
- devServer: 開發伺服器, 使用webpack-dev-server提供的開發伺服器
- resolve: 規則,定制一些查找檔案的規則
- resolveLoader loader加載器的選項,這個選項來指定如何查找loader
1.壓縮 css js
- yarn add terser-webpack-plugin optimize-css-assets-webpack-plugin -D
terser-webpack-plugin 替換掉 uglifyjs-webpack-plugin,解決 uglifyjs 不支援 es6 文法問題
2.檔案位置存放 css 哪些等的存放的目錄,不是都在一個檔案夾上
(範圍從整個項目有東西變化就變 -> 部分項目(chunk) -> 單個檔案内容)
-
- 正常項目輸出檔案直接用 hash css 的就用 contenthash
- hash 代表本次的編譯,每當編譯一次,hash 會變一次,所有的産出資源的 hash 都一樣
- chunkhash 代碼塊的 hash,因為一般來說,每個 entry 都會産生不一樣的 chunk(檔案名和字尾)
- contenthash 内容 hash,隻有當内容變化的時候才變化
3.在 html 中引入圖檔
- html-withimg-loader
4. 處理 css3 屬性字首(等,加上浏覽器适配) 和.browserslistrc , postcss.config.js
- yarn add postcss-loader autoprefixer -D
5.轉義代碼 jsx es6 es7
- yarn add babel-loader @babel/core @babel/preset-env @babel/preset-react -D
裝飾器,類進行轉化的插件
- yarn add @babel/plugin-proposal-decorators @babel/plugin-proposal-class-properties -D
6.類,方法,等代碼重複建立問題
對一些公共輔助代碼,可以通過下面插件提取成一個獨立子產品,避免重複引入 (@babel/runtime)
- yarn add @babel/plugin-transform-runtime -D
7.配置 eslint 規則
- yarn add eslint eslint-loader babel-eslint -D
使用 airbnb 的規則
- yarn add eslint-config-airbnb eslint-plugin-import eslint-plugin-react eslint-plugin-react-hooks eslint-plugin-jsx-a11y -D
8.引入字型 使用 url-loader 配置
9.在引入的時候+字首 全局引入
- yarn add expose-loader -D
10.externals 引入然後不需要 webpack 打包起來,到時候我們直接引入 (外部引用)
- yarn add html-webpack-externals-plugin -D
11.拷貝靜态檔案
- yarn add copy-webpack-plugin -D
12.請求代理 在 devServer 那邊配置映射
13.express 提供的 webpack-dev-server 靜态伺服器中間件,webpack-dev-middleware
- yarn add webpack-dev-middleware -D
15.多入口項目打包多頁面項目 glob 擷取多個入口 使用 glob, 代碼如上
- yarn add glob -D
16.友好的顯示資訊的插件 friendly-errors-webpack-plugin
- yarn add friendly-errors-webpack-plugin -D
17.費時上報插件 speed-measure-webpack-plugin
- yarn add speed-measure-webpack-plugin -D
18.需要配合 webpack webpack-cli 一起使用,生成代碼分析報告,幫助提高代碼品質和網站性能
- yarn add webpack-bundle-analyzer -D
加入插件,然後修改 webpack 的配置檔案,預設不開啟分析頁面的伺服器
- “generateAnalyzerFile”: “webpack --profile --json > stats.json”
webpack --profile --json > stats.json 生成 stats.json 檔案輸出到和項目打包的目錄一樣
- “analyzer”: “webpack-bundle-analyzer --port 8888 ./dist/stats.json”
webpack-bundle-analyzer --port 8888 ./dist/stats.json 這個包啟動這個 json 檔案,并啟動一個伺服器,端口是 8888
19. polyfill 相容一些東西不能在别的浏覽器使用,不相容問題,比如 promise 在 IE11 不行 (缺點太大,直接引入到項目中)
- yarn add babel-polyfill -D
可以使用一個腳本進行替代
[polyfill-service] polyfill.io 通過分析請求頭的資訊中的 UserAgent 實作自動加載浏覽器所需要的 polyfills
20. libraryTarget 和 library (打包成庫的玩法,看 webpack-study-2 項目)
- output.library 配置導出庫的名稱
- output.libraryExport 配置要導出子產品中哪些子子產品需要被導出。它隻能在 output.library 被設定成 commonjs 或者 commonjs2 時使用才有意義
- output.libraryTarget 配置以何種方式導出庫,是字元串的枚舉類型,支援以下配置
寫一個庫,運用libraryTarget 和 library
寫一個庫,運用libraryTarget 和 library
- 實作數學運算的功能
- webpack 還可以打包 js 庫,打包成壓縮版和非壓縮版的庫.支援 CJS/ESM 方式導入
- require(‘xxx’) , import xxx from ‘xxx’
優化篇
優化篇
14.圖檔壓縮優化
- yarn add image-webpack-loader -D
21. purgecss-webpack-plugin 除去未使用的 css,一般和 glob,glob-all 配合使用
- yarn add purgecss-webpack-plugin -D
cdn 又叫内容分發網絡,通過把資源部署到世界各地,使用者在通路時按照就近原則從最近的伺服器擷取資源,進而加速資源的擷取速度。
22. px 轉化成 rem 的插件和 loader
- yarn add px2rem-loader lib-flexible -D
23. DLL .dll 為字尾的檔案稱為動态連接配接庫,在一個動态連接配接庫中可以包含給其他子產品調用的函數和方法。 (dynamic link library) [webpack 庫内置]
把基礎子產品獨立出來打包到單獨的動态連接配接庫裡
當需要導入的子產品在動态連接配接庫裡的時候,子產品不能再次被打包,而是去動态連接配接庫中擷取
dll-plugin 插件,用于打包除一個個動态連接配接庫
dll-reference-plugin 插件,在配置檔案中引入 DLLPlugin 插件打包好的動态連接配接庫
[name].manifest.json 的檔案(編譯的時候需要而已,是一座橋梁,生産模式下沒用)
- DllPlugin DllReferencePlugin 都在 webpack/lib/xxx 下面直接引入
24. tree shaking [搖樹優化] 一個子產品可以有多個方法,隻要其中某個方法使用到了,則整個檔案都會被打包到 bundle 裡面去,tree shaking 就是隻把用到的方法打入 bundle 中,沒用到的方法會 uglify 階段擦除掉。[有傳回值的方法沒人接受,也清除掉,多次指派前面沒有使用,最後一次使用留最後一次的指派] [隻要entry用到的,就不搖掉]
原理就是利用 es6 子產品的特點,隻能作為子產品頂層語句出現,import 的子產品名隻能是字元串常量
- webpack4 預設支援,在.babelrc 裡面設定[’@babel/preset-env’,{modules: false }] modules: false [保留es的子產品化模式] ,即可在 production 模式下預設開啟,防止打包整個庫,隻打包使用的,不過要設定 devtool 為 none|false
- 編寫元件的時候,搖樹要注意什麼? [require引用後但沒用到也不能瑤掉,不要改變window啥的,能做到變量提升]
- 1.一定要盡量使用es6 modules
- 2.盡量編寫沒有副作用的代碼
25. scope hoisting 讓webpack打包出來的代碼檔案更小,運作速度更快,又叫做’作用域提升’ webpack3出現的功能。
webpack轉換之後的子產品會包裹上一層函數,import會轉換成require
代碼體積更小,因為函數申明語句會産生大量代碼,包裹後不會産生
代碼在運作時因為建立的函數作用域更少了,記憶體開銷也随着變小
大量作用域包裹代碼會導緻體積變大
運作時建立的函數作用域變多,記憶體開銷增大
scope hoisting的原理是将所有的子產品按照引用順序放在一個函數作用域中,如果适當地重命名一些變量以防止命名沖突
這個功能在mode為production下預設開啟,開發環境需要用webpack.optimize.ModuleConcatenationPlugin插件,也要使用es6 module,cjs不支援這個。
26. 熱加載 react-hot-loader 開發環境使用的[熱加載是為了防止熱更新重新整理頁面操作而産生的,主要是為了防止頁面整體重新整理,實作局部重新整理,提高效率] 設定devServer.hot:true 和配置 webpack.HotModuleReplacementPlugin 插件
- yarn add react-hot-loader -D
// .babelrc
{
"plugins":['react-hot-loader/babel']
}
// App.js
import { hot } from 'react-hot-loader';
const App = () => <div>Hello world!</div>;
export default hot(App); // 包裹,傳回,熱更新就替換 hot是一個高階元件
代碼分割 chunk 動态導入,代碼分割相關
- optimization: {
- splitChunks: {
- chunks: 'all'
- }
- }
+ output.chunkFilename: '[name].bundle.js',
module.exports = {
//...
optimization: {
splitChunks: {
// 代碼分割
cacheGroups: {
// node_modules下面的代碼都放在vendors裡面
vendor: {
chunks: 'initial', // 指定分割的類型,預設三種 all[全部] async[預設異步] initial[同步]
name: 'vendors', // 給分割出去的代碼塊起名字
test: /node_modules/, // 哪裡的代碼需要分割
priority: -10 // 優化優先級
},
// 公共代碼部分
// 被2個或以上代碼引用的的代碼都放在commons裡面
commons: {
chunks: 'initial',
name: 'commons',
minSize: 0, // 最小提取位元組
minChunks: 2, // 最少被幾個chunk引用才被提取
priority: -20 // 優化優先級
}
}
}
}
// ...
}