fix: typescript lib path resolution for api-extractor in monorepo #360
+36
−14
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
该 PR 修复 Monorepo 项目中 vite-plugin-dts 对 TypeScript 依赖库路径获取的问题。
问题描述
Monorepo 项目的 Workspace Root 安装 TS 版本为
v5.5.4
,在子项目中 vite-plugin-dts 没有正确获取 Workspace Root 的 TS(通过 debug 观察 libFolder 变量值为undefined
),而它使用了api-extractor
内置的 TSv5.4.2
版本,如图:可能相关的 ISSUE:#266
问题触发条件
Monorepo 项目,如果
<WorkspaceRoot>/node_modules/typescript
存在,但子项目<WorkspaceRoot>/packages/xxx/node_modules/typescript
不存在。复现步骤
pnpm add -D --workspace-root typescript
)pnpm -F vite-project build
)复现代码
https://github.com/qwqcode/vite-plugin-dts-mre
clone 后给 node_modules 中的相关代码打上断点,通过 VSCode JS 调试终端执行
pnpm build
旧版实现
生成 dts 文件调用
@microsoft/api-extractor
的Extractor.invoke
方法会传递 typescriptCompilerFolder 参数,指定 TypeScript 库的路径:vite-plugin-dts/src/rollup.ts
Line 92 in f5d9c06
为了让
api-extractor
工具中调用的 TS 和用户开发环境的 TS 版本一致,需正确设置 typescriptCompilerFolder 参数。如果为
undefined
则会默认使用api-extractor
自带的 TS,与开发环境 TS 版本可能不符,从而导致问题。目前旧版在 Monorepo 项目下libFolder
变量可能为undefined
。TS 库路径变量
libFolder
是通过字符串拼接得到的:vite-plugin-dts/src/plugin.ts
Lines 657 to 670 in f5d9c06
新版实现
修改为通过调用 Node 的 API
require.resolve('typescript')
获取编译时用户当前项目中安装的 TS 路径。兼容性方面,为了同时兼容 ES Modules 和 CommonJS,使用
createRequire(import.meta.url)
获取 require 对象并调用 resolve 方法 1。为了保险起见,仍然通过 try catch 提供了 fallback 的解决方案,保留旧版的字符串拼接代码。
性能方面,
libFolder
通过require.resolve
只需在编译过程中获取一次。已测试 TS 路径在 Monorepo 项目中也能正确获取:
其他可能的改进:通过更新日志发现 3.0.0-beta.2 版本将
libFolderPath
参数移除,目前rollupTypes
功能不支持自定义 TS 库路径,可以考虑增加一个参数。Footnotes
参考:https://stackoverflow.com/questions/54977743/do-require-resolve-for-es-modules ↩