TypeScript项目的目录结构

47

对于TypeScript项目,什么是惯用的目录结构?

我希望这样的目录结构包括以下功能:

  1. 将TypeScript源代码和转译后的JavaScript分开放置在不同的目录中
  2. 将项目源代码和测试代码放置在不同的目录中
  3. 解决跨测试和源代码引用的机制。
4个回答

19

将生成的JS与源TS分离

我建议生成单个文件输出。无论是面向浏览器还是Node,这都是一个更好的选择。请记住,大多数IDE可以隐藏.gitignore文件,因此即使您让.js文件坐在它们的.ts文件旁边,也不应该成为问题。

从技术上讲,你可以使用--outDir通过适当设置tsconfig.json来输出想要的方式。

将测试与源代码分离

这相当简单!只需维护一个/tests目录。导入所需的只是简单的目录遍历,例如:import {MyClass} from "../src/modules/my-class"(其中../是为了从/tests目录中跳出)。

解决引用的机制

这在浏览器中比在Node上更具挑战性——后者对于TypeScript而言已经有了可用的require

在浏览器上

强烈建议你使用类似webpack之类的工具,但如果你坚持要冒险,这里有一个适用于浏览器的require,我用它来快速迭代TypeScript代码而无需设置构建流程。

浏览器上的require()

  • 不适合弱心者——这将是你累积下来的技术债务

由于绝对路径对于网页导入是必要的,因此在这里,我演示如何在TypeScript中使用我的require()方法(通常用于快速调试会话而无需重新构建)。

/entities/user.ts

import {Username} from "../entities/username";
import {Password} from "../entities/password";

export class User {
    username: Username;
    password: Password;
}

UsernamePassword是在/entities/username.ts/entities/password.ts中导出的类。尽管../entities/看起来多余,但请注意,这对于浏览器具有适当的实体路径是至关重要的。 :)


感谢您的输入。您的帖子让我找到了解决方案。 - codematix
1
我现在正在2020年重新审视这个问题。如果有人能提醒我为什么我那么确定为Node生成单文件输出是一个好主意,我将不胜感激。 - Angad
@Angad 为节点生成单个文件是一个不好的想法吗?你能详细说明一下吗? - Jan Ciołek
1
@JanCiołek 嗯,我确实认为这绝不是一个坏主意!这实际上是一个动机的问题 - 到目前为止,在我的项目中,除了为浏览器 WebPacking 时,我没有动力生成单个文件输出。它显著地增加了调试的复杂性,因此,除非你需要它,否则我不建议使用它。 - Angad

7

看来我做错了。我尝试使用以下结构:

src
|---- lib
|-----|---- mymodule.ts
|---- tests
|-----|---- mymodule.tests.ts

然而,我试图将 lib 目录下的源代码与 tests 目录下的测试代码分开编译。
执行以下命令来编译源代码: find src/lib -name *.ts | xargs tsc --declaration --sourceMap --module commonjs --target es5 --listFiles --outDir lib 然后执行以下命令来编译测试代码: find src/tests -name *.ts | xargs tsc --declaration --sourceMap --module commonjs --target es5 --listFiles --outDir tests 这会导致 tests 文件夹中出现另一个 lib 子目录和一个 tests 子目录。这不是我想要的结果。
为了解决这个问题,我需要将它们一起编译,所以现在我的命令是: find src -name *.ts | xargs tsc --declaration --sourceMap --module commonjs --target es5 --listFiles --outDir . 感谢大家的帮助。

谢谢。我现在已经按照同样的方式结构化了我的项目,将tsconfig.json放置在src文件夹中,只需运行“tsc -p ./src”即可编译所有内容。 - Randy Burden
提醒一下,使用正确的工具(如Atom上的“Atom TypeScript”)自动创建tsconfig.json非常简单。如果您还没有尝试过,请强烈建议您去了解一下 - 因为构建过程而选择特定目录结构听起来像是可读性债务的开始 :) - Angad

3
很难给出具体建议,因为这在很大程度上取决于项目规模、工具和平台等因素。
1. TypeScript编译器有一个--outDir选项,可以用来输出到单独的目录。但是,你可能更喜欢打包,所以将输出到单个文件可能更可取,只要你也创建了调试所需的映射文件map。你可以使用例如Gulp之类的工具非常好地构建所有这些内容。 2. 这与目录结构有什么关系?如果你想分割它,那就分割它。 3. “机制”非常广泛,并且取决于你使用的工具。例如,测试运行器可以在测试代码之前“导入”生产代码。你还可以使用一些模块加载库,等等。

0
这对我来说是一个不断发展的事情,但对于Node项目,我正在设置一个/src和/dist目录,使用tsconfig的outDir来指向dist目录。
/root
  |__dist/
  |__src/
  |____lib/
  |____etc...

对于绝对路径,我在package.json中使用"imports"。
"imports": {
    "#src/*": "./dist/*",
    "#lib/*": "./dist/lib/*",
    "#root/*": "./*"
  },

记住,当它进行转译时,它不会触及导入语句,这意味着你需要从创建的js代码的角度来编写它们。对我来说,在开发时,从src/的角度编写导入语句更合乎逻辑,这就是为什么你看到有一个src/映射到dist/的原因。
个人而言,我将package.json的类型设置为模块,以便使用更现代的导入/导出方式(尽管我知道它可以转译为commonJS风格的require模块),并且我针对最新的ES版本进行目标设置 - 原因是如果只是后端代码,我对与旧的node版本的向后兼容性不太关心。
有一件有点烦人的事情是,如果你使用--watch标志,dist文件夹没有任何内置的清理解决方案,但是个人而言,我只是设置了nodemon来监视src/目录,然后运行类似于以下的命令:
"scripts": {"dev-watch": "nodemon --watch src --ext \"*\" --exec \"tsc && node dist/app.js\""}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接