一般我們在模塊化編碼時,總會導入其它模塊,通常我們使用如下語法:
import { A } from './a'; // ES6語法
import { A } from 'a';
var A = require('./a'); // commonjs規范
不論使用哪種語法,導入的文件一般有兩種:內部文件(自己開發的)和外部(node_modules)中兩種,其中導入內部模塊稱之為相對導入,導入node_modules中,稱之為非相對導入,它們在語法上的區別就是導入的路徑是否是相對的
接下來我們看看typescript和node中它們是如何解析模塊的
Typescript模塊解析策略
相對導入
假如b.ts路徑是:/root/src/b.ts
import { A } from './a';
typescript編譯器在查找a模塊時會依次按照如下順序查找,如果仍然找不到則會模塊找不到的錯誤。
/root/src/a.ts
/root/src/a.tsx
/root/src/a.d.ts
/root/src/a/package.json (如果指定了"types"屬性,則使用types中)
/root/src/a/index.ts
/root/src/a/index.tsx
/root/src/a/index.d.ts
非相對導入
假如b.ts路徑是:/root/src/b.ts
import { A } from 'a';
typescript編譯器在查找a模塊時會按照如下順序查找:
/root/src/node_modules/a.ts
/root/src/node_modules/a.tsx
/root/src/node_modules/a.d.ts
/root/src/node_modules/a/package.json
/root/src/node_modules/a/index.ts
/root/src/node_modules/a/index.tsx
/root/src/node_modules/a/index.d.ts
/root/node_modules/a.ts
/root/node_modules/a.tsx
/root/node_modules/a.d.ts
/root/node_modules/a/package.json
/root/node_modules/a/index.ts
/root/node_modules/a/index.tsx
/root/node_modules/a/index.d.ts
/node_modules/a.ts
/node_modules/a.tsx
/node_modules/a.d.ts
/node_modules/a/package.json
/node_modules/a/index.ts
/node_modules/a/index.tsx
/node_modules/a/index.d.ts
其中在上面兩處空白行處,編譯器會跳到上一級目錄查找,直到到工程根目錄
注意:有時候我們在導入外部模塊(沒有ts文件,只有),編譯器會報模塊找不到,但是我們node_modules確實有,這種方式不是編譯器bug而需要我們在配置文件tsconfig.json中修改模塊解析策略:
"moduleResolution": "node"
說到這里我們看看Nodejs時如何解析模塊的,NodeJs使用了commonjs模塊規范,typescript編譯和其大同小異。
Nodejs相對導入
假如b.ts路徑是:/root/src/b.js
var A = require('./a')
typescript編譯器在查找a模塊時會按照如下順序查找:
/root/src/a
/root/src/a.js
/root/src/a.json
/root/src/a/package.json (如果指定了"main"屬性,則使用main中的)
/root/src/a/index.js
/root/src/a/index.json
上述第二步中,假如main:"./core/main.js",則最終模塊路徑:
/root/src/a/core/main.js
Nodejs非相對導入
var A = require('a')
typescript編譯器在查找a模塊時會按照如下順序查找:
/root/src/node_modules/a.js
/root/src/node_modules/a/package.json (如果指定了"main"屬性,則使用main中的)
/root/src/node_modules/a/index.js
/root/node_modules/a.js
/root/node_modules/a/package.json (如果指定了"main"屬性,則使用main中的)
/root/node_modules/a/index.js
/node_modules/a.js
/node_modules/a/package.json (如果指定了"main"屬性,則使用main中的)
/node_modules/a/index.js
