如何在Nx/Vite的manifest.json中配置base/baseHref添加CDN前缀
问题原因
Vite 配置项 base 的默认作用范围是构建后HTML中注入的资源引用、运行时公开资源路径解析、客户端路由基路径,不会自动改写manifest.json内存储的资源路径。Vite 生成的manifest默认只会记录资源相对于构建输出目录(默认是dist)的相对路径,这是框架的默认设计,不属于配置错误。
实现方案
方法1:自定义Vite插件构建时自动改写manifest
该方案全Vite版本通用,不需要改动业务逻辑,只需要在配置中新增一个轻量插件,构建完成后自动读取manifest文件,给对应资源字段拼接CDN前缀后写回,配置示例如下:
import { defineConfig } from 'vite' import fs from 'node:fs' import path from 'node:path' // 给manifest资源添加CDN前缀的插件 const manifestCdnPlugin = (cdnPrefix) => ({ name: 'manifest-cdn-prefix', apply: 'build', closeBundle() { const manifestPath = path.resolve(this.config.build.outDir, 'manifest.json') const manifest = JSON.parse(fs.readFileSync(manifestPath, 'utf-8')) Object.values(manifest).forEach(entry => { // 处理主文件路径 if (entry.file) entry.file = cdnPrefix + entry.file // 处理关联CSS路径 if (Array.isArray(entry.css)) { entry.css = entry.css.map(p => cdnPrefix + p) } // 处理关联静态资源路径 if (Array.isArray(entry.assets)) { entry.assets = entry.assets.map(p => cdnPrefix + p) } // 注意:dynamicImports字段存储的是其他chunk的键名,不是文件路径,不需要修改 }) fs.writeFileSync(manifestPath, JSON.stringify(manifest, null, 2)) } }) export default defineConfig({ base: 'https://my-cdn.com/', plugins: [ // 传入CDN前缀,注意末尾必须带斜杠/ manifestCdnPlugin('https://my-cdn.com/') ], build: { manifest: true, rollupOptions: { input: '/path/to/main.js' } } })
注意事项:
- 传入插件的CDN地址末尾必须携带斜杠
/,避免拼接出格式错误的资源路径 - 插件会自动读取你配置的
build.outDir路径,自定义输出目录时不需要额外修改插件逻辑 - 如果manifest中存在其他自定义资源字段需要拼接前缀,直接在遍历逻辑中添加对应字段的处理即可,即使使用了多页面、legacy兼容等生成多chunk的场景,插件也能自动覆盖所有条目
方法2:服务端读取manifest时动态拼接前缀
如果不需要修改构建产物,可以在服务端读取manifest、渲染页面引用资源的时候,手动拼接CDN前缀,这种方式更灵活,切换CDN地址时不需要重新构建:
// 服务端逻辑示例 import fs from 'node:fs' const manifest = JSON.parse(fs.readFileSync('dist/manifest.json', 'utf-8')) const CDN_BASE = 'https://my-cdn.com/' const mainEntry = manifest['main.js'] // 拼接得到带CDN前缀的资源地址 const jsPath = CDN_BASE + mainEntry.file const cssPaths = mainEntry.css.map(p => CDN_BASE + p) const assetPaths = mainEntry.assets.map(p => CDN_BASE + p)
内容的提问来源于stack exchange,提问作者widan35174
相关产品推荐
相关产品推荐

