獲取全套webpack 4.x教程,請(qǐng)?jiān)L問(wèn)瓦力博客
小菜之前寫(xiě)過(guò)關(guān)于瀏覽器是如何緩存的nginx 緩存{:target="_blank"},感興趣的小伙伴們可以看看。在前面小菜寫(xiě)的配置都是如何去緩存
//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中這樣寫(xiě)filename:'[name].[hash].js',每次打包都會(huì)重新生成js文件(文件名不重名),上傳到服務(wù)器,用戶(hù)在客戶(hù)端上刷新都會(huì)重新從服務(wù)器上拉取js文件,這樣就會(huì)造成請(qǐng)求資源浪費(fèi)。
1.演示
安裝loadsh
之前沒(méi)有安裝過(guò)loadsh庫(kù)伙伴需要安裝一下
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

從上面兩個(gè)截圖可以發(fā)現(xiàn),當(dāng)我們修改index.js文件的代碼后,重新打包生成main.js和vendors~main后面的hash值變了。因?yàn)槲覀冃薷?code>index.js文件的代碼,在index.js中引用的第三方庫(kù)文件,loadsh是不需修改的,所以打包后我們希望mian.js的hash值變,而vendors~main的hash值不變。
2.配置webpack
為了實(shí)現(xiàn)上面的功能,我們需要對(duì)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)
運(yùn)行webpack
yarn run prod

修改index.js
import _ from 'loadsh';
+ let arr = ['hello','wali'];
let str = _.join(arr,'--');
console.log(str)
運(yùn)行webpack
yarn run prod

從上面兩張截圖中可以看出來(lái),當(dāng)我們修改index.js文件內(nèi)容。main.js后面的hash值發(fā)生改變,vendors~main.js后面hash值保持不變。當(dāng)用戶(hù)在瀏覽頁(yè)面時(shí),我們修改本地代碼,打包上傳后,用戶(hù)刷新瀏覽器,瀏覽器只會(huì)請(qǐng)求hash改變的js文件,而hash值沒(méi)變的文件依舊從瀏覽器緩存讀取。
3.總結(jié)
寫(xiě)本小節(jié)的時(shí)候,小菜遇到了兩個(gè)問(wèn)題,分享給大家
[contenthash]打包報(bào)錯(cuò)
小菜在調(diào)式時(shí),直接在build/output.js文件中這樣寫(xiě)
let output = {
path:dirPath.dist,
+ filename: '[name].[contenthash].js',
+ chunkFilename: '[name].[contenthash].js',
publicPath: config.publicPath
}
在運(yùn)行yarn run prod報(bào)錯(cuò),報(bào)錯(cuò)信息
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]在網(wǎng)上找到資料解決連接{:target="_blank"}。在用new webpack.HotModuleReplacementPlugin()熱更新插件的時(shí)候是不能使用[chunkhash]和[contenthash],所以小菜build/plugins.js中修改配置,添加了判斷,只有在development模式下才在使用new webpack.HotModuleReplacementPlugin(),然后在output.js中添加判斷,問(wèn)題就解決了
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
運(yùn)行yarn run dev命令本地服務(wù)器不來(lái)
說(shuō)起來(lái)很搞笑,按道理到上面配置基本都沒(méi)問(wèn)題了,小菜就運(yùn)行yarn run dev啟動(dòng)本地服務(wù),發(fā)現(xiàn)頁(yè)面起不來(lái)


這個(gè)問(wèn)題排查了很久,最終發(fā)現(xiàn)小菜在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 開(kāi)發(fā) 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;
本地服務(wù)路徑./弄錯(cuò)了,所以服務(wù)起起來(lái)但是一直找不到根路徑,頁(yè)面也無(wú)法訪問(wèn)。當(dāng)時(shí)這么寫(xiě)是因?yàn)橄朐谏?code>index.html查看路徑,后面一直沒(méi)有改才會(huì)碰到這個(gè)問(wèn)題。這個(gè)問(wèn)題找到后,小菜將webpack-14{:target="_blank"}這節(jié)配置重新寫(xiě)了一遍,之后又重新跑了一遍,所以小伙伴們可能遇不到我這個(gè)問(wèn)題。