我在TS中有一个服务器项目,并且使用ts-node运行它。
我还有一个名为public
的文件夹,用于存放静态文件。
我需要的是一种在to_public
文件夹中写入.ts文件的方法,这样它们将通过服务器的接口进行类型检查,但输出为.js而不转换所有定义文件。
例如
// A.ts
export interface A { key: string }
// file.ts
import {A} from '../A.ts'
function f(a:A){ console.log(a.key) }
所需的结构:
我的tsconfig.json
有
"compilerOptions": {
...
"outDir": "../../public/js/",
}
"include": [
"../../src/public_ts"
],
当file.ts没有引用任何东西时,这很完美。
但是当我引用src
中的任何内容时,整个文件夹结构都会被复制。这是实际结果:
尽管编译后的file.js
没有引用任何内容,我可以按原样使用它,但我不希望将整个src项目复制到public
。
有什么建议吗?
答案 0 :(得分:1)
捆绑器解决方案:
您的方案对于捆绑器而言似乎是一个很好的用例。这是一个分析您的代码并提取所有依赖项以生成单个输出文件的工具。流行的选择是webpack,browserify和parcel。 这意味着从A导入的依赖项将包含在为您的公共脚本生成的输出文件中。
包裹具有“零配置”理念,这意味着(与webpack或browserify完全不同)它可以在不需要任何设置的情况下运行。
我重新创建了您的代码:
我已经在全球范围内安装了包裹(npm install -g parcel
),所以我可以运行:
parcel build src/to_public/*
这将查看您的to_public
文件夹,并将所有脚本捆绑在其中。 Parcel知道打字稿,并自动调用打字稿编译器。生成的脚本将复制到新的dist/
目录中。您的文件夹现在如下所示:
对于to_public文件夹之外的文件,您需要完全支持Typescript,但无需编译它们。为此,可以将noEmit
标志添加到您的editorOptions中。
{
"compilerOptions": {
"module": "commonjs",
"noEmit": true
},
"exclude": [
"node_modules"
]
}
包裹具有一些非常好的功能。例如,它缓存编译,并且如果您反复调用它会非常快。而且,它可以与Javascript生态系统中的其他工具很好地交互。与打字稿编译器的互操作是无缝的。 Parcel将使用tsconfig中的设置,甚至默认情况下还会生成源地图。
当然,也可以为其他选择提供充分的理由。我在这里推荐包裹,因为它基本上是零成本。您只需安装该软件包,无需任何配置,它就可以正常工作。
没有捆绑软件的解决方案:
如果要避免使用捆绑程序,则可以使用多个编译器配置。问题在于打字稿需要了解您正在使用的接口。它可以通过查看源代码或读取定义文件来实现。因此,您的答案是一个可行的解决方案,但是如果定义是自动创建的,那就更好了。我已经设置了三个编译器配置:
默认配置是此配置,它将由您的编辑器选择。我已将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
请注意导入路径。如果要在server/A.ts
中使用to_public/file.ts
,请导入"./server/A.ts"
答案 1 :(得分:1)
可能的解决方案 直到进一步的想法,这就是我想出的:
// to_public/definition.d.ts
export * from '../A.ts'
和
// to_public/file.ts
import {IA} from './definition'
function f(a:IA){ console.log(a.key) }