从CRA迁移至Vite后第三方组件库资源加载失败问题
解决Vite开发模式下第三方组件库资源404问题
问题分析
从CRA迁移到Vite后,开发模式下组件库的图片、字体等资源出现404,控制台显示请求路径为node_modules/assets,但实际资源位于node_modules/component-library/dist/assets。构建后资源正常加载,原因是:
- Vite开发模式基于ES模块直接加载,对第三方库资源的解析逻辑和CRA(webpack)不同;
- 组件库内部的资源引用路径在开发时被Vite解析为项目根目录下的
assets,而非组件库dist目录下的对应路径; - 构建阶段Vite会自动收集并复制第三方库资源到输出目录,因此无问题。
解决方案
方案一:开发服务器请求路径重写
在Vite配置中添加configureServer钩子,拦截/assets开头的请求,重定向到组件库的实际资源路径:
/// <reference types="vitest" /> import { defineConfig } from 'vite' import { configDefaults } from 'vitest/config' import * as path from 'path' import react from '@vitejs/plugin-react' import viteTsconfigPaths from 'vite-tsconfig-paths' import svgrPlugin from 'vite-plugin-svgr' export default defineConfig({ base: '/', server: { open: true, port: 3000, // 添加请求重写中间件 configureServer(server) { server.middlewares.use((req, res, next) => { // 拦截/assets开头的请求,排除项目自身src/assets的资源 if (req.url?.startsWith('/assets/') && !req.url.startsWith('/src/assets/')) { req.url = `/node_modules/component-library/dist${req.url}`; } next(); }); }, }, plugins: [ react(), viteTsconfigPaths(), svgrPlugin({ svgrOptions: { svgProps: { role: 'img' }, titleProp: true, descProp: true, }, }), ], resolve: { alias: [{ find: '^@/', replacement: path.resolve(__dirname, 'src/') }], }, test: { globals: true, environment: 'jsdom', setupFiles: './test-setup.ts', coverage: { reporter: ['text', 'html'], exclude: ['./node_modules/', './test-setup.ts', './dist/', './build/'], }, exclude: [...configDefaults.exclude, 'build', 'ssl', 'coverage'], include: ['./src/**/*.{test,spec}.{ts,tsx}'], }, })
方案二:资源路径别名映射
通过resolve.alias将资源请求路径直接映射到组件库的资源目录:
resolve: { alias: [ { find: '^@/', replacement: path.resolve(__dirname, 'src/') }, { find: '/assets', replacement: path.resolve(__dirname, 'node_modules/component-library/dist/assets') } ], },
说明
- 之前尝试的
optimizeDeps主要用于预构建CommonJS模块为ES模块,不处理资源路径映射,因此无法解决该问题; - 方案一仅作用于开发服务器,不会影响生产构建的资源处理逻辑,更推荐使用。
内容的提问来源于stack exchange,提问作者hjaraba
相关产品推荐
相关产品推荐

