
本文介绍在 Rollup(或基于 Rollup 的构建工具如 Vite)中,如何可靠获取经构建处理后的资源最终路径(例如 module-abc123.js),解决无法通过 import.meta.url 或动态 new URL() 获取真实生产 URL 的问题。
本文介绍在 rollup(或基于 rollup 的构建工具如 vite)中,如何可靠获取经构建处理后的资源最终路径(例如 `module-abc123.js`),解决无法通过 `import.meta.url` 或动态 `new url()` 获取真实生产 url 的问题。
在 Rollup 构建流程中,源码中的相对导入路径(如 ./src/module.js)会被重写为带内容哈希的生产路径(如 /assets/js/module-9f8e7d6c.js),但该重写仅发生在打包阶段,运行时无法直接调用类似 rollupResolve() 的 API——Rollup 本身不提供运行时路径解析能力,也无内置 resolve 方法供 JS 代码调用。
✅ 正确方案:生成构建产物清单(Manifest)
最可靠、标准且广泛采用的方式是:在构建阶段生成一份输出清单(manifest),记录源路径与最终产物路径的映射关系。该 manifest 可被应用代码在运行时读取并查表,从而获得任意模块的正式部署 URL。
推荐使用 rollup-plugin-output-manifest 插件(兼容 Vite —— Vite 4+ 内置了类似能力,可通过 build.manifest: true 启用):
✅ Vite 示例(推荐,开箱即用)
// vite.config.ts
export default defineConfig({
build: {
manifest: true, // ✅ 自动生成 .vite/manifest.json
rollupOptions: {
output: {
assetFileNames: 'assets/[name]-[hash][extname]',
chunkFileNames: 'assets/[name]-[hash].js',
entryFileNames: 'assets/[name]-[hash].js'
}
}
}
})
构建后将生成 manifest.json,结构如下:
{
"src/module.js": {
"file": "assets/module-9f8e7d6c.js",
"css": [],
"imports": []
}
}
运行时读取(注意:需确保 manifest 文件被静态托管):
// utils/getModuleUrl.ts
export async function getModuleUrl(sourcePath: string): Promise<string> {
const manifest = await fetch('/manifest.json').then(r => r.json());
const entry = manifest[sourcePath];
if (!entry?.file) throw new Error(`No built asset found for ${sourcePath}`);
return '/'+ entry.file; // 拼接为完整 URL
}
// 使用示例
getModuleUrl('./src/module.js').then(url => {
doSomethingWithUrl(url); // → '/assets/module-9f8e7d6c.js'
});</string>
✅ 纯 Rollup 配置(如未使用 Vite)
// rollup.config.js
import manifest from 'rollup-plugin-output-manifest';
export default {
plugins: [
manifest({
fileName: 'manifest.json',
publicPath: '/' // 与实际部署路径一致
})
]
};
⚠️ 注意事项与替代思路
- new URL('./src/module.js', import.meta.url).href 不可靠:它依赖浏览器对模块的解析逻辑,在 Vite 开发模式下指向原始源码,在生产模式下可能内联小文件(如 无法保证与 Rollup 最终产物一致。
- 避免硬编码路径:手动拼接哈希路径违反构建确定性,且易出错。
- 优化建议:若对网络请求敏感,可将 manifest 内联为全局变量(如通过 injectManifest 插件注入 window.__MANIFEST__),避免额外请求。
- Vite 用户注意:build.manifest: true 仅在 build 模式生效,开发环境无 manifest;需做好降级处理(如 fallback 到 import.meta.url 仅用于 dev)。
综上,构建时生成 manifest + 运行时查表 是当前生态下最健壮、可维护的解决方案,既符合 Rollup/Vite 的设计哲学,也具备良好的可扩展性与调试友好性。











