做者:心静止水(前端时空)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'
}
复制代码