typescript - 在 Typescript 中防止不适当的导入和执行项目层次结构
问题描述
在 TS 项目中,我希望阻止以下内容:
- 从文件夹
common
导入的文件projectA
- 从文件夹
projectB
导入的文件projectA
我希望允许以下内容:
- 文件夹中的文件从文件夹
projectA
导入common
。
我知道参考资料。但是,据我了解,它们需要构建用于类型检查(如果进行了这种分离,则必须先构建以创建 d.ts 文件),我宁愿避免这种情况。
我有什么选择?是否可以简单地通过每个项目/文件夹的单独 tsconfig 文件来实现?
解决方案
TLDR;你真的应该只使用参考。这正是他们的目的。
但是,让我们首先解决您的一些具体想法:
是否可以简单地通过每个项目/文件夹的单独 tsconfig 文件来实现?
是的,但它不是很灵活。您可以通过将其设置为来隔离common。如果您尝试将projectA导入common ,则会出现错误。但是为了能够将common导入projectA,它必须更加全球化,但是这样您就可以导入projectB。
rootDir
.
'/path/to/projectA' is not under 'rootDir'
rootDir
不仅如此,根据项目参考文档:
以前,如果您使用单个 tsconfig 文件,则使用此结构相当尴尬:
- 实现文件可以导入测试文件
- 不可能在没有出现在输出文件夹名称中的情况下同时构建
test
,这可能是您不想要的src
src
- 仅更改实现文件中的内部结构需要再次对测试进行类型检查,即使这不会导致新的错误
- 仅更改测试需要再次对实现进行类型检查,即使没有任何更改
您可以使用多个 tsconfig 文件来解决其中一些问题,但会出现新问题:
- 没有内置的最新检查,所以你最终总是运行
tsc
两次 - 调用
tsc
两次会导致更多的启动时间开销 tsc -w
不能同时在多个配置文件上运行
我知道参考资料。但是,据我了解,它们需要构建用于类型检查(如果进行了这种分离,则必须先构建以创建 d.ts 文件),我宁愿避免这种情况。
这种厌恶的原因是什么?
如果这是构建新项目克隆的前期成本,那将远远超过改进的构建时间(参见下面的论点)。后者对开发人员生产力的好处将远远超过前者的成本。
具有讽刺意味的是,您对前期成本的关注越大,缩短构建时间所带来的好处就越大!
如果您希望能够在 VS Code 或 WebStorm 等类型和链接感知编辑器中导航新克隆而无需构建,您可以通过将
.d.ts
文件签入源代码控制来实现此目的。
这是文档具体说的:
由于依赖项目使用
.d.ts
从其依赖项构建的文件,因此您必须检查某些构建输出或在克隆项目后构建项目,然后才能在编辑器中导航项目而不会看到虚假错误。我们正在开发一个应该能够缓解这种情况的幕后 .d.ts 生成过程,但现在我们建议通知开发人员他们应该在克隆后构建。
项目参考的论据
从文档:
您可以大大缩短构建时间
期待已久的功能是 TypeScript 项目的智能增量构建。在 3.0 中,您可以将
--build
标志与tsc
. 这实际上是一个新的入口点,tsc
它的行为更像是一个构建协调器,而不是一个简单的编译器。运行
tsc --build
(tsc -b
简称)将执行以下操作:- 查找所有引用的项目
- 检测它们是否是最新的
- 以正确的顺序构建过时的项目
不必担心对您在命令行上传递的文件进行排序——
tsc
如果需要,将重新排序它们,以便始终首先构建依赖项。强制组件之间的逻辑分离
以新的更好的方式组织您的代码。
Project References文档中有一些更有用的好处/功能。
示例设置
src/tsconfig.json
即使您在根目录下没有代码,此 tsconfig 也可以是所有常用设置所在的位置(其他设置将从它继承),并且可以轻松
tsc --build src
构建整个项目(并--force
从头开始构建它)。{ "compilerOptions": { "rootDir": ".", "outDir": "../build", "composite": true }, // this root project has no source of its own "files": [], // but building this project will build all of the following: "references": [ { "path": "./common" } { "path": "./projectA" } { "path": "./projectB" } ] }
src/common/tsconfig.json
因为common没有引用,所以导入仅限于其目录中的目标和
npm_modules
. 我相信,你甚至可以通过赋予它自己的package.json
.{ "compilerOptions": { "rootDir": ".", "outDir": "../../build/common", "composite": true } }
src/projectA/tsconfig.json
由于声明了引用,projectA可以导入common 。
{ "compilerOptions": { "rootDir": ".", "outDir": "../../build/projectA", "composite": true }, "references": [ { "path": "../common" } ] }
src/projectB/tsconfig.json
由于声明了引用, projectB可以导入common AND projectA 。
{ "compilerOptions": { "rootDir": ".", "outDir": "../../build/projectB", "composite": true }, "references": [ { "path": "../common" } { "path": "../projectA" } ] }
构建
这些只是一些例子。tsc
我使用以下开关的缩写形式,例如,-b
而不是--build
. 从 repo 根目录执行的所有命令。
tsc -b src
- 构建整个树。
tsc -p src/projectA/
只编译 projectA。
tsc -b src/projectA/
构建 projectA 和任何过期的依赖项。
tsc -b -w src
- 建造并观看整棵树。
tsc -b --clean src
- 删除整个树的输出。
tsc -b -f src
- 强制重建整个树。
使用 -d
或-dry
开关预览tsc -b
将要执行的操作。
推荐阅读
- r - Foreach 循环仅针对第一组工作人员返回错误消息
- python - 为什么索引超出范围?
- postgresql - 聚合函数指定处理的字段顺序,聚合后每组返回指定大小的数据并终止
- python - 一段时间后如何显示、隐藏和显示 tkinter 画布?
- javascript - 隐藏默认 HTML CSS | 类型=网址
- python - Python VideoCapture(0) 我的相机坏了
- javascript - 创建一个遍历数组的函数,如果找到特定的数值,则返回 true
- python - 如何获取 Smartsheet 已发布工作表的网址?
- java - 如何使用spring boot创建动态存储库对象
- javascript - 使用现有数组的元素和每个元素的标注结果创建对象或关联数组