做者:心靜止水(前端時空)javascript
❝概念:「HMR:」 hot module replacement 熱模塊替換 / 模塊熱替換css
❞
做用:一個模塊發生變化,只會從新打包這一個模塊,而不是打包全部模塊,極大的提高了構建速度html
module.exports = {
// 引入html,解決熱更新的問題
entry: [
'./src/js/index.js',
'./src/index.html'
],
devServer: { // 開啓 HMR 功能 // 當修改了 webpack 配置,新配置要想生效,必須重啓服務
hot: true
}
}複製代碼
概念:一種提供源代碼構建後代碼映射技術(若是構建後代碼出錯了,能夠經過映射追蹤到源代碼錯誤)前端
[inline-|hidden-|eval-][nosources-][cheap-[module-]]source-map
source-map
:外部(錯誤代碼的準確信息 和 位置)
inline-source-map
:內聯(只生成一個內聯 source-map)(錯誤代碼的準確信息 和 位置)
hidden-source-map
:外部(直接生成
.map
文件)(不能追蹤源代碼錯誤,只能提示到構建後代碼的錯誤位置)
eval-source-map
:內聯(每個文件都生成對應的 source-map,都在 eval)(錯誤代碼的準確信息 和 位置)
nosources-source-map
:外部(錯誤代碼的準確信息,沒有源代碼信息)
cheap-source-map
:外部(錯誤代碼的準確信息 和 位置,但只能精確到行)
cheap-module-source-map
:外部(錯誤代碼的準確信息 和 位置,會將 loader 的 source-map 加入)
eval-source-map
/
eval-cheap-module-source-map
eval-source-map
)
eval-cheap-source-map
、
eval-source-map
、
source-map
、
cheap-module-source-map
、
cheap-source-map
source-map
/
cheap-module-source-map
nosources-source-map
、
hidden-source-map
module.exports = {
mode: 'development', // 'production'
devtool: 'eval-source-map' // 'source-map'
}複製代碼
oneOf:避免了每個文件都要被 loader 過一次 注:不能有兩個配置處理同一種類型文件vue
module.exports = {
module: {
rules: [
{ test: /\.js$/,
exclude: /node_modules/, //優先執行
enforce: 'pre',
loader: 'eslint-loader',
options: { fix: true }
},
{ // 如下 loader 只會匹配一個
oneOf: [ ..., {}, {} ] } ]
}
}複製代碼
module.exports = {
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
loader: 'babel-loader',
options: {
presets: { // 開啓 babel 緩存 // 第二次構建時,會讀取以前的緩存
cacheDirectory: true
}
}
}
]
}
}複製代碼
tree shaking:去除無用的代碼java
前提:1. 必須使用 ES6 模塊化;2. 開啓 production 環境
做用:減小代碼體積
在 package.json 中配置:node
"sideEffects": false
全部的代碼都沒有反作用(均可以進行 tree shaking)
sideEffects: ["*.css", "*.less"]
module.exports = {
entry: { // 多入口
main: './src/js/index.js',
test: './src/js/test.js'
},
output: { // [name]: 取文件名
filename: 'js/[name].[contenthash:10].js',
path: resolve(__dirname, 'build')
},
mode: 'production'
}複製代碼
module.exports = {
entry: './src/js/index.js',
output: {
filename: 'js/built.[contenthash:10].js',
path: resolve(__dirname, 'build') }, // 能夠將 node_modules 中的代碼單獨打包一個chunk最終輸出
optimization: {
splitChunks: {
chunks: 'all'
}
},
mode: 'production'
}複製代碼
// import動態導入語法:能將某個文件單獨打包成一個 chunk// 此處的註釋能夠命名打包後文件名import(/* webpackChunkName: 'test' */ './test.js') .then(() => {}) .catch(() => {})複製代碼
懶加載:當文件須要時才加載react
預加載 prefetch:會在使用前,提早加載 js 文件。等其餘資源加載完畢,瀏覽器空閒了,在偷偷加載資源jquery
正常加載能夠認爲是並行加載(同一時間加載多個文件)webpack
// import動態導入語法:能將某個文件單獨打包成一個 chunk
// webpackChunkName 此處的註釋能夠命名打包後文件名,webpackPrefetch 預加載
import(/* webpackChunkName: 'test', webpackPrefetch: true */ './test.js')
.then(() => {})
.catch(() => {}
)複製代碼
PWA:漸進式網絡開發應用程序(離線可訪問)
插件:workbox --> npm i workbox-webpack-plugin -D
module.exports = {
plugins: [
new WorkboxWebpackPlugin.GenerateSW({
// 1. 幫助 serviceworker 快速啓動
// 2. 刪除舊的 serviceworker
// 生成一個 serviceworker 配置文件
clientsClaim: true,
skipWaiting: true
})
]
}複製代碼
註冊 serviceworker,並處理兼容性問題
"env": { "browser": true}複製代碼
// 註冊 serviceworker,並處理兼容性問題
if ('serviceworker' in navigator) {
window.addEventListener('load', () => {
navigator.serviceworker
.register('/service-worker.js')
.then(() => {
console.log('sw註冊成功了')
})
.catch(() => {
console.log('sw註冊失敗了')
})
})
}複製代碼
插件:npm i thread-loader -D
進程啓動大概爲 600ms,進程通訊也有開銷。只有工做消耗品時間比較長,才須要多進程打包。
module.exports = {
module: {
rules: [ {
test: /\.js$/,
exclude: /node_modules/,
use: [
// 開啓多進程打包
'thread-loader', {
loader: 'babel-loader',
options: {
presets: []
}
}
]
}
]
}
}複製代碼
module.exports = {
externals: {
// 忽略庫名 --> npm包名
jquery: 'jQuery'
}
}複製代碼
<script src="xxx"></script>
對代碼進行單獨打包,(第三方庫:jQuery,react,vue ...),第二次之後打包時再也不打包第三方庫。webpack.dll.js
文件:
注:運行 webpack 時,默認查找 webpack.config.js
,須要運行 webpack.dll.js 文件時,能夠經過運行 webpack --config webpack.dll.js
實現運行
const { resolve } = require('path')
const webpack = require('webpack')
module.exports = {
entry: {
// 最終打包生成的[name] --> jquery
// ['jquery'] --> 要打包的庫是 jquery
jquery: ['jquery']
},
output: {
filename: '[name].js',
path: resolve(__dirname, 'dll'),
library: '[name]_[hash]'
// 打包的庫裏面向外暴露的內容的名字 },
plugins: [
// 打包生成一個 manifest.json --> 提供和 jQuery 映射
new webpack.DllPlugin({
name: '[name]_[hash]', // 映射庫的暴露的內容名稱
path: resolve(__dirname, 'dll/manifest.json')
})
],
mode: 'produciton'
}複製代碼
const { resolve } = require('path')
const webpack = require('webpack')
module.exports = {
plugins: [
// 告訴webpack哪些庫不參與打包,同時使用名稱改變
new webpack.DllReferencePlugin({
path: resolve(__dirname, 'dll/manifest.json')
}),
// 將某個文件打包輸出,並在html中自動引入
new AddAssetHtmlWebpackPlugin({
filepath: resolve(__dirname, 'dll/jquery.js')
})
],
mode: 'produciton'
}
複製代碼