Webpack的HTML模板文件名是否需加hash?如何适配express路由?
问题解决方案
一、无需每次手动更新sendFile文件名的实现方法
分两种场景,优先推荐第一种调整webpack配置的方案:
方案1:修改HtmlWebpackPlugin配置(推荐)
直接把html文件名设置为固定值,不需要加hash,从根源避免这个问题:
// webpack.front-end.config.js plugins: [ new HtmlWebpackPlugin({ minify, template: path.resolve('./src/index.html'), filename: 'index.html', // 去掉[hash],用固定文件名 chunks: ['home'] }) ]
对应express路由直接写固定文件名即可:
// server.js const path = require('path'); app.get('/', (req, res) => { res.sendFile(path.join(__dirname, './dist/index.html')); });
缓存问题我们通过服务端响应头配置解决,不会有性能损耗,具体说明看第二部分。
方案2:保留html文件名hash的适配方法
如果一定要给html加hash,可以通过下面两种方式实现路由自动匹配:
- 方法1:打包生成资源映射表
安装webpack-manifest-plugin插件,打包时会生成包含所有资源文件名映射的json文件,express启动时读取该文件获取最新的html文件名:// webpack.front-end.config.js const { WebpackManifestPlugin } = require('webpack-manifest-plugin'); plugins: [ new HtmlWebpackPlugin({ minify, template: path.resolve('./src/index.html'), filename: 'index.[hash].html', chunks: ['home'] }), new WebpackManifestPlugin() ]// server.js const manifest = require('./dist/manifest.json'); const distPath = path.resolve(__dirname, './dist'); app.get('/', (req, res) => { res.sendFile(path.join(distPath, manifest['index.html'])); }); - 方法2:express路由动态匹配html文件
每次请求根路径时,读取dist目录下符合index.*.html规则的文件返回:// server.js const fs = require('fs'); const distPath = path.resolve(__dirname, './dist'); app.get('/', (req, res) => { const htmlFiles = fs.readdirSync(distPath).filter(file => /^index\.[0-9a-f]+\.html$/.test(file)); if (htmlFiles.length) { res.sendFile(path.join(distPath, htmlFiles[0])); } else { res.status(404).send('入口文件不存在'); } });
二、index.html文件名是否需要加hash
完全不需要,理由如下:
html作为应用的入口文件,本身不适合做强缓存,我们只需要在服务端给html配置正确的缓存响应头,就能同时兼顾缓存性能和版本更新的需求:
- 给带hash的静态资源(js、css、图片等)配置响应头
Cache-Control: public, max-age=31536000, immutable,这类文件只有内容变更时hash才会变化,文件名也随之变化,设置一年的强缓存不会有更新问题,性能最优。 - 给html文件配置响应头
Cache-Control: public, max-age=0, must-revalidate,浏览器每次请求时都会和服务端校验资源是否更新,未更新则返回304(不会传输完整文件,几乎无性能损耗),更新则返回最新内容,完全不会出现缓存旧版本的问题。
你提到的用meta标签禁止缓存的方案确实会降低性能,但是只要通过服务端配置上述缓存策略,就不需要加meta标签,也不需要给html文件名加hash,是性价比最高的方案。
内容的提问来源于stack exchange,提问作者Zack
相关产品推荐
相关产品推荐

