为何我的TypeScript模块映射指向src而非dist?
解决React组件库引入后Source Map指向不存在src目录的警告问题
现象
将自制React组件库引入其他项目时,控制台抛出如下警告:
WARNING in ./node_modules/[package]/dist/esm/index.js
Module Warning (from ./node_modules/source-map-loader/dist/cjs.js):
Failed to parse source map from '[app dir]\node_modules[package]\src\components\PieChart\PieChart.component.tsx' file: Error: ENOENT: no such file or directory, open '[app dir]\node_modules[package]\src\components\PieChart\PieChart.component.tsx'
组件库已正确生成dist目录,但Source Map文件指向了未发布到npm的src目录,导致宿主项目的source-map-loader无法找到源文件。
当前配置文件
tsconfig.json
{ "compilerOptions": { "target": "ESNext", "jsx": "react-jsx", "rootDir": "./", "moduleResolution": "node", "allowJs": false, "maxNodeModuleJsDepth": 1, "declaration": true, "emitDeclarationOnly": true, "sourceMap": true, "outDir": "dist", "declarationDir": "types", "esModuleInterop": true, "forceConsistentCasingInFileNames": true, "strict": true, "noUnusedLocals": true, "noUnusedParameters": true, "noImplicitReturns": true, "noFallthroughCasesInSwitch": true, "noUncheckedIndexedAccess": true, "allowUnreachableCode": false, "skipLibCheck": true, } }
rollup.config.mjs
import resolve from "@rollup/plugin-node-resolve"; import commonjs from "@rollup/plugin-commonjs"; import typescript from "@rollup/plugin-typescript"; import dts from "rollup-plugin-dts"; import packageJson from "./package.json" assert { type: "json" }; export default [ { preserveModules: true, input: "src/index.ts", output: [ { dir: "dist/esm/", format: "esm", sourcemap: true, } ], plugins: [ resolve(), commonjs(), typescript({ tsconfig: "./tsconfig.json", compilerOptions: { outDir: "dist/esm/", declarationDir: "dist/esm/types" } }), ], }, { input: "dist/esm/types/index.d.ts", output: [{ file: "dist/index.d.ts", format: "esm" }], plugins: [dts()], }, ];
rollup.config.cjs
import resolve from "@rollup/plugin-node-resolve"; import commonjs from "@rollup/plugin-commonjs"; import typescript from "@rollup/plugin-typescript"; import dts from "rollup-plugin-dts"; import packageJson from "./package.json" assert { type: "json" }; export default [ { preserveModules: true, input: "src/index.ts", output: [ { dir: "dist/cjs/", format: "cjs", sourcemap: true, } ], plugins: [ resolve(), commonjs(), typescript({ tsconfig: "./tsconfig.json", compilerOptions: { outDir: "dist/cjs/", declarationDir: "dist/cjs/types" } }), ], }, { input: "dist/esm/types/index.d.ts", output: [{ file: "dist/index.d.ts", format: "esm" }], plugins: [dts()], }, ];
原因分析
该问题由TypeScript与Rollup配置共同导致:
- TypeScript配置缺陷:
rootDir设为./会让TS将项目根目录下所有文件视为源文件,生成的Source Map会包含基于根目录的路径;而组件库发布时不会包含src目录,导致宿主项目找不到对应文件。另外emitDeclarationOnly: true会让TS仅生成声明文件,干扰Rollup的完整编译流程。 - Rollup配置缺陷:启用
preserveModules: true后未正确配置Source Map路径转换,导致生成的Map文件依然指向原始src路径。
解决方案
1. 修正tsconfig.json
- 将
rootDir改为./src,限定TS仅处理源码目录,生成的Source Map路径会相对src目录而非项目根目录。 - 移除
emitDeclarationOnly: true,让Rollup的typescript插件能完整处理JS与声明文件的生成。
修改后的关键配置:
{ "compilerOptions": { // ...其他配置保留 "rootDir": "./src", "emitDeclarationOnly": false, // ...其他配置保留 } }
2. 修正Rollup配置(mjs和cjs文件均需调整)
- 在output中添加
sourcemapPathTransform,将源文件路径转换为相对路径,避免指向宿主项目的node_modules/src;或直接设置sourcemap: 'inline'嵌入Map内容。 - 在typescript插件中明确指定
rootDir并排除node_modules,确保编译范围正确。
修改后的rollup.config.mjs示例:
import resolve from "@rollup/plugin-node-resolve"; import commonjs from "@rollup/plugin-commonjs"; import typescript from "@rollup/plugin-typescript"; import dts from "rollup-plugin-dts"; import packageJson from "./package.json" assert { type: "json" }; export default [ { preserveModules: true, input: "src/index.ts", output: [ { dir: "dist/esm/", format: "esm", sourcemap: true, // 转换Source Map中的源路径为相对格式 sourcemapPathTransform: (relativeSourcePath) => { return `../src/${relativeSourcePath}`; } } ], plugins: [ resolve(), commonjs(), typescript({ tsconfig: "./tsconfig.json", compilerOptions: { outDir: "dist/esm/", declarationDir: "dist/esm/types", rootDir: "./src" }, exclude: ["node_modules/**"] }), ], }, { input: "dist/esm/types/index.d.ts", output: [{ file: "dist/index.d.ts", format: "esm" }], plugins: [dts()], }, ];
3. 配置package.json的files字段
确保发布到npm时仅包含编译后的dist目录,避免冗余文件:
{ "files": [ "dist" ] }
4. 可选:禁用生产环境Source Map
如果组件库不需要在生产环境提供Source Map,可以直接关闭该功能,彻底消除警告:
output: [ { dir: "dist/esm/", format: "esm", sourcemap: false } ]
内容的提问来源于stack exchange,提问作者Aradiel
相关产品推荐
相关产品推荐

