视频1 视频21 视频41 视频61 视频文章1 视频文章21 视频文章41 视频文章61 推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37 推荐39 推荐41 推荐43 推荐45 推荐47 推荐49 关键词1 关键词101 关键词201 关键词301 关键词401 关键词501 关键词601 关键词701 关键词801 关键词901 关键词1001 关键词1101 关键词1201 关键词1301 关键词1401 关键词1501 关键词1601 关键词1701 关键词1801 关键词1901 视频扩展1 视频扩展6 视频扩展11 视频扩展16 文章1 文章201 文章401 文章601 文章801 文章1001 资讯1 资讯501 资讯1001 资讯1501 标签1 标签501 标签1001 关键词1 关键词501 关键词1001 关键词1501 专题2001
关于TypeScript模块导入的那些事
2020-11-27 22:13:04 责编:小采
文档


前言

模块在其自身的作用域里执行,而不是在全局作用域里;这意味着定义在一个模块里的变量,函数,类等等在模块外部是不可见的,除非你明确地使用export之一导出它们。 相反,如果想使用其它模块导出的变量,函数,类,接口等的时候,你必须要导入它们,可以使用import之一。

模块是自声明的。在TypeScript里,两个模块之间的关系是通过在文件级别上使用import和export建立的。

下面话不多说了,来一起看看详细的介绍吧

ES6 模块导入的

我们先来看一个具体的例子:

在 Node 项目里,使用 CommonJS 规范引入一个模块:

const koa = require('koa')

改写为 TypeScript(1.5+ 版本)时,通常有两种方式:

使用 ES6 模块导入方式:

// allowSyntheticDefaultImports: false
import * as koa from 'koa'

使用 TypeScript 模块导入语法:

import koa = require('koa')

两者大部分是等价的,但 ES6 规范对 import * as 创建出的模块对象有一点。

根据该规范,该模块对象不可被调用,也不可被实例化,它只具有属性。

因此,如果你想调用该对象,或者使用 new 方法,在 allowSyntheticDefaultImports: false 的配置下,应该使用例子中的第二种方式。

2.7 版本对 CommonJs/AMD/UMD 模块导入的增强

在之前的版本,TypeScript 对 CommonJs/AMD/UMD 模块的处理方式与 ES6 模块相同,这会导致一些问题:

  • 如前文所提到的,当导入一个 CommonJs/AMD/UMD 模块时,TypeScript 视 import * as koa from 'koa' 与 const koa = require('koa') 等价,但使用 import * as 创建的模块对象实际上不可被调用以及被实例化。
  • 类似的,当导入一个 CommonJs/AMD/UMD 模块时,TypeScript 视 import foo from 'foo' 与 const koa = require('koa').default 等价,但在大部分 CommonJs/AMD/UMD 模块里,它们并没有默认导出。
  • 在 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/357061/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

    总结

    下载本文
    显示全文
    专题