webpack 安装
- webpack
- webpack-cli
- webpack-dev-server
yarn add webpack webpack-cli -D
yarn add webpack-dev-server -D
打包编译
npx webpack
webpack-dev-server
配置本地启动服务,该服务内部使用express框架。
官方配置文档
- port: 端口
- compress: 压缩
- client.progress: 显示进度
- open: 打开页面
hot和liveload的区别
- 模块热替换(HMR - hot module replacement)功能会在应用程序运行过程中,替换、添加或删除 模块,而无需重新加载整个页面。
- liveload 监听到文件变化时 dev-server 将会重新加载或刷新页面
devtool设置sourcemap
- cheap:只显示行,不显示列。
- module:添加后可以显示第三方模块中的报错。
- eval:代码显示在eval函数中。
- inline:sourcemap文件不单独现在一个文件。
一般测试环境配置:cheap-module-eval-source-map。
生产环境直接关闭,或者cheap-module-source-map
output设置library
module.exports = {
output:{
library:"defineLibrary",
libraryTarget: "umd", //umd:usually mode即通用模式,支持amd、cmd、es6、静态引入。
}
}
loader
解析js时设置babel-loader的配置文件.babelrc。内部解析时,从下往上,从右向左。
{
presets:[
[
'@babel/preset-env',{
targets: {
chrome: '67'
},
useBuiltIns: 'usage'
}
],
'@babel/preset-react'
]
}
- 配置useBuiltIns: ‘usage’,可以减小打包提交,进行polyfill只编译项目中使用的语法。
- 先解析preset-react然后再解析preset-env。
plugins
- clean-webpack-plugin: 清理dist目录文件
- html-webpack-plugin: 根据设置的html模版,生成启动文件的index.html文件入口
- minicssExtractPlugin:抽离css文件
- workbox-webpack-plugin: PWA 离线缓存应用,创建service worker
优化
tree-shaking
5版本后, 默认会开启,自动过滤掉未使用的代码。
4版本,在package.json中,如果希望所有模块代码都进行tree-shaking过滤,可设置”sideEffects”: false。如果不希望一些模块执行tree-shaking可以设置”sideEffects”: [“@babel/polly-file”]进行排除。
注意⚠️:该功能只在ES Module语法下生效,即es6的 import。
Code Spliting&splitChunks
将代码进行代码分割,分成不同类型的js包。
module.exports = {
optimization:{
splitChunks:{
chunks: 'all', //all:对所有代码生效。async:对异步代码生效。initial:对同步代码分割
minSize: 30000, //超过30kb,才进行代码分割
maxSize: 3000000, //超过了3M,代码会进行二次代码分割。最大限制【某些库超过也无法分割】
minChunks: 2, //拆分前必须共享模块的最小 chunks 数。超过该数值则抽离为单独chunk
maxAsyncRequests: 30, //按需加载时的最大并行请求数,超过了就不进行代码分割
maxInitialRequests: 30, //入口点的最大并行请求数
automaticNameDelimiter: "~", //名称间的分割符
name: true, // cacheGroups中设置的filename生效
cacheGroups:{
// 组名称
common: {
// 抽离公用代码
},
styles:{// 抽离样式代码
},
vendors:{// 抽离第三方模块公用代码
},
default:false
}
}
}
}
webpackPrefetch和webpackPreload
document.addEventListener("click", ()=>{
import(/* webpackPrefetch:true */ "./click.js").then(()=>{
console.log("webpackPrefetch")
})
})
document.addEventListener("click", ()=>{
import(/* webpackPreLoad:true */ "./click.js").then(()=>{
console.log("webpackPreLoad")
})
})
webpackPrefetch等页面核心代码加载完毕,会加载异步代码。webpackPreLoad会和主要代码一起进行加载。更多使用webpackPrefetch
performance
不显示警告
module.exports = {
performance: false
}
DllPlugins
动态链接库 项目中使用了react和react-dom库,打包之后文件会非常大。DllPlugin可以先把react和react-dom单独抽离出来。
- 新建一个专门打包链接库的配置文件,webpack.config.dll.js
let webpack = require('webpack');
let path = require('path');
module.exports = {
mode: 'development',
entry: {
react: ['react', 'react-dom'],
},
output: {
filename: '_dll_[name].js',
path: path.resolve(__dirname, 'dist'),
library: '_dll_[name]',
// libraryTarget: 'var'
},
plugins: [
new webpack.DllPlugin({
name: '_dll_[name]',
path: path.resolve(__dirname, 'dist', 'manifest.json'),
}),
],
};
- 执行npx webpack —config webpack.config.dll.js。打包出来_dll_react.js和manifest.json
- 在html模版中引入_dll_react.js静态文件,可以使用插件add-asset-html-webpack-plugin给html模板添加静态文件
- 给标准webpack配置文件添加插件
plugins: [
new webpack.DllReferencePlugin({
manifest: path.resolve(__dirname, 'dist', 'manifest.json'),
})
]
多进程打包
webpack4使用多线程打包的loader,webpack5可以使用thread-loader。以及parallel-webpack多页面插件打包
给less的loader在plugins中用happypack重新定义id为styles,重新设置less类型的loader解析
module:[
rules:[
{
test: /\.less$/,
use: 'happypack/loader?id=styles',
}
]
],
// ...
plugins:[
new HappyPack({
id: 'styles',
threads: 2,
loaders: ['style-loader', 'css-loader', 'postcss-loader', 'less-loader'],
})
]