如何避免Docusaurus构建生成带~的runtime~main.[hash].js文件?
解决Docusaurus构建生成含波浪号(~)文件名导致的服务器500错误
问题背景
使用Docusaurus构建文档站点时,执行docusaurus build后会生成runtime~main.c20a87de.js这类带波浪号的文件,部署到禁止文件名含~的服务器后,搜索框因资源加载500错误无法正常工作。
解决方案
方法1:通过Webpack配置直接修改文件名规则
你的原有配置未生效,大概率是因为未完整覆盖Docusaurus默认的Webpack优化配置,尤其是splitChunks的缓存组设置。尝试使用以下自定义插件:
module.exports = function forceWebpackRuntimeConfig() { return { name: 'force-webpack-runtime-config', configureWebpack(config, isServer) { // 合并原有优化配置,避免丢失默认设置 config.optimization = { ...config.optimization, // 固定runtime chunk名称,避免生成带~的文件名 runtimeChunk: { name: 'runtime', }, splitChunks: { ...config.optimization.splitChunks, chunks: 'all', cacheGroups: { ...config.optimization.splitChunks.cacheGroups, defaultVendors: { test: /[\\/]node_modules[\\/]/, name: 'vendors', chunks: 'all', }, }, }, }; // 统一输出文件名规则,确保无波浪号 config.output.filename = '[name].[contenthash].js'; config.output.chunkFilename = '[name].[contenthash].chunk.js'; return config; }, }; };
将上述代码保存为plugins/force-webpack-config.js,然后在docusaurus.config.js中注册插件:
module.exports = { // ...其他站点配置 plugins: [ './plugins/force-webpack-config.js', // ...其他已有的插件 ], };
完成后清理缓存并重新构建:
rm -rf node_modules/.cache && docusaurus build
方法2:构建后自动重命名文件(兜底方案)
如果方法1仍无法阻止Webpack生成带~的文件,可添加一个构建后钩子插件,自动重命名文件并替换所有引用:
const fs = require('fs'); const path = require('path'); module.exports = function renameRuntimeFiles() { return { name: 'rename-runtime-files', postBuild({ outDir }) { const buildDir = path.resolve(outDir); // 筛选所有带~的runtime文件 const targetFiles = fs.readdirSync(buildDir).filter(file => file.startsWith('runtime~')); targetFiles.forEach(oldName => { const newName = oldName.replace('~', '-'); // 重命名文件 fs.renameSync(path.join(buildDir, oldName), path.join(buildDir, newName)); // 更新HTML中的引用 const htmlFiles = fs.readdirSync(buildDir).filter(file => file.endsWith('.html')); htmlFiles.forEach(file => { const content = fs.readFileSync(path.join(buildDir, file), 'utf8'); fs.writeFileSync(path.join(buildDir, file), content.replace(oldName, newName)); }); // 更新其他JS文件中的引用 const jsFiles = fs.readdirSync(buildDir).filter(file => file.endsWith('.js') && file !== newName); jsFiles.forEach(file => { const content = fs.readFileSync(path.join(buildDir, file), 'utf8'); fs.writeFileSync(path.join(buildDir, file), content.replace(oldName, newName)); }); }); }, }; };
同样将此插件注册到docusaurus.config.js中,构建后会自动处理带~的文件。
内容的提问来源于stack exchange,提问作者Bharat
相关产品推荐
相关产品推荐

