github.com/atbulbs/web…javascript
官方推薦的一些打包分析插件 webpack.js.org/guides/code…css
安裝和使用webpack-bundle-analyzer github.com/webpack-con…html
# 生成stats.json文件
$ webpack --profile --json > stats.json
複製代碼
官方文檔: developers.google.com/web/updates…前端
參考文檔: blog.logrocket.com/using-the-c…java
// 查看代碼覆蓋率
// dev tool > command + shift + P > Show Coverage > 錄屏
複製代碼
官方文檔: webpack.js.org/api/module-…node
function getComponent () {
return import(/* webpackChunckName: 'lodash' */'lodash').then(({ default: _ }) => {
var element = document.createElement('div')
element.innerHTML = _.join(['a', 'b'], '*')
return element
})
}
複製代碼
官方文檔: webpack.js.org/guides/code…webpack
實現第一次加載的時候就是最快的, webpack推薦交互的代碼放到異步加載的模塊裏去寫 prefeching/preloading可實現網頁空閒時預先加載異步模塊git
// src/click.js
export default funciton clickHandler () {
console.log('clicked')
}
// src/index.js
window.document.addEventListener('click', () => {
// prefetch會等待覈心代碼加載完成, 頁面空閒時去加載prefetch的文件
// webpackPreload會和核心代碼一塊兒加載
import(/* webpackPrefetch: true */'./click.js').then({ default: func } => func())
})
複製代碼
官方文檔 webpack.js.org/guides/code…es6
分割業務代碼和庫代碼, 否則打包文件會很大, 首次訪問加載時間會很長github
並且若是不分割, 修改業務代碼後, 從新訪問, 又所有得從新加載庫代碼
分割方式: 配置 + 同步引入 與 動態引入(無需作任何配置)
動態引入文檔 webpack.js.org/guides/code…
function getComponent () {
// jsonp引入
// 動態的import, 實驗性的語法
// npm i babel-plugin-dynamic-import-webpack -D
return import('lodash').then(({ default: _ }) => {
var element = document.createElement('div')
element.innerHTML = _.join(['a', 'b'], '*')
return element
})
}
getComponent().then(element => {
document.body.appendChild(element)
})
// .babelrc 動態引入
// npm i -D babel-plugin-dynamic-import-webpack
{
plugins: ['dynamic-import-webpack']
}
複製代碼
SplitChunksPlugin官方文檔: webpack.js.org/plugins/spl…
// splitPlugin 配置
optimization: {
// SplitChunksPlugin config
// 以下是官方默認配置
splitChunks: {
// async 只對異步代碼生效
// all 對同步異步都作代碼分割, 可是同步代碼還需cacheGrops配置
// initial 只對同步代碼作分割
chunks: 'async',
// 若是引入的模塊大於minSize才作代碼分割
minSize: 30000,
// 對於大於maxsize的模塊嘗試進行二次代碼分割
maxSize: 0,
// 打包後的文件至少有多少個chunk文件引入這個模塊才進行代碼分割
minChunks: 1,
// 同時加載的模塊數量,
// 在打包前5個庫的時候會生成5個js文件,
// 超過5個就再也不作代碼分割
maxAsyncRequests: 5,
// 入口文件作代碼分割的最大文件數量
maxInitialRequests: 3,
// 自動命名定界符
automaticNameDelimiter: '~',
// 讓cacheGroups裏的filename生效
name: true,
// 緩存組, 把庫文件先放到緩存裏, 再根據test規則分組合並打包
cacheGroups: {
// vendors: false
vendors: {
// 若是是node_modules裏面的文件, 就打包到vendors組裏
test: /[\\/]node_modules[\\/]/,
// 分組時的優先級
priority: -10
// 組文件的名字 vendors.js, 否則會是 vendors~main.js
// filename: 'vendors.js'
},
// 被分割的代碼的默認的配置, 沒有test, 全部模塊都符合要求
default: {
// 至少被引用了2次
minChunks: 2,
priority: -20,
// 複用已被分割打包過了的模塊
reuseExistingChunk: true,
// 組的文件名
// filename: 'common.js',
}
}
}
}
複製代碼
官方文檔: webpack.js.org/guides/lazy…
前端框架結合webpack實現懶加載: webpack.js.org/guides/lazy…
// 點擊頁面纔會加載lodash代碼
function getComponent () {
// 懶加載並非webpack裏面的一個概念, 而是ES的import語法,
// webpack能識別這種語法, 對import引入的模塊作代碼分割
// 至關於對optimization的splitChunks作了配置
return import(/* webpackChunckName: 'lodash' */'lodash').then(({ default: _ }) => {
var element = document.createElement('div')
element.innerHTML = _.join(['a', 'b'], '*')
return element
})
}
window.document.addEventListener('click', () => {
getComponent().then(el => window.document.body.appendChild(el))
})
複製代碼
官方文檔: webpack.js.org/guides/tree…
官方文檔: webpack.js.org/configurati…
關於靜態模塊結構的官方文檔: exploringjs.com/es6/ch_modu…
// Tree Shaking只支持 ES Module(靜態引入), 不支持Common JS(動態引入)
// development mode 默認沒有tree shaking
// production mode 不須要這個optimization
optimization: {
usedExports: true
}
// package.json
"sideEffects": false, // false時對全部模塊搖樹
// 實踐
"sideEffects": [
// 否則打包時會忽略 @babel/polly-fill, 由於其沒有導出對象, 只在window上掛載了對象
"@babel/polly-fill",
// 對css不搖樹
"*.css"
],
複製代碼
官方文檔: webpack.js.org/configurati…
devtool: 'none' // 關閉sourcemap
devtool: 'source-map' // 會生成一個.map文件
devtool: 'inline-source-map' // .map文件會被打包到js文件裏, 錯誤提示會精確到第幾行第幾列
devtool: 'cheap-inline-source-map' // 只精確到行, 不精確到列, 提示性能, 並且只會提示業務代碼的錯誤, 不提示loader和第三方模塊的錯誤
devtool: 'cheap-module-inline-source-map' // 提示loader和第三方模塊的錯誤
devtool: 'eval' // 用js eval效率最高, 提示不全面, 不展現行數
devtool: 'cheap-module-eval-source-map' // 開發時的最佳實踐
devtool: 'cheap-module-source-map' // 生產時的最佳實踐
複製代碼