Vite构建后index.html中script路径未变,是因为它仅将index.html视为入口模板而非构建目标,不解析HTML文本重写src属性;需确保index.html在根目录、脚本用相对路径、base配置匹配部署路径,并依赖vite:html插件自动注入正确资源路径。

构建后 index.html 里 <script></script> 还指向 /src/main.js?不是配置漏了,是 Vite 根本不重写 HTML —— 它只处理模块脚本,不改 HTML 文本本身。必须靠路径约定 + 插件机制才能让产出可运行。
为什么 vite build 后 HTML 脚本路径没变
Vite 默认把 index.html 当作入口模板,不是构建目标。它不会解析 HTML 文本去替换 src 属性,只对其中的模块脚本(如 <script type="module"></script>)做依赖分析和注入。所以你看到的 ./main.js 或 /src/main.js 会被原样保留,而实际打包输出的是 assets/index-xxx.js,导致 404 或空白页。
-
index.html必须放在项目根目录,Vite 才认它为入口模板 - 所有
<script src="..."></script>必须用相对路径(./main.js),不能用绝对路径(/src/main.js) - 如果改过
build.rollupOptions.output.entryFileNames,要确保匹配index入口,比如assets/index-[hash].js,否则内置 HTML 插件找不到 chunk 去注入 - 检查
dist/index.html中的<script src="..."></script>是否已变成assets/index-xxx.js,没变就是上述某条没满足
如何让构建后的 HTML 正确加载资源
关键不是“手动改 HTML”,而是让 Vite 的 HTML 插件自动注入正确路径。Vite 内置该能力,但需满足前提:
-
base配置必须与部署路径一致:根目录部署用base: './',子路径部署(如/myapp/)用base: '/myapp/' -
public目录下的文件(如favicon.ico、robots.txt)会原样复制到dist根目录,引用时写/favicon.ico即可 - 不要在
index.html里硬编码src为开发路径;也不要用public下的 JS/CSS 然后手动<script src="/public/xxx.js"></script>—— 这绕过了构建流程,无法哈希、无法压缩、无法注入环境变量 - 若需动态 title、meta 或注入 script 标签,用
vite-plugin-html,而不是手写 EJS 模板再塞进src/—— Vite 只处理根目录index.html,其他 HTML 文件默认当静态资源复制
public 和 src/assets 的资源该怎么放
二者处理逻辑完全不同,混用会导致路径失效或构建警告:
立即学习“前端免费学习笔记(深入)”;
-
public下的资源:不做任何处理,直接复制到dist根目录。适合favicon.ico、manifest.json、第三方 SDK 的未打包 JS(如百度统计hmt.js)。引用时必须以/开头,如<img src="/logo.png" alt="HTML在Vite构建工具中的自动化处理与打包配置" > -
src/assets下的资源:参与构建,被哈希、压缩、可能内联(import logo from '@/assets/logo.png',或在 CSS 中用url('@/assets/bg.jpg')—— 别名需在vite.config.ts中配置resolve.alias - 别写
./public/logo.png或/public/logo.png:开发时能访问,构建后路径错乱,Vite 会警告并生成错误路径 - SVG 图标若需作为组件使用,别放
public,应走vite-svg-loader或vite-plugin-svgr插件导入
多页应用(MPA)或带变量的 HTML 怎么处理
Vite 默认只处理一个 index.html。想支持多个入口或动态内容,必须用插件,不能靠“多建几个 HTML 文件”:
- 不要删掉根目录
index.html,另建src/template.html并指望 Vite 自动识别 —— 它只会当普通文本复制过去 - 用
vite-plugin-html配置多个入口:entry: ['src/main.ts', 'src/admin/main.ts'],配合template: 'public/admin.html',插件会为每个入口生成对应 HTML - 环境变量注入靠插件的
inject.data,例如传{ title: import.meta.env.VITE_APP_TITLE },模板里写<title></title> - 压缩 HTML 是可选功能,开
minify: true即可,但注意 EJS 语法(如)不能被误删,需确认插件版本支持安全压缩
最常被忽略的点:Vite 不会“理解” HTML 文本语义,它只按约定规则注入 script/style 标签。一旦路径写死、base 配置不一致、或 rollup output 名称格式被破坏,HTML 就会断链 —— 这不是 bug,是设计使然。



















