获取全套webpack 4.x教程,请访问瓦力博客
小菜之前写过关于浏览器是如何缓存的nginx 缓存{:target="_blank"},感兴趣的小伙伴们可以看看。在前面小菜写的配置都是如何去缓存
//build/output.js
const srcPath = require('./base/path');
const config = require('./base/config');
let output = {
path: srcPath.dist,
filename: '[name].[hash].js',
publicPath: config.publicPath
}
module.exports = output;
如果output.js
中这样写filename:'[name].[hash].js'
,每次打包都会重新生成js文件(文件名不重名),上传到服务器,用户在客户端上刷新都会重新从服务器上拉取js文件,这样就会造成请求资源浪费。
1.演示
安装loadsh
之前没有安装过loadsh库伙伴需要安装一下
yarn add loadsh
index.js
import _ from 'loadsh';
let arr = ['hello','world'];
let str = _.join(arr,'--');
console.log(str)
编译webpack
yarn run prod
修改index.js
import _ from 'loadsh';
+ let arr = ['hello','wali'];
let str = _.join(arr,'--');
console.log(str)
编译webpack
yarn run prod
从上面两个截图可以发现,当我们修改index.js文件的代码后,重新打包生成main.js
和vendors~main
后面的hash值变了。因为我们修改index.js
文件的代码,在index.js
中引用的第三方库文件,loadsh
是不需修改的,所以打包后我们希望mian.js
的hash值变,而vendors~main
的hash值不变。
2.配置webpack
为了实现上面的功能,我们需要对webpack配置做一些改变
build/output.js
const dirPath = require('./base/path');
const config = require('./base/config');
let output = {
path:dirPath.dist,
+ filename: config.NODE_ENV == 'development'?'[name].js':'[name].[contenthash].js',
+ chunkFilename: config.NODE_ENV == 'development'?'[name].js':'[name].[contenthash].js',
publicPath: config.publicPath
}
module.exports = output
build/optimization.js
let optimization = {
usedExports: true,
splitChunks: {
chunks: 'all',
minSize: 30000,
maxSize: 0,
minChunks: 1,
maxAsyncRequests: 5,
maxInitialRequests: 3,
automaticNameDelimiter: '~',
name: true,
cacheGroups: {
vendors: {
test: /[\\/]node_modules[\\/]/,
priority: -10
},
default: {
minChunks: 2,
priority: -20,
reuseExistingChunk: true
}
}
},
+ runtimeChunk:{
+ name: entrypoint => `runtimechunk~${entrypoint.name}`
+ }
}
module.exports = optimization
build/plugins.js
const dirpath = require('./base/path');
const config = require('./base/config');
const webpack = require('webpack');
const HtmlWebpackPlugin = require('html-webpack-plugin'); //生成html文件
const { CleanWebpackPlugin } = require('clean-webpack-plugin'); //清除
const MiniCssExtractPlugin = require("mini-css-extract-plugin"); //css样式提取
let plugins = [
new HtmlWebpackPlugin({
title: '瓦力博客',
template: dirpath.src + '/index.html' //以src/index.html为编译模板
}),
new MiniCssExtractPlugin({
filename: config.NODE_ENV == 'development'?'[name.css]': `${dirpath.css}/[name].[hash].css`,
chunkFilename: config.NODE_ENV == 'development'?'[id].css': `${dirpath.css}/[id].[hash].css`
}), //css提取
new CleanWebpackPlugin(),
- new webpack.HotModuleReplacementPlugin()
]
+ if('development' == config.NODE_ENV){
+ plugins.push(new webpack.HotModuleReplacementPlugin());
+ }
module.exports = plugins;
index.js
import _ from 'loadsh';
let arr = ['hello','world'];
let str = _.join(arr,'--');
console.log(str)
运行webpack
yarn run prod
修改index.js
import _ from 'loadsh';
+ let arr = ['hello','wali'];
let str = _.join(arr,'--');
console.log(str)
运行webpack
yarn run prod
从上面两张截图中可以看出来,当我们修改index.js文件内容。main.js
后面的hash值发生改变,vendors~main.js
后面hash值保持不变。当用户在浏览页面时,我们修改本地代码,打包上传后,用户刷新浏览器,浏览器只会请求hash改变的js文件,而hash值没变的文件依旧从浏览器缓存读取。
3.总结
写本小节的时候,小菜遇到了两个问题,分享给大家
[contenthash]打包报错
小菜在调式时,直接在build/output.js
文件中这样写
let output = {
path:dirPath.dist,
+ filename: '[name].[contenthash].js',
+ chunkFilename: '[name].[contenthash].js',
publicPath: config.publicPath
}
在运行yarn run prod
报错,报错信息
ERROR in chunk runtimechunk~main [entry]
[name].[contenthash].js
Cannot use [chunkhash] or [contenthash] for chunk in '[name].[contenthash].js' (use[hash] instead)
不能使用[chunkhash]
或[contenthash]
在网上找到资料解决连接{:target="_blank"}。在用new webpack.HotModuleReplacementPlugin()
热更新插件的时候是不能使用[chunkhash]
和[contenthash]
,所以小菜build/plugins.js
中修改配置,添加了判断,只有在development
模式下才在使用new webpack.HotModuleReplacementPlugin()
,然后在output.js
中添加判断,问题就解决了
const dirPath = require('./base/path');
const config = require('./base/config');
let output = {
path:dirPath.dist,
+ filename: config.NODE_ENV == 'development'?'[name].js':'[name].[contenthash].js',
+ chunkFilename: config.NODE_ENV == 'development'?'[name].js':'[name].[contenthash].js',
publicPath: config.publicPath
}
module.exports = output
运行yarn run dev命令本地服务器不来
说起来很搞笑,按道理到上面配置基本都没问题了,小菜就运行yarn run dev
启动本地服务,发现页面起不来
这个问题排查了很久,最终发现小菜在build/base/config.js
中将
let _mode = process.argv[process.argv.length - 1];
let env = _mode.replace(/--mode=(.+)/g,"$1");
let config = {
NODE_ENV: env == 'development'?'development':'production', //development 开发 production 线上
- publicPath: env == 'development'?'./':'http://www.waliblog.com',
+ publicPath: env == 'development'?'/':'http://www.waliblog.com',
apiUrl:'http://www.waliblog.com',
port: 9999
}
module.exports = config;
本地服务路径./
弄错了,所以服务起起来但是一直找不到根路径,页面也无法访问。当时这么写是因为想在生成index.html
查看路径,后面一直没有改才会碰到这个问题。这个问题找到后,小菜将webpack-14{:target="_blank"}这节配置重新写了一遍,之后又重新跑了一遍,所以小伙伴们可能遇不到我这个问题。