使用捆绑器的解决方案:
您的场景似乎是捆绑器的一个很好的用例。这是一个分析您的代码并提取所有依赖项以生成单个输出文件的工具。流行的选择是webpack、browserify 和parcel。
这意味着从 A 导入的依赖项将包含在为您的公共脚本生成的输出文件中。
Parcel 具有“零配置”理念,这意味着(与 webpack 或 browserify 非常不同)它无需设置即可工作。
我重新创建了您的代码:
我已经全局安装了包裹 (npm install -g parcel),所以我可以运行:
parcel build src/to_public/*
这会查看您的 to_public 文件夹并将所有脚本捆绑在其中。 Parcel 知道 typescript 并自动调用 typescript 编译器。生成的脚本将复制到新的dist/ 目录。您的文件夹现在如下所示:
对于您的 to_public 文件夹之外的文件,您需要 typescript 的完全支持,但您不需要编译它们。为此,您可以将 noEmit 标志添加到您的 compilerOptions。
{
"compilerOptions": {
"module": "commonjs",
"noEmit": true
},
"exclude": [
"node_modules"
]
}
Parcel 有一些非常好的功能。例如,它会缓存编译,如果您重复调用它,它会非常快。此外,它还可以与 Javascript 生态系统中的其他工具很好地交互。与 typescript 编译器的互操作是无缝的。 Parcel 将使用您在 tsconfig 中的设置,甚至默认生成源地图。
当然,也可以为替代方案提供强有力的案例。我在这里推荐包裹,因为它基本上是零成本的。您只需安装软件包,无需任何配置,它就可以正常工作。
没有捆绑器的解决方案:
如果您想避免使用捆绑程序,您可以使用多个编译器配置。问题是打字稿需要了解您正在使用的接口。它可以通过查看源代码或读取定义文件来做到这一点。因此,您的答案是一个可行的解决方案,但如果定义是自动创建的,那就太好了。我已经设置了三个编译器配置:
- 用于一般语法检查
- 生成定义文件
- 编译公共javascript
默认配置是这个,它将由您的编辑器选择。我已将noEmit 设置为true,以避免意外编译会弄乱您的文件夹结构。
tsconfig.json
{
"compilerOptions": {
"module": "commonjs",
"noEmit": true,
"rootDir": "src"
}
}
然后我将您的源目录拆分为src/server 和src/to_public。如果没有这种拆分,就很难从编译器中排除文件(您必须手动列出它们)。
这是生成声明文件的配置。它有标志 emitDeclarationOnly ,输出目录是你的公共 javascript 文件夹:
definitions.json
{
"compilerOptions": {
"module": "commonjs",
"declaration": true,
"emitDeclarationOnly": true,
"noResolve": true,
"rootDir": "src",
"outDir": "src/to_public"
}
}
如果您运行上述配置,它将从您的服务器端代码生成声明。这可用于最后的编译器配置。它读取您的 to_public 文件夹中的文件并将它们编译到输出目录。这里重要的编译器标志是noResolve,这样可以避免将声明文件复制到输出文件夹。
public_scripts.json
{
"compilerOptions": {
"module": "commonjs",
"noResolve": true,
"rootDir": "src/to_public",
"outDir":"public/"
},
"exclude": ["src/server"]
}
你现在可以编译你的代码了
tsc -p definitions.json
tsc -p public_scripts.json
请注意导入路径。如果你想在to_public/file.ts中使用server/A.ts,那么你导入"./server/A.ts"