You need to enable JavaScript to run this app. Vite构建HTML文件时静态资源路径异常,嵌套页面路径无法匹配需求
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.19 06:06:05