1. 缓存
我们使用 webpack 来打包我们的模块化后的应用程序,webpack 会生成一个可部署的 /dist 目录,然后把打包后的内容放置在此目录中。只要 /dist 目录中的内容部署到 server 上,client(通常是浏览器)就能够访问此 server 的网站及其资源。而最后一步获取资源是比较耗费时间的,这就是为什么浏览器使用一种名为缓存的技术。可以通过命中缓存,以降低网络流量,使网站加载速度更快
1.1 output文件名
之前的输出文件名是这样的,会导致即使修改了文件中的内容由于文件名没变
output: {
filename: '[name].bundle.js',
path: path.resolve(__dirname, './dist'),
clean: true,
assetModuleFilename: 'images/[contenthash][ext]'
},
现在修改成这样,可以实现更新文件名:
output: {
filename: '[name].[contenthash].js',
path: path.resolve(__dirname, './dist'),
clean: true,
assetModuleFilename: 'images/[contenthash][ext]'
},
1.2 缓存第三方库
将第三方库(library)(例如 lodash )提取到单独的 vendor chunk 文件中,是比较推荐的做法,这是因为,它们很少像本地的源代码那样频繁修改。因此通过实现以上步骤,利用 client 的长效缓存机制,命中缓存来消除请求,并减少向 server 获取资源,同时还能保证 client 代码和 server 代码版本一致。
将optimization中的splitChunks修改成这样:
optimization: {
minimizer: [
new CssMinimizerPlugin()
],
splitChunks: {
cacheGroups: {
vendor: {
// 找到node_modules
test: /[\\/]node_modules[\\/]/,
// 起个名字
name: 'vendors',
// 对所有chunk作处理
chunks: 'all'
}
}
}
}
1.3 将所有js打包成一个文件夹
output中的filiename修改成这样即可:
filename: 'scripts/[name].[contenthash].js'
2. 拆分开发环境和生产环境配置
之前我们只能手工的来调整 mode 选项,实现生产环境和开发环境的切换,且很多配置在生产环境和开发环境中存在不一致的情况,比如开发环境没有必要设置缓存,生产环境还需要设置公共路径等等。
因此该章尝试实现拆分两种环境的配置。
2.1 公共路径
用于指定所有资源的基础路径,通过在output中添加一个属性实现:
output: {
filename: 'scripts/[name].[contenthash].js',
path: path.resolve(__dirname, './dist'),
clean: true,
assetModuleFilename: 'images/[contenthash][ext]',
// 公共路径
publicPath: 'http://localhost:8080/'
}
2.2 环境变量
可以在输入命令时添加环境变量实现调控参数,比如
npx webpack --env production --env name=yoimiya
就传入了两个参数,一个production:true,一个name:yoimiya。
首先要把module.exports变成一个函数,然后在函数中返回一个对象,就可以接收到命令行的参数:
module.exports = (env) =>{
return {
}
}
此时我们改一下mode表达式,使它根据参数动态改变:
mode: env.production ? 'production' : 'development'
此时我们需要一个插件来压缩一下js代码,就和当时压缩css一样的:
npm install terser-webpack-plugin -D
然后加到optimization里
optimization: {
minimizer: [
new CssMinimizerPlugin(),
new TerserPlugin()
],
}
2.3 拆分配置文件
实现不同配置文件对应不同开发模式的配置
我们首先创建一个config文件夹,创建三个文件,分别对应公共代码,开发环境专用代码和生产环境专用代码。
我们把两种环境的公共代码提取到common中,模式中只留下自用代码,比如dev只留下这些即可:
module.exports = {
output: {
filename: 'scripts/[name].js'
},
mode: 'development',
devtool: 'inline-source-map',
devServer: {
static: './dist'
}
}
而prod需要留下这些:
const CssMinimizerPlugin = require('css-minimizer-webpack-plugin')
const TerserPlugin = require('terser-webpack-plugin')
module.exports = {
output: {
filename: 'scripts/[name].[contenthash].js',
publicPath: 'http://localhost:8080/'
},
mode: 'production',
optimization: {
minimizer: [
new CssMinimizerPlugin(),
new TerserPlugin()
]
},
performance: {
hints: false
}
}
那么如何将这几个文件合并呢?需要用到一个工具:webpack-merge
npm i webpack-merge -D
安装好后我们需要在刚刚的config文件夹下再创建一个webpack.config.js,在其中写入以下内容:
const { merge } = require('webpack-merge')
const commonConfig = require('./webpack.config.common')
const productionConfig = require('./webpack.config.prod')
const developmentConfig = require('./webpack.config.dev')
module.exports = (env) => {
switch (true) {
case env.development:
return merge(commonConfig, developmentConfig)
case env.production:
return merge(commonConfig, productionConfig)
}
}
然后在package.json中定义一下两种运行方式的简写即可:
"scripts": {
"start": "webpack serve -c ./config/webpack.config.js --env development",
"build": "webpack -c ./config/webpack.config.js --env production"
}