Vite构建HTML文件时静态资源路径异常,嵌套页面路径无法匹配需求
问题原因
你当前的配置下Vite的base: './'是相对于你配置的root: 'src'目录计算路径,所有入口页面都会统一使用相对于src根的资源路径,不会根据页面的嵌套层级动态调整,因此嵌套页面的资源路径会指向错误的位置。
解决方案
我们可以通过添加一个自定义Rollup插件,在构建阶段根据每个HTML文件的嵌套层级动态替换资源前缀:
步骤1:添加自定义插件到vite.config.ts
在配置的plugins数组中加入以下插件代码:
{ name: 'html-adjust-asset-path', transformIndexHtml: { order: 'post', handler(html, ctx) { // 计算当前html文件相对于dist根目录的层级 const relativePath = ctx.path.replace(/^\/|\/[^\/]+$/g, '') const level = relativePath ? relativePath.split('/').length : 0 // 生成对应的前缀,比如层级1就是../,层级2就是../../ const prefix = level ? '../'.repeat(level) : './' // 替换所有/assets/开头的资源路径 return html.replace(/(["'])\/assets\//g, `$1${prefix}assets/`) } } }
步骤2:调整base配置
把原来的base: './'修改为base: '/',确保构建生成的资源路径统一以/assets/开头,方便插件统一替换。
修改后完整配置示例
import * as glob from 'fast-glob'; import { resolve, join } from 'path'; import { defineConfig } from 'vite'; import eslintPlugin from 'vite-plugin-eslint'; import styleLint from '@amatlash/vite-plugin-stylelint'; import * as tsconfig from './tsconfig.json'; const paths = tsconfig.compilerOptions.paths; const defaultAlias = Object.keys(paths).reduce((acc, key) => { const value = paths[key][0]; const path: string = key.replace('/*', ''); acc.push({ find: path, replacement: resolve(__dirname, value.replace('/*', '')), }); return acc; }, [] as any[]); const files = glob.sync(resolve(__dirname, 'src') + '/**/*.html').reduce((acc: Record<string, string>, cur: string) => { let name = cur .replace(join(__dirname) + '/src/', '') .replace('/index.html', '') .replace('.html', ''); if (name === '') { name = 'home'; } acc[name] = cur; return acc; }, {}); console.clear(); console.log(files); export default defineConfig({ root: 'src', base: '/', // 修改此处 clearScreen: false, plugins: [ // 新增的自定义插件放最前面 { name: 'html-adjust-asset-path', transformIndexHtml: { order: 'post', handler(html, ctx) { const relativePath = ctx.path.replace(/^\/|\/[^\/]+$/g, '') const level = relativePath ? relativePath.split('/').length : 0 const prefix = level ? '../'.repeat(level) : './' return html.replace(/(["'])\/assets\//g, `$1${prefix}assets/`) } } }, styleLint(), eslintPlugin({ fix: true, exclude: ['node_modules', '*.html', 'src/pages', 'src/index.html'], }), ], build: { rollupOptions: { input: files, }, outDir: '../dist', }, resolve: { alias: [ ...defaultAlias, { find: /~(.+)/, replacement: join(process.cwd(), 'node_modules/$1'), }, ], }, });
额外适配说明
如果你的资源还包括css里引用的图片、字体等静态资源,需要额外在build配置中添加以下输出规则,保证css内的资源路径也能正确适配相对路径:
build: { assetsInlineLimit: 0, rollupOptions: { input: files, output: { assetFileNames: 'assets/[name].[hash][extname]', chunkFileNames: 'assets/[name].[hash].js', entryFileNames: 'assets/[name].[hash].js' } } }
内容的提问来源于stack exchange,提问作者priosshrsth
相关产品推荐
相关产品推荐

