是否存在增量式文件命名的Webpack配置?CRA构建命名修改方法
当然可以实现这种增量式的版本命名!不过因为 Create React App(CRA)默认封装了 Webpack 配置,我们需要先解锁配置,再调整输出文件名的规则。下面是具体的实现步骤,我会推荐无需 eject 的更安全方案(eject 不可逆,会暴露所有配置文件):
1. 准备工作:安装依赖并修改脚本
首先安装 react-app-rewired 和 customize-cra,这两个工具可以让我们在不 eject 的情况下修改 CRA 的 Webpack 配置:
npm install react-app-rewired customize-cra --save-dev
接着修改 package.json 里的脚本,把默认的 start、build、test 替换为 react-app-rewired 对应的命令:
"scripts": { "start": "react-app-rewired start", "build": "node build-version.js && react-app-rewired build", "test": "react-app-rewired test", "eject": "react-scripts eject" }
2. 实现版本号自动递增
我们需要一个文件来存储当前版本号,每次构建前自动递增:
- 在项目根目录创建
version.json,初始内容如下:
{"version": 1}
- 再创建
build-version.js脚本,用来读取并递增版本号:
const fs = require('fs'); const path = require('path'); const versionPath = path.resolve(__dirname, 'version.json'); try { const versionData = JSON.parse(fs.readFileSync(versionPath, 'utf8')); versionData.version += 1; fs.writeFileSync(versionPath, JSON.stringify(versionData, null, 2)); console.log(`版本号已更新为 v${versionData.version}`); } catch (err) { console.error('更新版本号失败:', err); }
3. 修改 Webpack 输出规则
在项目根目录创建 config-overrides.js,这个文件用来覆盖 CRA 的默认 Webpack 配置:
const { override, adjustWorkbox } = require('customize-cra'); const MiniCssExtractPlugin = require('mini-css-extract-plugin'); const fs = require('fs'); const path = require('path'); // 读取当前版本号 const versionData = JSON.parse(fs.readFileSync(path.resolve(__dirname, 'version.json'), 'utf8')); const versionTag = `v${versionData.version}`; module.exports = override( // 调整 JS 和 CSS 的输出文件名 (config) => { // 修改 JS 输出规则 config.output.filename = `static/js/main.${versionTag}.js`; config.output.chunkFilename = `static/js/[name].${versionTag}.chunk.js`; // 修改 CSS 输出规则(CRA 用 MiniCssExtractPlugin 处理 CSS) const cssPlugin = config.plugins.find(plugin => plugin instanceof MiniCssExtractPlugin); if (cssPlugin) { cssPlugin.options.filename = `static/css/main.${versionTag}.css`; cssPlugin.options.chunkFilename = `static/css/[name].${versionTag}.chunk.css`; } return config; }, // 如果你的项目启用了 PWA,调整 service-worker 的文件名 adjustWorkbox(wbConfig => { wbConfig.swDest = `service-worker.${versionTag}.js`; return wbConfig; }) );
4. 可选:清理旧构建产物
因为增量式命名会保留所有历史版本的文件,建议每次构建前先清空 build 目录。安装 rimraf 工具:
npm install rimraf --save-dev
然后修改 package.json 的 build 脚本:
"build": "rimraf build && node build-version.js && react-app-rewired build"
效果验证
现在执行 npm run build,首次构建会生成 main.v1.js、main.v1.css;再次执行构建,版本号会自动递增为 v2,产物文件名也会对应更新。
补充说明
如果你不介意不可逆的 eject 操作,也可以执行 npm run eject 暴露所有配置文件,然后直接修改 config/webpack.config.js 里的 output.filename 和 MiniCssExtractPlugin 的 filename 配置,再配合版本递增脚本即可,逻辑和上面一致。
内容的提问来源于stack exchange,提问作者michoprogrammer

