Express.js如何动态发送Webpack编译生成的带hash后缀的index.html文件
方案1:修改Webpack配置(最优解)
HTML作为页面入口文件不需要加hash做缓存控制,hash只需要配置给JS、CSS、图片等静态资源即可,直接改HtmlWebpackPlugin的文件名配置为固定值,无需修改Express路由逻辑:
// 修改webpack.static.config.js中HtmlWebpackPlugin的配置 new HtmlWebpackPlugin({ minify, template: path.resolve('./src/index.html'), filename: 'index.html', // 移除hash字段,使用固定文件名 chunks: ['home'] })
Express路由直接引用固定路径即可:
const path = require('path') app.get('/', (req, res) => { res.sendFile(path.resolve(__dirname, '../dist/index.html')) })
另外你现有webpack配置里的DefinePlugin部分存在语法错误,reduce回调里返回的变量名写错了,需要修正为:
const definition = Object.keys(env).reduce((variables, key, i) => { variables[key] = JSON.stringify(env[key]); return variables; // 原代码写的def,未定义会报错 }, {});
方案2:动态匹配带hash的HTML(特殊场景使用)
如果因为业务需求必须保留HTML文件名的hash,可以在Express中通过文件匹配动态获取目标HTML路径:
- 先安装
clean-webpack-plugin,每次编译前清空dist目录,避免匹配到历史旧文件:
// webpack.static.config.js中添加清理插件 const { CleanWebpackPlugin } = require('clean-webpack-plugin') module.exports = { // 其他原有配置不变 plugins: [ new CleanWebpackPlugin(), // 放在插件列表最前面 // 原有其他插件 ] }
- Express中编写文件匹配逻辑:
const fs = require('fs') const path = require('path') const distDir = path.resolve(__dirname, '../dist') // 预匹配dist下的带hash的index.html,生产环境启动时执行一次即可 const getIndexHtmlPath = () => { const distFiles = fs.readdirSync(distDir) const targetHtml = distFiles.find(file => /^index\.[0-9a-f]+\.html$/.test(file)) if (!targetHtml) throw new Error('未找到编译后的入口HTML文件,请先执行Webpack打包') return path.resolve(distDir, targetHtml) } app.get('/', (req, res) => { res.sendFile(getIndexHtmlPath()) })
如果是开发环境开启热更新的场景,可把getIndexHtmlPath的调用放到请求回调内部,每次请求都重新匹配最新文件即可。
内容的提问来源于stack exchange,提问作者Zack
相关产品推荐
相关产品推荐

