node.js - 编译另一个没有所有引用的打字稿输出目录
问题描述
我在 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) }
所需结构:
- 源代码
- A.ts
- to_public
- 文件.ts
- 上市
- 文件.js
我tsconfig.json
有
"compilerOptions": {
...
"outDir": "../../public/js/",
}
"include": [
"../../src/public_ts"
],
当 file.ts 没有引用任何东西时,这很完美。
但是当我从 中引用任何内容时src
,会复制整个文件夹结构。这是实际结果:
- 源代码
- A.ts
- to_public
- 文件.ts
- 上市
- A.js <--不需要
- to_public <--最好没有
- 文件.js
虽然编译后file.js
没有引用任何东西,我可以按原样使用它,但我不希望我的整个 src 项目被复制到public
.
有什么建议吗?谢谢
解决方案
使用捆绑器的解决方案:
您的场景似乎是捆绑器的一个很好的用例。这是一个分析您的代码并提取所有依赖项以生成单个输出文件的工具。流行的选择是webpack、browserify和parcel。这意味着从 A 导入的依赖项将包含在为您的公共脚本生成的输出文件中。
Parcel 具有“零配置”理念,这意味着(与 webpack 或 browserify 非常不同)它无需设置即可工作。
我重新创建了您的代码:
- 源代码
- A.ts
- to_public
- 文件1.ts
- 文件2.ts
我已经全局安装了包裹(npm install -g parcel
),所以我可以运行:
parcel build src/to_public/*
这会查看您的to_public
文件夹并将所有脚本捆绑在其中。Parcel 知道 typescript 并自动调用 typescript 编译器。生成的脚本被复制到一个新dist/
目录。您的文件夹现在如下所示:
- 源代码
- //...
- 距离
- 文件1.js
- 文件2.js
对于您的 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
请注意导入路径。如果你想使用server/A.ts
in to_public/file.ts
,那么你导入"./server/A.ts"
推荐阅读
- python - 如何使用 pscp 将在 python 脚本中创建的文件复制到需要密码的远程服务器?
- c# - 无法从模型中引用 asp:HIddenField
- python - 如何比较 python/pandas 中 2 个 csv 文件(csv1 和 csv2)列中的所有条目?
- ag-grid - ag-grid angular上组标题的单击事件
- c# - 如何从文件夹中压缩文件但保持分开
- python - 无法更改 KMeansClustering Tensorflow 中的集群数量
- java - 为什么我不能在 Java.net 中使用任何端口?
- flutter - 列表视图构建器项的动态高度
- python - 显示每个条形堆栈的所有数据标签的总和
- swift - 无法转换“URL”类型的值?到预期的参数类型“数据”