Rollup监听/构建滞后一次变更问题排查求助
问题分析与解决方案
核心问题定位
你遇到的首次保存不更新、二次保存才生效的问题,主要源于配置路径不匹配、多构建任务依赖顺序混乱、TS配置与Rollup插件冲突这三个关键点,再加上Monorepo场景下的监听叠加干扰,最终导致了实时构建的异常。
具体问题拆解
- 声明文件路径完全错误:tsconfig中
declarationDir设为types(项目根目录下的文件夹),但第二个Rollup任务却试图读取dist/esm/types/index.d.ts,第一次构建时该文件根本不存在,只有二次保存后旧的声明文件被错误生成,才让d.ts任务执行成功。 - TS配置与Rollup插件功能冲突:
emitDeclarationOnly: true会让tsc只生成.d.ts文件,不输出JS代码,导致@rollup/plugin-typescript无法完成JS编译工作,实际代码更新的流程被打断。 - 多Rollup任务无执行顺序保障:两个构建任务并行执行,d.ts任务依赖TS编译结果,但Rollup watch模式下不会自动处理任务间的依赖关系,第一次变更时d.ts任务因找不到最新文件直接跳过,二次保存才补上。
- Monorepo监听叠加干扰:Lerna的watch与Rollup的watch同时运行时,会出现重复触发、文件变更检测延迟的问题。
修复方案
1. 修正TS配置,统一文件输出路径
修改tsconfig.json,让声明文件和JS代码都输出到dist目录,同时关闭emitDeclarationOnly,让Rollup插件完整处理编译流程:
{ "compilerOptions": { // 保留原有默认配置 "target": "es5", "esModuleInterop": true, "forceConsistentCasingInFileNames": true, "strict": true, "skipLibCheck": true, // 修改以下配置 "jsx": "react", "module": "ESNext", "declaration": true, "declarationDir": "./dist/types", // 声明文件输出到dist下的types目录 "sourceMap": true, "outDir": "./dist", "moduleResolution": "node", "allowSyntheticDefaultImports": true, "emitDeclarationOnly": false // 关闭,让tsc同时生成JS和声明文件 } }
2. 调整Rollup配置,修复任务依赖与路径
让d.ts任务直接从源码生成,不再依赖dist目录的中间文件,同时确保任务间的逻辑独立:
import packageJson from './package.json' assert { type: 'json' }; import del from '@rollup/plugin-delete'; // 先安装:npm i -D @rollup/plugin-delete export default [ { input: "src/index.ts", output: [ { file: packageJson.main, format: "cjs", sourcemap: true, }, { file: packageJson.module, format: "esm", sourcemap: true, }, ], plugins: [ del({ targets: 'dist/*' }), // 构建前清除旧dist文件,避免缓存干扰 resolve(), commonjs(), typescript({ tsconfig: "./tsconfig.json", declaration: true, declarationDir: "./dist/types" }), ], external: ["react", "react-dom"] }, { input: "src/index.ts", // 直接从源码生成d.ts,无需依赖中间文件 output: [{ file: "dist/index.d.ts", format: "esm" }], plugins: [dts({ tsconfig: "./tsconfig.json", respectExternal: true // 排除react等外部依赖的类型 })], external: ["react", "react-dom"] } ];
3. 优化Monorepo监听流程
避免同时使用Lerna watch和Rollup watch,直接在包的package.json中配置dev脚本:
{ "scripts": { "dev": "rollup -c -w" } }
然后通过Lerna启动单个包的监听:
lerna run dev --scope=your-component-package-name
或并行启动多个包:
lerna run dev --parallel
替代工具推荐
如果Rollup的配置问题依然难以解决,可以尝试以下更适配Monorepo场景的工具:
- Vite:对TS、React和Monorepo的支持开箱即用,热更新速度快,配置极简,适合组件库的开发与构建。
- tsup:基于Rollup的封装工具,内置TS、React支持,监听模式稳定,无需复杂配置即可完成组件库的实时构建。
内容的提问来源于stack exchange,提问作者Jordy van der Tang
相关产品推荐
相关产品推荐

