fix: ensure `rollupTypes` work if vite `emptyOutDir` is `false`
问题描述
当 vite 配置为 emptyOutDir: false (即构建前不清空 dist 目录)。vite-plugin-dts 开启 rollupTypes 模式可能会生成错误的 d.ts 内容。
代码修改
在生成 my-lib.d.ts 前,清除 dist 目录下的相关 d.ts 文件。
问题复现
当 vite 配置 emptyOutDir 为 false 时,执行一次 build 后,第二次 build 前不会清空目录。
步骤1. vite-plugin-dts 在 dist 目录生成包含 export * from '${fromPath}' 的 my-lib.d.ts,
代码逻辑目前是:文件如果已存在,my-lib.d.ts 不会再被写入
https://github.com/qmhc/vite-plugin-dts/blob/9262d012a8f57e2eca5a51b66ca7790b1cc5195a/src/plugin.ts#L603-L626
步骤2. 当 rollupTypes 为 true 时,会继续接下来的步骤 —— 使用 @microsoft/api-extractor 提取出 rollupTypes。
但由于 my-lib.d.ts 是上次 build 已经生成的文件(并且没有被 步骤1 写入预期内容),上次构建的 my-lib.d.ts 会作为输入值,继续传给 @microsoft/api-extractor 去解析,导致最后得到错误的 rollupTypes 结果。
https://github.com/qmhc/vite-plugin-dts/blob/9262d012a8f57e2eca5a51b66ca7790b1cc5195a/src/plugin.ts#L667-L677
复现代码
https://github.com/qwqcode/vite-dts-test
其他可能的修改
在构建时仅对 dist 目录进行写的操作(不再多次对 dist 进行读写的 IO 操作)。
如果 rollupTypes 开启,目前 dist/** 会被 @microsoft/api-extractor 读取,然后写入,以及删除 dist/src 目录。
可以创建一个临时目录,例如 node_modules/.vite,然后 @microsoft/api-extractor 不再去读 dist 目录,而是读这个临时目录里面的 ts 文件。然后构建的文件拷贝到 dist 里面一步到位
直接删除已存在的同名文件并不可取,因为如果这个有可能是用户本身就存在的文件,举例:
要插入的入口:dist/index.d.ts,用户有一个源文件 src/index.ts,此时未 rollup 前的产物已包含 dist/index.d.ts,而正确的处理应该直接使用这个产物而不是覆盖它。
可以创建一个临时目录,例如 node_modules/.vite,然后 @microsoft/api-extractor 不再去读 dist 目录
我认为这个方案是可行的,如果开启了 rollupTypes 则在 node_modules/.dts 的临时目录下生产文件并 rollup,再将产物移动到目标位置、并清空临时目录。