1. 程式人生 > >Typescript和Node模塊解析策略

Typescript和Node模塊解析策略

div nod 一級目錄 exp pos ack express code blog

一般我們在模塊化編碼時,總會導入其它模塊,通常我們使用如下語法:

import { A } from ‘./a‘; // ES6語法
import { A } from ‘a‘;
var A = require(‘./a‘); // commonjs規範

不論使用哪種語法,導入的文件一般有兩種:內部文件(自己開發的)和外部(node_modules)中兩種,其中導入內部模塊稱之為相對導入,導入node_modules中,稱之為非相對導入,它們在語法上的區別就是導入的路徑是否是相對的

接下來我們看看typescript和node中它們是如何解析模塊的

Typescript模塊解析策略

我們知道import語法用來導入某個文件,

import { A } from ‘./a‘;   // 相對導入
import { A } from ‘../a‘;  // 相對導入
import { Express } from ‘express‘; // node_modules中模塊

接下來我們看下這種兩種方式在解析時有什麽區別?

相對導入

假如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.js
/root/src/a/package.json (如果指定了"main"屬性,則使用main中的)
/root/src/a/index.js

上述第二步中,假如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

Typescript和Node模塊解析策略