Vite React项目构建时如何为404.html注入base-url?
解决Vite React中public目录404.html的base-url适配问题
方法一:通过Vite配置钩子手动替换
Vite默认只对入口index.html做base-url注入,public下的其他HTML文件不会被处理。可以在vite.config.js中使用transformIndexHtml钩子,手动读取并替换404.html中的base占位符:
- 先在
public/404.html里用自定义占位符(比如{{BASE_URL}})代替无效的{import.meta.env.BASE_URL},示例:
<link rel="icon" href="{{BASE_URL}}favicon.ico" />
- 在
vite.config.js中添加钩子逻辑:
import { defineConfig } from 'vite' import react from '@vitejs/plugin-react' import fs from 'fs' import path from 'path' export default defineConfig({ plugins: [ react(), { name: 'transform-404-html', transformIndexHtml(html, ctx) { // 只处理404.html if (ctx.filename?.endsWith('404.html')) { const baseUrl = process.env.BASE_URL || '/'; return html.replace(/{{BASE_URL}}/g, baseUrl); } return html; }, // 确保构建时处理public下的404.html并输出到产物 generateBundle(options, bundle) { const publicDir = path.resolve(__dirname, 'public'); const fourOhFourPath = path.join(publicDir, '404.html'); const fourOhFourContent = fs.readFileSync(fourOhFourPath, 'utf-8'); const baseUrl = process.env.BASE_URL || '/'; const processedContent = fourOhFourContent.replace(/{{BASE_URL}}/g, baseUrl); bundle['404.html'] = { type: 'asset', fileName: '404.html', source: processedContent }; } } ], base: process.env.BASE_URL || '/' })
这个逻辑会在构建时读取public里的404.html,替换占位符后输出到dist目录,开发环境也能同步生效。
方法二:把404.html设为额外入口(不引入JS/CSS)
如果不想用钩子,也可以把404.html添加为Vite的额外入口,同时配置阻止自动注入JS/CSS:
- 在
vite.config.js的build配置中添加入口:
import { defineConfig } from 'vite' import react from '@vitejs/plugin-react' import path from 'path' export default defineConfig({ plugins: [react()], base: process.env.BASE_URL || '/', build: { rollupOptions: { input: { main: path.resolve(__dirname, 'index.html'), '404': path.resolve(__dirname, 'public/404.html') } } }, // 阻止给404.html注入自动生成的JS/CSS transformIndexHtml(html, ctx) { if (ctx.filename?.endsWith('404.html')) { return html; } return html; } })
这种方式下,Vite会自动处理404.html里的资源引用(把/xxx替换成${base}/xxx),同时因为我们在钩子中返回原HTML,不会自动添加JS和CSS入口,完全符合需求。
注意事项
- 构建时指定base-url的方式不变:可以通过命令行
vite build --base=/my-website/,或者直接在vite.config.js的base字段配置。 - 方法一中的占位符可以自定义,只要和替换逻辑对应即可,避免和其他语法冲突。
内容的提问来源于stack exchange,提问作者PlayerG9
相关产品推荐
相关产品推荐

