如何在Create React App构建中自定义bundle.js的哈希值为唯一时间戳
把CRA构建的Bundle哈希替换为自定义时间戳的实现方法
当然可以将Create React App构建后生成的bundle文件哈希替换为唯一时间戳,下面是几种可行的实现方案:
方案一:Eject暴露Webpack配置(不推荐)
这种方式会把CRA的内置配置全部暴露出来,后续无法再享受CRA的官方更新,谨慎使用:
- 在项目根目录执行命令:
确认操作后,项目根目录会生成npm run eject # 或 yarn ejectconfig文件夹,里面包含webpack.config.js。 - 打开
config/webpack.config.js,先在文件顶部定义时间戳变量:const timestamp = new Date().getTime(); - 找到
output配置段,修改filename和chunkFilename:output: { filename: `static/js/[name].${timestamp}.js`, chunkFilename: `static/js/[name].${timestamp}.chunk.js`, // 其他原有配置保持不变 } - 找到
MiniCssExtractPlugin的配置(一般在plugins数组里),修改CSS文件的命名规则:new MiniCssExtractPlugin({ filename: `static/css/[name].${timestamp}.css`, chunkFilename: `static/css/[name].${timestamp}.chunk.css`, }), - 执行
npm run build,就能看到以时间戳命名的静态文件了。
方案二:用react-app-rewired + customize-cra(推荐,无需Eject)
这是社区常用的CRA配置修改方案,无需暴露内置配置:
- 先安装依赖:
npm install react-app-rewired customize-cra --save-dev # 或 yarn add react-app-rewired customize-cra -D - 在项目根目录创建
config-overrides.js文件,写入以下内容:const { override } = require('customize-cra'); // 生成唯一时间戳 const timestamp = new Date().getTime(); module.exports = override( (config) => { // 修改JS文件命名 config.output.filename = `static/js/[name].${timestamp}.js`; config.output.chunkFilename = `static/js/[name].${timestamp}.chunk.js`; // 修改CSS文件命名 const miniCssPlugin = config.plugins.find(plugin => plugin.constructor.name === 'MiniCssExtractPlugin' ); if (miniCssPlugin) { miniCssPlugin.options.filename = `static/css/[name].${timestamp}.css`; miniCssPlugin.options.chunkFilename = `static/css/[name].${timestamp}.chunk.css`; } // 如果项目用了PWA,同步修改service worker文件名 const workboxPlugin = config.plugins.find(plugin => plugin.constructor.name === 'InjectManifest' || plugin.constructor.name === 'GenerateSW' ); if (workboxPlugin) { workboxPlugin.options.swDest = `service-worker.${timestamp}.js`; } return config; } ); - 修改
package.json里的scripts命令,替换成react-app-rewired的命令:"scripts": { "start": "react-app-rewired start", "build": "react-app-rewired build", "test": "react-app-rewired test", "eject": "react-scripts eject" } - 执行
npm run build即可生成带时间戳的静态文件。
方案三:用Craco(替代方案,无需Eject)
Craco是另一个CRA配置修改工具,用法和上面类似:
- 安装依赖:
npm install @craco/craco --save-dev # 或 yarn add @craco/craco -D - 在项目根目录创建
craco.config.js文件:const timestamp = new Date().getTime(); module.exports = { webpack: { configure: (webpackConfig) => { // 修改JS文件命名 webpackConfig.output.filename = `static/js/[name].${timestamp}.js`; webpackConfig.output.chunkFilename = `static/js/[name].${timestamp}.chunk.js`; // 修改CSS文件命名 const miniCssPlugin = webpackConfig.plugins.find(p => p.constructor.name === 'MiniCssExtractPlugin' ); if (miniCssPlugin) { miniCssPlugin.options.filename = `static/css/[name].${timestamp}.css`; miniCssPlugin.options.chunkFilename = `static/css/[name].${timestamp}.chunk.css`; } return webpackConfig; } } }; - 修改
package.json的scripts:"scripts": { "start": "craco start", "build": "craco build", "test": "craco test", "eject": "react-scripts eject" } - 执行
npm run build完成构建。
注意事项
- 时间戳是构建时生成的,每次构建都会生成新的时间戳,保证文件名唯一。
- 替换哈希为时间戳后,会失去Webpack内容哈希的优势(内容不变则哈希不变,利于浏览器缓存),如果是为了强制用户刷新缓存,这个方案是可行的;如果想兼顾缓存效率和更新,需要权衡。
- 如果项目使用了PWA的Service Worker,记得同步修改Service Worker的文件名,避免旧缓存影响新内容加载。
内容的提问来源于stack exchange,提问作者Shubhankar Kumar
相关产品推荐
相关产品推荐

