一、webpack 生产环境基本配置理解
-
创建空文件夹,通过
npm init
命令初始化package.json
文件,通过npm install webpack webpack-cli -g
命令全局下载webpack
和webpack-cli
,通过npm install webpack webpack-cli -D
命令本地下载webpack
和webpack-cli
,通过npm i html-webpack-plugin mini-css-extract-plugin optimize-css-assets-webpack-plugin -D
命令下载html-webpack-plugin
、mini-css-extract-plugin
和optimize-css-assets-webpack-plugin
,通过npm i eslint-loader eslint -D
命令下载eslint-loader
和eslint
,通过npm i eslint-config-airbnb-base eslint-plugin-import eslint -D
命令下载eslint-config-airbnb-base
、eslint-plugin-import
和eslint
,eslint-config-airbnb-base
依赖于eslint-plugin-import
和eslint
,通过npm i postcss-loeader postcss-preset-env -D
命令下载postcss-loeader
和postcss-preset-env
,通过npm i css-loader less-loader -D
命令下载css-loader
和less-loader
,通过npm i url-loader file-loader html-loader -D
命令下载url-loader
、file-loader
和html-loader
,通过npm i babel-loader @babel/core @babel/preset-env -D
命令下载babel-loader
、@babel/core
和@babel/preset-env
,通过npm i @babel/polyfill core-js -D
命令下载@babel/polyfill
和core-js
。 -
创建
src
文件夹,在里面创建index.js
、index.html
、a.css
和b.css
文件,代码如下所示:
- index.js
import '../css/a.css'; import '../css/b.css'; function add(x, y) { return x + y; } console.log(add(2, 5));
- index.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>webpack</title> </head> <body> <h1>hello webpack</h1> <div id="box1"></div> <div id="box2"></div> </body> </html>
- a.css
#box1 { width: 100px; height: 100px; background-color: pink; }
- b.css
#box2 { width: 200px; height: 200px; background-color: deeppink; }
- 创建
webpack.config.js
文件,通过require
引入path
、html-webpack-plugin
、mini-css-extract-plugin
和optimize-css-assets-webpack-plugin
。通过process.env.NODE_ENV
定义nodejs
环境变量:决定使用browserslist
的哪个环境。定义一个复用loader
,在下面匹配.css
和.less
文件的时候,需要重复使用。通过MiniCssExtractPlugin.loader
提取css
单独文件,使用css-loader
,使用postcss-loader
做css
的兼容性处理,同时使用postcss-preset-env
做css
的按需加载的兼容性处理,options
是postcss-loader
的配置项,ident
是固定写法,plugins
是使用postcss-preset-env
这个插件。entry
是入口文件,output
是出口文件,filename
是输出的文件名,path
是文件的输出路径。module
是loader
的配置,rules
是详细的loader
配置。第一个规则是匹配以.css
结尾的文件,通过use
使用commonCssLoader
这个抽出复用的loader
。第二个规则是匹配以.less
结尾的文件,通过use
使用commonCssLoader
这个抽出复用的loader
和less-loader
。第三个规则是匹配以.js
结尾的文件,通过exclude
不包括node_modules
,通过enforce
优先执行,通过loader
使用eslint-loader
,通过options
设置自动修复eslint
的错误。第四个规则是匹配以.js
结尾的文件,通过exclude
不包括node_modules
,通过loader
使用babel-loader
,通过options
进行配置,presets
为预设,指示babel
做怎么样的兼容性处理,使用babel/preset-env
这个预设。通过useBuiltIns
按需加载,通过corejs
指定core-js
版本,通过targets
指定兼容性做到哪个版本浏览器。js
兼容性处理需要使用到babel-loader
、@babel/core
和@babel/preset-env
。如果是基本js
兼容性处理,需要使用@babel/preset-env
,但是只能转换基本语法,如promise
高级语法不能转换。如果使用全部js
兼容性处理,需要使用@babel/polyfill
,但是只要解决部分兼容性问题,但是将所有兼容性代码全部引入,体积太大了,所有就需要做兼容性处理的就做做兼容性处理的就做,使用core-js
。第五个规则是匹配以.jpg
、png
和gif
格式的图片资源,通过loader
使用url-loader
,url-loader
依赖于file-loader
。进行options
配置,设置limit
为8 * 1024
,图片大小小于8kb
,就会被base64
处理,给图片做优化。这样做的优点是减少请求数量(减轻服务器压力),缺点是图片体积会更大(文件请求速度更慢)。设置esModule
为false
,由于url-loader
默认使用es6
模块化解析,而html-loader
引入图片是commonjs
,解析时会出问题为[object Module]
,所以关闭url-loader
的es6
模块化,使用commonjs
解析。设置name
为[hash:10].[ext]
,给图片进行重命名,因为图片值为hash
,[hash:10]
取图片的hash
的前10
位,[ext]
取文件原来扩展名。第三个规则是匹配以.html
结尾的文件,使用loader
为html-loader
,处理html
文件的img
图片(负责引入img
,从而能被url-loader
进行处理)。第六个规则是匹配以.html
结尾的文件,通过loader
使用html-loader
。第七个规则是匹配其它资源,通过loader
使用file-loader
,通过options
进行输出路径配置,输出文件夹为media
。plugins
里面是一些插件配置,通过MiniCssExtractPlugin
插件提取css
以及对输出的css
文件进行重命名,通过OptimizeCssAssetsWebpackPlugin
对css
文件进行压缩,通过HtmlWebpackPlugin
复制里面的文件,并自动引入打包输出的所有资源(JS/CSS
),进行minify
配置,通过collapseWhitespace
移除空格,通过removeComments
移除注释,压缩 html 文件。设置mode
为production
,在生产环境下webpack
会自动压缩js
代码,代码如下所示:
const { resolve } = require('path');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const OptimizeCssAssetsWebpackPlugin = require('optimize-css-assets-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
process.env.NODE_ENV = 'production'
const commonCssLoader = [
MiniCssExtractPlugin.loader,
'css-loader',
{
loader: 'postcss-loader',
options: {
ident: 'postcss',
plugins: () => [
require('postcss-preset-env')()
]
}
}
]
module.exports = {
entry: 'src/js/index.js',
output: {
filename: 'built.js',
path: resolve(__dirname, 'build')
},
module: {
rules:[
{
test: /\.css$/,
use: [...commonCssLoader]
},
{
test: /\.less$/,
use: [...commonCssLoader, 'less-loader']
},
{
test: /\.js$/,
exclude: /node_modules/,
enforce: 'pre',
loader: 'eslint-loader',
options: {
fix: true
}
},
{
test: /\.js$/,
exclude: /node_modules/,
loader: 'babel-loader',
options: {
presets: [
'@babel/preset-env',
{
useBuiltIns: 'usage',
corejs: {
version: 3
},
targets: {
chrome: '60',
firefox: '60',
ie: '9',
safari: '10',
edge: '17'
}
}
]
}
},
{
test: /\.(jpg|png|gif)/,
loader: 'url-loader',
options: {
limit: 8 * 1024,
name: '[hash:].[ext]',
outputPath: 'imgs',
esModule: false
}
},
{
test: /\.html$/,
loader: 'html-loader'
},
{
test: /\.(js|css|less|html|jpg|png|gif)/,
loader: 'file-loader',
options: {
outputPath: 'media'
}
}
]
},
plugins: [
new MiniCssExtractPlugin({
filename: 'css/built.css'
}),
new OptimizeCssAssetsWebpackPlugin(),
new HtmlWebpackPlugin({
template: './src/index.html',
minify: {
collapseWhitespace: true,
removeComments: true
}
})
],
mode: 'production'
}
- 在
package.json
这个文件中,进行配置browserslist
,在css
兼容处理的时候,需要帮postcss
找到package.json
中browserslist
里面的配置,通过配置加载指定的css
兼容性样式,development
为开发环境配置,last 1 chrome version
表示兼容最近的chrome
版本,last 1 firefox version
表示兼容最近的firefox
版本,last 1 safari version
表示兼容最近的safari
版本。production
为生产环境配置,>0.2%
表示大于99.8%
的浏览器,not dead
表示不要已经死的浏览器,not op_mini all
表示不要使用op_mini all
浏览器。eslint
并不知道要检查什么,所有就有airbnb
风格指南,airbnb
需要使用eslint-config-airbnb-base
这个库,这个库依赖于eslint-plugin-import
和eslint
。所有需要在package.json
中eslintConfig
中设置检查规则,设置extends
为airbnb-base
,代码如下所示:
"browserslist": {
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
],
"production": [
">0.2%",
"not dead",
"not op_mini all"
]
},
"eslintConfig": {
"extends": "airbnb-base"
}
- 在命令行输入
webpack
命令,资源就会进行打包,以及相应的压缩代码。
二、webpack 性能优化配置分析
-
webpack
性能优化分为开发环境性能优化和生产环境性能优化。 -
webpack
开发环境性能优化可以从优化打包构建速度和优化代码调试两个方面。通过HMR
可以优化打包构建速度,通过source-map
可以优化代码调试。 -
webpack
生产环境性能优化可以从 优化打包构建速度和优化代码运行的性能两个方面。通过oneOf
、babel
缓存、多进程打包、externals
和dll
可以优化打包构建速度。通过 缓存(hash-chunkhash-contenthash
)、tree shaking
、code split
、懒加载/预加载和pwa
可以优化代码运行的性能。