[TOC]
[整個章節的參考鏈接](https://kaiwu.lagou.com/course/courseInfo.htm?courseId=416#/detail/pc?id=4425)
>[success] # 編譯階段提速
~~~
1.編譯模塊階段的效率提升,下面的行為操作都是在webpack編譯階段去做的
~~~
>[warning] ### IgnorePlugin -- 忽略第三方包指定目錄
~~~
1.webpack 的內置插件,作用是忽略第三方包指定目錄。
2.有的依賴包,除了項目所需的模塊內容外,還會附帶一些多余的模塊,例如'moment' 會將所有
本地化內容和核心功能一起打包
3.下面案例通過配置的'webpack-bundle-analyzer'來看使用 'IgnorePlugin'后對'moment'的影響
~~~
* 配置代碼
~~~
const webpack = require('webpack')
//webpack.config.js
module.exports?=?{
????//...
????plugins:?[
????????//忽略?moment?下的?./locale?目錄
????????new webpack.IgnorePlugin({
resourceRegExp: /^\.\/locale$/,
contextRegExp: /moment$/,
}),
????]
}
~~~
* 配置前

* 配置后

>[danger] ##### 疑問這些包并不想全排除部分還是想引用要怎么做
~~~
1.可以配合'ContextReplacementPlugin' ,關于這部分可以參考=
'https://iamakulov.com/notes/webpack-contextreplacementplugin/'
~~~
>[warning] ### 按需引入
~~~
1.以'lodash' 為例通常項目中只使用很少的lodash方法,但是構建時卻發現構建時引入了整個依賴包
所以需要按需引入這些內容
如果之前你的項目是這樣使用loash:
import _ from 'lodash'
console.log(_.slice([]))
現在按需你需要這么寫:
import slice from 'lodash/slice'
console.log(slice([]))
~~~
* 配置前

* 配置后

>[danger] ##### lodash 如果已經在項目初期沒有做按需引入如何補救
~~~
1.使用'babel-plugin-lodash' 和'lodash-webpack-plugin' 插件參考文章'https://www.jianshu.com/p/3dd1948cf5a2'
2.使用'babel-plugin-import '參考'https://www.ctolib.com/mip/shenshanyoumu-babel-plugin-import-annotations.html'
'https://xiaozhuanlan.com/topic/2984105637'
上面兩個來實現動態刪除無效代碼
~~~
>[warning] ### 預編譯資源模塊
~~~
1.提前對一些業務包,一類打包后然后使用
~~~
>[danger] ##### 創建一個webpack.dll.js
~~~
1.創建一個webpack.dll.js 用來專門處理這些需要預處理的文件
2.使用 DLLPlugin 進行分包,DllReferencePlugin對 manifest.json 引用
~~~
~~~
const path = require('path');
const webpack = require('webpack');
module.exports = {
entry: {
// 要處理的文件,這個library不是固定的可以自己個根據需要起適合自己的
library: [
'react',
'react-dom'
]
},
output: {
filename: '[name]_[chunkhash].dll.js', // library.dll.js中暴露出的全局變量名是entry里面key
path: path.join(__dirname, 'build/library'),// 打包后文件輸出的位置
library: '[name]_[hash]' // 庫暴露出來的名字 可以參考打包組件和基礎庫
},
plugins: [
new webpack.DllPlugin({
name: '[name]_[hash]',// 生成一個文件映射json名字
path: path.join(__dirname, 'build/library/[name].json') // 保存的位置
})
]
};
~~~
>[danger] ##### 在webpack 打包指令位置配置
~~~
1.上面是一個單獨的指令,專門用來打包提取包的不是對項目打包,將提取包的內容通過
'DllReferencePlugin' 引入之后,在執行打包
plugins: [
new webpack.DllReferencePlugin({
context: __dirname,
manifest: require('./build/library/')
})
],
~~~
>[danger] ##### 可以參考
[參考鏈接](https://www.cnblogs.com/lusongshu/p/8473318.html)
>[warning] ### 使用Externals
~~~
1.希望 webpack 不會對其進行打包,此時就可以配置 externals
~~~
>[danger] ##### 使用
~~~
1.這樣jq在編譯階段就不會被,打入項目中可以通過cdn的形式引入
module.exports?=?{
????//...
????externals:?{
????????//jquery通過script引入之后,全局中即有了?jQuery?變量
????????'jquery':?'jQuery'
????}
}
// 通過手動cdn形式引入
<!DOCTYPE?html>
<html?lang="en">
<head>
????<meta?charset="UTF-8">
????<meta?name="viewport"?content="width=device-width,?initial-scale=1.0">
????<meta?http-equiv="X-UA-Compatible"?content="ie=edge">
????<title>Document</title>
</head>
<body>
????<div?id="root">root</div>
????<script?src="http://libs.baidu.com/jquery/2.0.0/jquery.min.js"></script>
</body>
</html>
~~~
>[danger] ##### Externals 和 DLLPlugin 區別
~~~
1.在 Webpack 的配置方面,externals 更簡單,而 DllPlugin 需要獨立的配置文件。
2.DllPlugin 包含了依賴包的獨立構建流程,而 externals 配置中不包含依賴框架的生成方式,通常
使用已傳入 CDN 的依賴包。
3.externals 配置的依賴包需要單獨指定依賴模塊的加載方式:全局對象、CommonJS、AMD 等。
4.在引用依賴包的子模塊時,DllPlugin 無須更改,而 externals 則會將子模塊打入項目包中。
~~~
>[danger] ##### 如何自動引入cdn
* 說明 頁面提取資源使用vue 做的一個案例,[關于webpack中如何使用vue參考配置](https://vue-loader.vuejs.org/)
~~~
1.當做項目的時候對一些基礎第三方包我們可以采用cdn的形式,將類第三方包抽離
2.配置cnd的'plugins' 用到的是'html-webpack-externals-plugin' -- 'npm install --save-dev html-webpack-externals-plugin'
3.使用的時候需要配合'HtmlWebpackPlugin' 一起使用
~~~
[html-webpack-externals-plugin 具體使用地址](https://www.npmjs.com/package/html-webpack-externals-plugin)
>[danger] ##### 以vue 舉個例子
~~~
1.注意事項,下面案例'entry' 是直接可以跟cdn地址的,為什么vue這個卻沒有想react那種簡寫呢?因為
仔細看我用的vue的cdn地址結尾是沒有類型,如果是沒有具體類型的cdn地址,注意一定要加type字段
2.注意"global: 'Vue'" 這個vue 是大寫的,為什么是大寫因為我在后續文件引入寫法是
" import Vue from 'vue' ",我用的參數是大寫,這里也是一個坑,具體可以看文檔對global解釋
~~~
~~~
const HtmlWebpackExternalsPlugin = require('html-webpack-externals-plugin')
moudles.export = {
plugins: [
new HtmlWebpackExternalsPlugin({
externals: [{
module: 'vue',
entry: {
path: 'https://cdn.jsdelivr.net/npm/vue@2.6.11',
type: 'js'
},
global: 'Vue'
}],
files:['template.html'] // 也可以指定頁面加入對應cdn 看文檔都有
})
}
// entry 簡寫版本
// moudles.export = {
// plugins: [
// new HtmlWebpackExternalsPlugin({
// externals: [{
// module: 'react',
// entry: '//11.url.cn/now/lib/16.2.0/react.min.js',
// global: 'React'
// },
// {
// module: 'react-dom',
// entry: '//11.url.cn/now/lib/16.2.0/react-dom.min.js',
// global: 'ReactDom'
// }
// ]
// })
// ]
// }
~~~
>[warning] ### include/exclude
~~~
1.webpack 中所有的loader 都可以擁有include和exclude屬性。
exclude:排除不滿足條件的文件夾(這樣可以排除webpack查找不必要的文件)
include:需要被loader 處理的文件或文件夾
2.exclude 的優先級高于 include
3.作用不需要再用loader處理而已,打包還是會打包的,比如jQuery,不需要再被babel處理,因為jQuery已經是es5,
瀏覽器直接可以識別。這個時候,你不設置exclude,jQuery就會被處理,這樣就增加了打包時間。所以,設置好
exclude和include可以優化打包時間
{
test: /\.js$/,
exclude: /node_modules/, // include: [path.resolve(__dirname, 'src')]
use: ['babel-loader?cacheDirectory=true']
}
~~~
>[warning] ### noParse
[鏈接](https://blog.csdn.net/qq_17175013/article/details/86842321)
>[warning] ### Source Map
~~~
1.參考'Source Map' 章節
~~~
>[warning] ### TypeScript 編譯優化
~~~
1.Webpack 中編譯 TS 有兩種方式:使用 ts-loader 或使用 babel-loader
1.1.在使用 ts-loader 時,由于 ts-loader 默認在編譯前進行類型檢查,因此編譯時間往往比較慢,
通過加上配置項 transpileOnly: true可以在編譯時忽略類型檢查,提高編譯速度,但往往關閉后需要
在配合'ForkTsCheckerWebpackPlugin'
1.2. babel-loader 則需要單獨安裝 @babel/preset-typescript 來支持編譯 TS(Babel 7 之前的版本則還是需要
使用 ts-loader)
我這簡單試過幾次如果'ts-loader' +'ForkTsCheckerWebpackPlugin' 感覺比'@babel/preset-typescript ' 慢,
~~~
>[danger] ##### 使用
~~~
1.注釋部分是'ts-loader' +'ForkTsCheckerWebpackPlugin' 用法,沒注釋的地方是'babel-loader ' 用法,當然還需要
配置預設'@babel/preset-typescript ' 這里不做詳細說明了
~~~
~~~
var TSCheckerPlugin = require('fork-ts-checker-webpack-plugin')
module: {
rules: [
{
test: /\.ts$/,
// use: {
// loader: 'ts-loader',
// options: {
// transpileOnly: true,
// },
// },
use: ['babel-loader'], // 使用babel-loader 情況下
},
],
},
plugins: [
// new TSCheckerPlugin({
// typescript: {
// diagnosticOptions: {
// semantic: true,
// syntactic: true,
// },
// },
// }),
],
}
~~~
>[danger] ##### 文章說明
[對比說明](https://segmentfault.com/q/1010000019545436)
>[warning] ### resolve
~~~
1.這個后續再看優化 resolve.modules 配置(減少模塊搜索層級)
~~~
>[warning] ### 多進程打包處理 loader資源并行解析
~~~
1.webpack需要處理的文件是非常多的,構建過程是一個涉及大量文件讀寫的過程。項目復雜起來了,
文件數量變多之后,webpack構建就會特別滿,而且運行在nodeJS上的webpack是單線程模型的,
也就是說Webpack一個時刻只能處理一個任務,不能同時處理多個任務。
文件讀寫和計算操作是無法避免的,那能不能讓Webpack在同一時刻處理多個任務發揮多核CPU電腦的功能,
以提升
2.webpack 4.x 使用'thread-loader',小于4.0 可以使用'HappyPack'可以將原有的 webpack 對 loader 的執行過程,
從單一進程的形式擴展為多進程的模式,從而加速代碼構建
3.這里要注意如果你是小項目,這里多進程打包反而速度會慢
~~~
[https://segmentfault.com/a/1190000022414110](https://segmentfault.com/a/1190000022414110)
[thread-loader使用](https://www.webpackjs.com/loaders/thread-loader/)
~~~
const threadLoader = require('thread-loader');
const jsWorkerPool = {
// options
// 產生的 worker 的數量,默認是 (cpu 核心數 - 1)
// 當 require('os').cpus() 是 undefined 時,則為 1
workers: 2,
// 閑置時定時刪除 worker 進程
// 默認為 500ms
// 可以設置為無窮大, 這樣在監視模式(--watch)下可以保持 worker 持續存在
poolTimeout: 2000
};
const cssWorkerPool = {
// 一個 worker 進程中并行執行工作的數量
// 默認為 20
workerParallelJobs: 2,
poolTimeout: 2000
};
threadLoader.warmup(jsWorkerPool, ['babel-loader']);
threadLoader.warmup(cssWorkerPool, ['css-loader', 'postcss-loader']);
module.exports = {
// ...
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: [
{
loader: 'thread-loader',
options: jsWorkerPool
},
'babel-loader'
]
},
{
test: /\.s?css$/,
exclude: /node_modules/,
use: [
'style-loader',
{
loader: 'thread-loader',
options: cssWorkerPool
},
{
loader: 'css-loader',
options: {
modules: true,
localIdentName: '[name]__[local]--[hash:base64:5]',
importLoaders: 1
}
},
'postcss-loader'
]
}
// ...
]
// ...
}
// ...
}
~~~
* 或者
~~~
module: {
rules: [{
test: /\.js$/,
exclude: /node_modules/,
use: [{
loader: 'thread-loader',
options: {
// 產生的 worker 的數量,默認是 cpu 的核心數
workers: 3,
// 一個 worker 進程中并行執行工作的數量
// 默認為 20
workerParallelJobs: 50,
// 額外的 node.js 參數
// workerNodeArgs: ['--max-old-space-size', '1024'],
// 閑置時定時刪除 worker 進程
// 默認為 500ms
// 可以設置為無窮大, 這樣在監視模式(--watch)下可以保持 worker 持續存在
poolTimeout: 500,
// 池(pool)分配給 worker 的工作數量
// 默認為 200
// 降低這個數值會降低總體的效率,但是會提升工作分布更均一
poolParallelJobs: 200,
// 池(pool)的名稱
// 可以修改名稱來創建其余選項都一樣的池(pool)
// name: "my-pool"
}
},
'babel-loader'
]
}
}
~~~
- 工程化 -- Node
- vscode -- 插件
- vscode -- 代碼片段
- 前端學會調試
- 谷歌瀏覽器調試技巧
- 權限驗證
- 包管理工具 -- npm
- 常見的 npm ci 指令
- npm -- npm install安裝包
- npm -- package.json
- npm -- 查看包版本信息
- npm - package-lock.json
- npm -- node_modules 層級
- npm -- 依賴包規則
- npm -- install 安裝流程
- npx
- npm -- 發布自己的包
- 包管理工具 -- pnpm
- 模擬數據 -- Mock
- 頁面渲染
- 渲染分析
- core.js && babel
- core.js -- 到底是什么
- 編譯器那些術語
- 詞法解析 -- tokenize
- 語法解析 -- ast
- 遍歷節點 -- traverser
- 轉換階段、生成階段略
- babel
- babel -- 初步上手之了解
- babel -- 初步上手之各種配置(preset-env)
- babel -- 初步上手之各種配置@babel/helpers
- babel -- 初步上手之各種配置@babel/runtime
- babel -- 初步上手之各種配置@babel/plugin-transform-runtime
- babel -- 初步上手之各種配置(babel-polyfills )(未來)
- babel -- 初步上手之各種配置 polyfill-service
- babel -- 初步上手之各種配置(@babel/polyfill )(過去式)
- babel -- 總結
- 各種工具
- 前端 -- 工程化
- 了解 -- Yeoman
- 使用 -- Yeoman
- 了解 -- Plop
- node cli -- 開發自己的腳手架工具
- 自動化構建工具
- Gulp
- 模塊化打包工具為什么出現
- 模塊化打包工具(新) -- webpack
- 簡單使用 -- webpack
- 了解配置 -- webpack.config.js
- webpack -- loader 淺解
- loader -- 配置css模塊解析
- loader -- 圖片和字體(4.x)
- loader -- 圖片和字體(5.x)
- loader -- 圖片優化loader
- loader -- 配置解析js/ts
- webpack -- plugins 淺解
- eslit
- plugins -- CleanWebpackPlugin(4.x)
- plugins -- CleanWebpackPlugin(5.x)
- plugin -- HtmlWebpackPlugin
- plugin -- DefinePlugin 注入全局成員
- webapck -- 模塊解析配置
- webpack -- 文件指紋了解
- webpack -- 開發環境運行構建
- webpack -- 項目環境劃分
- 模塊化打包工具 -- webpack
- webpack -- 打包文件是個啥
- webpack -- 基礎配置項用法
- webpack4.x系列學習
- webpack -- 常見loader加載器
- webpack -- 移動端px轉rem處理
- 開發一個自己loader
- webpack -- plugin插件
- webpack -- 文件指紋
- webpack -- 壓縮css和html構建
- webpack -- 清里構建包
- webpack -- 復制靜態文件
- webpack -- 自定義插件
- wepack -- 關于靜態資源內聯
- webpack -- source map 對照包
- webpack -- 環境劃分構建
- webpack -- 項目構建控制臺輸出
- webpack -- 項目分析
- webpack -- 編譯提速優護體積
- 提速 -- 編譯階段
- webpack -- 項目優化
- webpack -- DefinePlugin 注入全局成員
- webpack -- 代碼分割
- webpack -- 頁面資源提取
- webpack -- import按需引入
- webpack -- 搖樹
- webpack -- 多頁面打包
- webpack -- eslint
- webpack -- srr打包后續看
- webpack -- 構建一個自己的配置后續看
- webpack -- 打包組件和基礎庫
- webpack -- 源碼
- webpack -- 啟動都做了什么
- webpack -- cli做了什么
- webpack - 5
- 模塊化打包工具 -- Rollup
- 工程化搭建代碼規范
- 規范化標準--Eslint
- eslint -- 擴展配置
- eslint -- 指令
- eslint -- vscode
- eslint -- 原理
- Prettier -- 格式化代碼工具
- EditorConfig -- 編輯器編碼風格
- 檢查提交代碼是否符合檢查配置
- 整體流程總結
- 微前端
- single-spa
- 簡單上手 -- single-spa
- 快速理解systemjs
- single-sap 不使用systemjs
- monorepo -- 工程
- Vue -- 響應式了解
- Vue2.x -- 源碼分析
- 發布訂閱和觀察者模式
- 簡單 -- 了解響應式模型(一)
- 簡單 -- 了解響應式模型(二)
- 簡單 --了解虛擬DOM(一)
- 簡單 --了解虛擬DOM(二)
- 簡單 --了解diff算法
- 簡單 --了解nextick
- Snabbdom -- 理解虛擬dom和diff算法
- Snabbdom -- h函數
- Snabbdom - Vnode 函數
- Snabbdom -- init 函數
- Snabbdom -- patch 函數
- 手寫 -- 虛擬dom渲染
- Vue -- minVue
- vue3.x -- 源碼分析
- 分析 -- reactivity
- 好文
- grpc -- 瀏覽器使用gRPC
- grcp-web -- 案例
- 待續