美文网首页
模块解析策略

模块解析策略

作者: 梦舟缘钓 | 来源:发表于2020-03-30 20:59 被阅读0次

模块解析是指编译器在查找导入模块内容时所遵循的流程。

编译器一般遵循两种解析策略:

  1. Classic 解析策略

  2. Node 解析策略

模块引用分相对引用和非相对引用:

  1. 相对引用:相对引用是以 /,./ 或 ../ 开头

  2. 非相对引用:所有其它的引用当作非相对引用

解析策略设置:使用 --moduleResolution标记来指定使用哪种模块解析策略。若未指定,那么在使用了 --module AMD | System | ES2015时的默认值为Classic,其它情况时则为Node。

classic 策略:这种策略在以前是TypeScript默认的解析策略。 现在,它存在的理由主要是为了向后兼容。

相对导入的模块是相对于导入它的文件进行解析的。 因此 /root/src/folder/A.ts文件里的import { b } from "./moduleB"会使用下面的查找流程:

  1. /root/src/folder/moduleB.ts

  2. /root/src/folder/moduleB.d.ts

对于非相对模块的导入,编译器则会从包含导入文件的目录开始依次向上级目录遍历,尝试定位匹配的声明文件。

比如:

有一个对moduleB的非相对导入import { b } from "moduleB",它是在/root/src/folder/A.ts文件里,会以如下的方式来定位"moduleB":

  1. /root/src/folder/moduleB.ts

  2. /root/src/folder/moduleB.d.ts

  3. /root/src/moduleB.ts

  4. /root/src/moduleB.d.ts

  5. /root/moduleB.ts

  6. /root/moduleB.d.ts

  7. /moduleB.ts

  8. /moduleB.d.ts

Node 策略:

通常,在Node.js里导入是通过require函数调用进行的。 Node.js会根据 require的是相对路径还是非相对路径做出不同的行为。相对路径很简单。 例如,假设有一个文件路径为 /root/src/moduleA.js,包含了一个导入var x = require("./moduleB"); Node.js以下面的顺序解析这个导入:

  1. 检查/root/src/moduleB.js文件是否存在。

  2. 检查/root/src/moduleB目录是否包含一个package.json文件,且package.json文件指定了一个"main"模块。 在我们的例子里,如果Node.js发现文件 /root/src/moduleB/package.json包含了{ "main": "lib/mainModule.js" },那么Node.js会引用/root/src/moduleB/lib/mainModule.js。

  3. 检查/root/src/moduleB目录是否包含一个index.js文件。 这个文件会被隐式地当作那个文件夹下的"main"模块。

非相对模块名的解析是个完全不同的过程。 Node会在一个特殊的文件夹 node_modules里查找你的模块。node_modules可能与当前文件在同一级目录下,或者在上层目录里。 Node会向上级目录遍历,查找每个node_modules直到它找到要加载的模块。

还是用上面例子,但假设/root/src/moduleA.js里使用的是非相对路径导入var x = require("moduleB");。 Node则会以下面的顺序去解析 moduleB,直到有一个匹配上。

  1. /root/src/node_modules/moduleB.js

  2. /root/src/node_modules/moduleB/package.json (如果指定了"main"属性)

  3. /root/src/node_modules/moduleB/index.js

  4. /root/node_modules/moduleB.js

  5. /root/node_modules/moduleB/package.json (如果指定了"main"属性)

  6. /root/node_modules/moduleB/index.js

  7. /node_modules/moduleB.js

  8. /node_modules/moduleB/package.json (如果指定了"main"属性)

  9. /node_modules/moduleB/index.js

node 允许的文件扩展名包含:.js、.json、.node,当引人文件不包含扩展名,node会依次补足扩展名,依次尝试。

TypeScript如何解析模块:

TypeScript在Node解析逻辑基础上增加了TypeScript源文件的扩展名( .ts,.tsx和.d.ts)

TypeScript在 package.json里使用字段"types"来表示类似"main"的意义

有一个导入语句import { b } from "./moduleB"在/root/src/moduleA.ts里,会以下面的流程来定位"./moduleB":

  1. /root/src/moduleB.ts

  2. /root/src/moduleB.tsx

  3. /root/src/moduleB.d.ts

  4. /root/src/moduleB/package.json (如果指定了"types"属性)

  5. /root/src/moduleB/index.ts

  6. /root/src/moduleB/index.tsx

  7. /root/src/moduleB/index.d.ts

相关文章

网友评论

      本文标题:模块解析策略

      本文链接:https://www.haomeiwen.com/subject/dbqbyctx.html