1、配置eslint语法检查
/**
* 语法检查 eslint-loader eslint
* 设置检查规则:
* package.json 中 eslintConfig中设置 或者创建.eslintrc.js文件
* // https://www.npmjs.com/package/eslint-config-airbnb-base
* airbnb-->eslint-config-airbnb-base eslint eslint-plugin-import eslint-import-resolver-node
*
*/
{
test: /\.js$/,
exclude: /node_modules/, // 注意只检查自己写的源代码,第三方库不用检查
loader: 'eslint-loader',
options:{
"fix": true // 自动修复eslint错误
}
},
.eslintrc.js https://www.jianshu.com/p/c81757b9b086
module.exports = {
"env": {
"browser": true,
"es2021": true,
"node": true
},
"extends": "airbnb-base"
}
2、js的兼容性处理
{
/**
* js兼容处理 babel-loader @babel/core
* 1、基本js兼容吃处理 --》 @babel/preset-env
* 2、全部js兼容处理 --> @babel/polyfill (在js文件从 import "@babel/polyfill" 即可,不过会把很多没用到的兼容打包)
* 3、解决部分项目中用到的兼容性问题 按需加载。---》corejs 如果运行报错的话,js文件引入 import "core-js/stable"; import "regenerator-runtime/runtime";
*
*/
test: /\.js$/,
exclude: /node_modules/,
loader: 'babel-loader',
options: {
// 预设: 指示babel做怎么样的兼容性处理
presets: [
[
'@babel/preset-env',
{
useBuiltIns: 'usage', // 按需加载
corejs: {
version: 3, //指定版本
proposals: true
},
// 指定兼容到哪个版本
targets:{
chrome: '60',
firefox: '60',
ie: '9',
safari: '10',
edge: '17'
}
}
]
]
}
},
https://babeljs.io/blog/2019/03/19/7.4.0#migration-from-core-js-2
3、js压缩
mode: "production" // 会自动压缩 会自动调用 UglifyJsPlugin插件
4、html压缩
new HtmlWebpackPlugin({
// 模板
template: './index.html',
minify:{
//移除空格
collapseWhitespace: true,
// 移除注释
removeComments: true
}
}),
5、性能优化
开发环境
- 优化打包构建速度
- 优化代码调试
生产环境
- 优化打包构建速度
- 优化代码运行性能
优化打包构建速度
1开启热更新
特别注意webpack 5中需要设置target:'web'才能开启热更新
target: 'web',
devServer: {
hot: true,
}
HMR hot mdule replacement 热模块替换
作用一个模块发生变化,只会重新打包这一个模块(而不是打包所有模块),极大提升构建速度
- 样式文件:可以使用 HMR功能,style-loader内部实现了。(所以开发模式下一般不要使用css文件提取,使用style-loader)
- js文件:默认不能使用HMR功能,----》需要修改js代码,添加支持HMR功能的代码。 注意:HMR功能对js的处理,只能处理非入口js文件的其他文件
index.js
import './test.js'
if(module.hot){
console.log('hot');
// 一旦 module.hot为true,说明开启了HMR功能
module.hot.accept('./test.js', ()=>{
// 方法会监听test.js文件变化
console.log('test.js变化了');
})
}
- html文件,默认不能使用HMR功能(如果要使用,在entry中引入html文件),同时会导致问题:html文件不能热更新(因为html文件变化,就会重新引入其他文件,所以不用做HMR功能。)
6、sourceMap(devtool)
/**
* source-map: 一种提供源代码到构建后代码映射技术 https://webpack.docschina.org/configuration/devtool/#root
* [inline-|hidden|eval-][nosources-][cheap-[moudle-]]source-map
* source-map 外部 错误代码和源代码位置
* inline-source-map 内联 错误代码和源代码位置 只生成一个内联 source-map
* hidden-source-map 外部 错误代码只提供构建后错误位置 只隐藏源代码,会提示构建后的错误
* eval-source-map 内联 错误代码和源代码位置 生成多个内联 source-map
* nosources-source-map 外部 错误代码无源代码信息 全部隐藏
* cheap-source-map 外部 错误代码和源代码位置(只提示到行)
* cheap-module-source-map 外部 错误代码和源代码位置(只提示到行) module会将loader中source map加入
*
*
*
* 开发环境: 速度快,调试友好
* 速度(eval>inline>cheap...)
* eval-cheap-source-map
* eval-source-map
* 调试友好
* source-map
* cheap-module-source-map
* cheap-source-map
*
* 综合取: eval-source-map | eval-cheap-module-source-map
*
* 生产环境: 源代码是否要隐藏, 调试要不要友好
* 内联会让代码体积变大,所有生产用外部
* 如果要隐藏
* hidden-source-map
* nosources-source-map
*
* 不隐藏的话
* 综合取: source-map | cheap-module-source-map
* */
devtool: 'eval-cheap-source-map'
7、oneof (每一个文件都会到loader中过一遍)
module: {
rules: [
{
// loader只会匹配一个
// 由于只能匹配一个,所有如果下面有匹配两个js 一个做eslitn 一个做兼容处理, 需要提取一个到外面
oneOf: [
{
test: /\.css$/,
...
8、生成环境缓存
对babel进行缓存cacheDirectory: true (让第二次构建速度更快)
test: /\.js$/,
exclude: /node_modules/,
loader: 'babel-loader',
options: {
// 开启babel缓存
// 第二次构建时,会读取之前的缓存
cacheDirectory: true,
...
但是如果有修改之后,上线,页面引入的js,css名称没有变化,这时会读取浏览器缓存,造成修改失败。这个时候就需要给js和css添加hash值,这样打包修改后。引入的js,css就会发生变化
// 输出
output: {
filename: 'js/[name].[hash:10].js', // 给js增加hash
path: path.resolve(__dirname, 'build')
},
...
plugins: [
new MiniCssExtractPlugin({
filename: 'css/[name].[hash:10].css'
}),
hash 区别 (让代码上线运行缓存更好用)
上面 如果我们改js,css也会重新打包。
为了解决看看以下区别
- hash: 每一次webpack构建时会生成唯一的一个hash值
- chunkhash: 根据chunk生成的hash值,如果打包来源于同一个chunk,那么hash值一样(一个入口文件, 入口文件里面移入其他文件,这些些都属于同一个chunk)
- contenthash: 根据文件的内容生成的hash值,不同文件的hash值不一样
所有 上面的hash缓存改为contenthash就可以了。
9、tree-shaking (去掉没有使用的代码)
/**
* tree shaking
* 1.使用es6模块 2.mode为production
* 作用: 减少代码体积
* package.json中设置
* "sideEffects": false 所有代码都没有副作用 (都可以进行tree shaking)
* 问题: 会把其他引入的 css文件给清除掉
* 所有需要设置 sideEffects: ["*.css", "*.less"]
*
* */
10、单独打包node_modules
//入口
entry: {
index: './src/index.js', index2: './src/index2.js'
},
// 输出
output: {
filename: 'js/[name].[contenthash:5].js',
path: path.resolve(__dirname, 'build')
},
/**
* 将 node_modules中代码单独打包成一个chunk最终输出
* 并且分析多入口chunk中,有没有公共的文件,如果有会打包成单独的一个chunk
*/
optimization: {
splitChunks: {
chunks: 'all'
}
},
11、把单独js打包
/***
* 通过js代码,单独打包某个文件为一个chunk
* import 动态导入语法: 将某个文件单独打包
* / * webpackChunkName:'命名打包后的文件名' * /
* */
import(/* webpackChunkName:'hahaha' */'./dandu.js').then(()=>{
console.log('文件加载成功');
}).catch(()=>{
console.log('文件加载失败');
})
webpack 常用配置解析(一)
webpack 常用配置解析(二)
webpack 常用配置解析(三)