Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: ensure rollupTypes work if vite emptyOutDir is false #291

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

qwqcode
Copy link

@qwqcode qwqcode commented Dec 27, 2023

问题描述

当 vite 配置为 emptyOutDir: false (即构建前不清空 dist 目录)。vite-plugin-dts 开启 rollupTypes 模式可能会生成错误的 d.ts 内容。

代码修改

在生成 my-lib.d.ts 前,清除 dist 目录下的相关 d.ts 文件。

问题复现

当 vite 配置 emptyOutDirfalse 时,执行一次 build 后,第二次 build 前不会清空目录。

步骤1. vite-plugin-dts 在 dist 目录生成包含 export * from '${fromPath}'my-lib.d.ts

代码逻辑目前是:文件如果已存在,my-lib.d.ts 不会再被写入

for (const name of entryNames) {
const path = multiple
? cleanPath(resolve(outDir, `${name.replace(tsRE, '')}.d.ts`))
: typesPath
if (existsSync(path)) continue
const index = cleanPath(
resolve(outDir, relative(entryRoot, `${entries[name].replace(tsRE, '')}.d.ts`))
)
let fromPath = normalizePath(relative(dirname(path), index))
fromPath = fromPath.replace(dtsRE, '')
fromPath = fullRelativeRE.test(fromPath) ? fromPath : `./${fromPath}`
let content = `export * from '${fromPath}'\n`
if (existsSync(index) && hasExportDefault(await readFile(index, 'utf-8'))) {
content += `import ${libName} from '${fromPath}'\nexport default ${libName}\n`
}
await writeOutput(cleanPath(path), content, outDir)
}

步骤2. 当 rollupTypestrue 时,会继续接下来的步骤 —— 使用 @microsoft/api-extractor 提取出 rollupTypes。

但由于 my-lib.d.ts 是上次 build 已经生成的文件(并且没有被 步骤1 写入预期内容),上次构建的 my-lib.d.ts 会作为输入值,继续传给 @microsoft/api-extractor 去解析,导致最后得到错误的 rollupTypes 结果。

rollupDeclarationFiles({
root,
configPath,
compilerOptions: rawCompilerOptions,
outDir,
entryPath: typesPath,
fileName: basename(typesPath),
libFolder,
rollupConfig,
rollupOptions
})

复现代码

https://github.com/qwqcode/vite-dts-test

image

其他可能的修改

在构建时仅对 dist 目录进行写的操作(不再多次对 dist 进行读写的 IO 操作)。

如果 rollupTypes 开启,目前 dist/** 会被 @microsoft/api-extractor 读取,然后写入,以及删除 dist/src 目录。

可以创建一个临时目录,例如 node_modules/.vite,然后 @microsoft/api-extractor 不再去读 dist 目录,而是读这个临时目录里面的 ts 文件。然后构建的文件拷贝到 dist 里面一步到位

@qmhc
Copy link
Owner

qmhc commented Dec 28, 2023

直接删除已存在的同名文件并不可取,因为如果这个有可能是用户本身就存在的文件,举例:

要插入的入口:dist/index.d.ts,用户有一个源文件 src/index.ts,此时未 rollup 前的产物已包含 dist/index.d.ts,而正确的处理应该直接使用这个产物而不是覆盖它。

可以创建一个临时目录,例如 node_modules/.vite,然后 @microsoft/api-extractor 不再去读 dist 目录

我认为这个方案是可行的,如果开启了 rollupTypes 则在 node_modules/.dts 的临时目录下生产文件并 rollup,再将产物移动到目标位置、并清空临时目录。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants