TypeScript 模塊導入那些事

ES6 模塊導入的限制

咱們先來看一個具體的例子:javascript

在 Node 項目裏,使用 CommonJS 規範引入一個模塊:html

const koa = require('koa')
複製代碼

改寫爲 TypeScript(1.5+ 版本)時,一般有兩種方式:java

  • 使用 ES6 模塊導入方式:git

    // allowSyntheticDefaultImports: false
    import * as koa from 'koa'
    複製代碼
  • 使用 TypeScript 模塊導入語法:typescript

    import koa = require('koa')
    複製代碼

二者大部分是等價的,但 ES6 規範對 import * as 建立出的模塊對象有一點限制。 根據該規範,該模塊對象不可被調用,也不可被實例化,它只具備屬性app

所以,若是你想調用該對象,或者使用 new 方法,在 allowSyntheticDefaultImports: false 的配置下,應該使用例子中的第二種方式。koa

2.7 版本對 CommonJs/AMD/UMD 模塊導入的加強

在以前的版本,TypeScript 對 CommonJs/AMD/UMD 模塊的處理方式與 ES6 模塊相同,這會致使一些問題:ui

  • 如前文所提到的,當導入一個 CommonJs/AMD/UMD 模塊時,TypeScript 視 import * as koa from 'koa'const koa = require('koa') 等價,但使用 import * as 建立的模塊對象實際上不可被調用以及被實例化。this

  • 相似的,當導入一個 CommonJs/AMD/UMD 模塊時,TypeScript 視 import foo from 'foo'const koa = require('koa').default 等價,但在大部分 CommonJs/AMD/UMD 模塊裏,它們並無默認導出。google

在 2.7 的版本里,TypeScript 提供了一個新選項 --esModuleInterop,旨在解決上述問題, 當使用該選項,且模塊爲 CommonJs/AMD/UMD 時,它會導入一個可調用或是可實例化的模塊,同時它規定該模塊必須做爲默認導入:

import koa from 'koa'
const app = new koa()
複製代碼

模塊導入僅僅是一些聲明類型

在以非相對路徑導入一個模塊時,你可能會看到 Could not find a declaration file for module 'someModule' 的錯誤, 此時你能夠安裝對應模塊的聲明文件或者寫一個包含 declare module 'someModule' 的聲明文件。

實際上,當咱們導入一個模塊時:

import koa from 'koa'
// import koa = require('koa')
複製代碼

它所作的事情只有兩個:

  • 導入模塊的全部類型信息;
  • 肯定運行時的依賴關係。

當你加載此模塊,但並無使用,或僅看成類型來使用時,編譯後,此模塊將會被移除。

當不使用時;

import koa from 'koa'
複製代碼

編譯後:

複製代碼

僅當作類型使用時:

import koa from 'koa'
let k: koa
複製代碼

編譯後:

var k
複製代碼

作爲值使用時,編譯後,此模塊將會被保留:

import koa from 'koa'
const app = new koa()
複製代碼

編譯後(假設使用 commonjs):

var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
var koa_1 = __importDefault(require("koa"));
var k = new koa_1.default();
複製代碼

注:__importDefault 爲使用 --esModuleInterop 選項時產生的方法。

參考

  • http://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-7.html
  • https://stackoverflow.com/questions/35706164/typescript-import-as-vs-import-require?utm_medium=organic&utm_source=google_rich_qa&utm_campaign=google_rich_qa
  • https://basarat.gitbooks.io/typescript/content/docs/project/external-modules.html
相關文章
相關標籤/搜索