我们的项目使用React / Typescript和Nx以及WebPack和Babel。我们的monorepo包含几十个应用程序。作为我们i18 n计划的一部分,我正在开发一个git钩子,它将扫描每个应用程序目录并创建一个默认的libs/pages/xyz/src/i18n/translations/messages-en-US.json
文件,我们的翻译团队可以将其摄取到他们的定制系统中,以便为其他语言(如messages-fr-CA.json
)生成额外的文件。
我们的第一种方法是让Node脚本查找每个根应用程序消息文件(例如:libs/pages/xyz/src/i18n/messages.ts
),将其转换为ES 2022,将其写入临时文件,然后通过import(temp.js)
动态导入该文件,因此我们可以在将其写入默认libs/pages/xyz/src/i18n/translations/messages-en-US.json
之前对该JSON进行多次转换。
然而,我在尝试动态导入这些文件时遇到了“模块未找到”错误,因为每个messages.ts
文件都包含别名导入路径...
(ex:messages.ts从common/foo/xyz
导入,但在我们的tsconfig.json路径中,它将Map到project-root/libs/shared/common/foo/src/xyz.ts
。
当使用ts.transpileModule(filePath, compilerOptions).outputText
时,传输代码工作正常,但当我尝试const module = await import(compiledJSFilePath)
时,我得到了模块解析错误,因为当动态导入带有别名导入的单个文件时,不使用在我的tsConfig.json
中定义的别名路径...
// my-app/src/i18n/messages.ts
import fooMessages from 'Common/foo/messages';
import barMessages from 'Common/bar/messages';
... other required imports ...
export default {
...fooMessages,
...barMessages,
... other message files ...
}
// extract-messages.mjs
...
import * as fsp from 'node:fs/promises';
import ts from 'typescript';
...
tsContent = await fsp.readFile(targetAppRootMessageFile, { encoding: 'utf8' });
jsContent = ts.transpileModule(tsContent, compilerOptions).outputText;
await fsp.writeFile(tempOutputFile, jsContent);
const { default: messages } = await import(tempOutputFile);
... do transformations here ...
await fsp.writeFile(defaulti18nEnUSFile, JSON.stringify(transformedMessages, null, 2));
... delete temp file ...
... iterate to next application ...
字符串
我不是一个NodeJS / Typescript编译器大师,所以任何建议或指导都将不胜感激。
1条答案
按热度按时间umuewwlo1#
tsconfig.json
中的paths
别名仅适用于tsc
编译器的类型,而不适用于实际发出的JS代码:请注意,此功能不会更改
tsc
发出的导入路径,因此paths
只应用于通知TypeScript另一个工具具有此Map,并将在运行时或捆绑时使用它。我猜你的项目有一个特定的webpack路径别名配置,而
tsconfig
只是复制了这些,如上面引用的那样。现在,IIUC,您正在编写一个新的工具脚本,它也将导入您编译的TS文件。因此,您需要在JS端再次实现路径别名。你可以例如使用
tsconfig-paths
库:使用此选项加载其位置在
tsconfig.json
的paths
部分中指定的模块然后在执行新脚本时,启用tsconfig-paths,以便它根据tsconfig调整节点模块分辨率:
字符串