你可以阅读Node.js文档了解更多详细信息:loading modules from node_modules
。
TypeScript如何解析模块
TypeScript是模仿Node.js运行时的解析策略来在编译阶段定位模块定义文件。 因此,TypeScript在Node解析逻辑基础上增加了TypeScript源文件的扩展名( .ts
,.tsx
和.d.ts
)。 同时,TypeScript在 package.json
里使用字段"typings"
来表示类似"main"
的意义 - 编译器会使用它来找到要使用的"main"定义文件。
比如,有一个导入语句import { b } from "./moduleB"
在/root/src/moduleA.ts
里,会以下面的流程来定位"./moduleB"
:
/root/src/moduleB.ts
/root/src/moduleB.tsx
/root/src/moduleB.d.ts
/root/src/moduleB/package.json
(如果指定了"typings"
属性)/root/src/moduleB/index.ts
/root/src/moduleB/index.tsx
/root/src/moduleB/index.d.ts
回想一下Node.js先查找moduleB.js
文件,然后是合适的package.json
,再之后是index.js
。
类似地,非相对的导入会遵循Node.js的解析逻辑,首先查找文件,然后是合适的文件夹。 因此/src/moduleA.ts
文件里的import { b } from "moduleB"
会以下面的查找顺序解析:
/root/src/node_modules/moduleB.ts
/root/src/node_modules/moduleB.tsx
/root/src/node_modules/moduleB.d.ts
/root/src/node_modules/moduleB/package.json
(如果指定了"typings"
属性)/root/src/node_modules/moduleB/index.ts
/root/src/node_modules/moduleB/index.tsx
/root/src/node_modules/moduleB/index.d.ts
/root/node_modules/moduleB.ts
/root/node_modules/moduleB.tsx
/root/node_modules/moduleB.d.ts
/root/node_modules/moduleB/package.json
(如果指定了"typings"
属性)/root/node_modules/moduleB/index.ts
/root/node_modules/moduleB/index.tsx
/root/node_modules/moduleB/index.d.ts
/node_modules/moduleB.ts
/node_modules/moduleB.tsx
/node_modules/moduleB.d.ts
/node_modules/moduleB/package.json
(如果指定了"typings"
属性)/node_modules/moduleB/index.ts
/node_modules/moduleB/index.tsx
/node_modules/moduleB/index.d.ts
不要被这里步骤的数量吓到 - TypeScript只是在步骤(8)和(15)向上跳了两次目录。 这并不比Node.js里的流程复杂。
使用--noResolve
正常来讲编译器会在开始编译之前解析模块导入。 每当它成功地解析了对一个文件 import
,这个文件被会加到一个文件列表里,以供编译器稍后处理。
--noResolve
编译选项告诉编译器不要添加任何不是在命令行上传入的文件到编译列表。 编译器仍然会尝试解析模块,但是只要没有指定这个文件,那么它就不会被包含在内。
比如
app.ts
import * as A from "moduleA" // OK, moduleA passed on the command-line
import * as B from "moduleB" // Error TS2307: Cannot find module 'moduleB'.
tsc app.ts moduleA.ts --noResolve
使用--noResolve
编译app.ts
:
- 可能正确找到
moduleA
,因为它在命令行上指定了。 - 找不到
moduleB
,因为没有在命令行上传递。
常见问题
为什么在exclude
列表里的模块还会被编译器使用
tsconfig.json
将文件夹转变一个“工程” 如果不指定任何 “exclude”
或“files”
,文件夹里的所有文件包括tsconfig.json
和所有的子目录都会在编译列表里。 如果你想利用 “exclude”
排除某些文件,甚至你想指定所有要编译的文件列表,请使用“files”
。
有些是被tsconfig.json
自动加入的。 它不会涉及到上面讨论的模块解析。 如果编译器识别出一个文件是模块导入目标,它就会加到编译列表里,不管它是否被排除了。
因此,要从编译列表中排除一个文件,你需要在排除它的同时,还要排除所有对它进行import
或使用了/// <reference path="..." />
指令的文件。
标签:TypeScript
相关阅读 >>
export和export default中的知识点介绍(附示例)
angular cli如果搭建angular+typescript+material项目?
简单对比,看看typescript中interface和type间的区别
更多相关阅读请进入《typescript》频道 >>

Vue.js 设计与实现 基于Vue.js 3 深入解析Vue.js 设计细节
本书对 Vue.js 3 技术细节的分析非常可靠,对于需要深入理解 Vue.js 3 的用户会有很大的帮助。——尤雨溪,Vue.js作者