写点什么

从 0 开始的 TypeScriptの十一:模块和命名空间

用户头像
空城机
关注
发布于: 1 小时前
从0开始的TypeScriptの十一:模块和命名空间

模块

JavaScript 先天缺少一项功能:模块。 所以在es6提出的Module模块的概念,当然在nodeJs中也存在CommonJS规范。


typescript中的主要模块概念还是Module模块


模块在其自身的作用域里执行,而不是在全局作用域里;这意味着定义在一个模块里的变量,函数,类等等在模块外部是不可见的,除非你明确地使用export形式之一导出它们。


相反,如果想使用其它模块导出的变量,函数,类,接口等的时候,你必须要导入它们,可以使用import形式之一。


模块是自声明的;两个模块之间的关系是通过在文件级别上使用importsexports建立的。


模块使用模块加载器去导入其它的模块。 在运行时,模块加载器的作用是在执行此模块代码前去查找并执行这个模块的所有依赖。


任何包含顶级import或者export的文件都被当成一个模块。相反地,如果一个文件不带有顶级的import或者export声明,那么它的内容被视为全局可见的(因此对模块也是可见的)。


在大型项目中,肯定需要模块化,不然仅仅是typescript的命名冲突就够报一堆错误了


当然,这里如果在文件中使用import或者export会产生一个问题。 使用 tsc转换后的 js 并不能在浏览器中直接使用,因为不支持。 所以这里可以采用 webpack打包转换

  1. 《webpack打包typescript》

  2. 《webpack5热更新打包TS》




导出 exports

任何声明(比如变量,函数,类,类型别名或接口)都能够通过添加export关键字来导出。


方式:


  • export var a:number = 10;

  • export { a };

  • export default a;


注意: export default 在一个模块中只能使用一次,并且导入不能使用 {},可以直接在 import 后写名称

例子

a.ts:

function add(a:number, b:number) {    console.log( a + b );    }export { add }
复制代码


b.ts: 使用 import 进行引入时,可以省略引入文件的后缀

import { add } from "./a";add(4, 5)  // 9
复制代码


此时运行 tsc b.ts命令,会同时生成a.jsb.js两个 JavaScript 文件。 可以使用node b.js来运行,打印 9;

可选的模块加载

编译器会检测是否每个模块都会在生成的 JavaScript 中用到。 如果一个模块标识符只在类型注解部分使用,并且完全没有在表达式中使用时,就不会生成 require 这个模块的代码。 省略掉没有用到的引用对性能提升是很有益的,并同时提供了选择性加载模块的能力。


这种模式的核心是import id = require("...")语句可以让我们访问模块导出的类型。 模块加载器会被动态调用(通过 require)。 它利用了省略引用的优化,所以模块只在被需要时加载。




命名空间

在代码量较大的情况下,为了避免各种变量命名相冲突,可将相似功能的函数、接口、类等放置到命名空间内


TypeScript的命名空间可以将代码包裹起来,只对外暴露需要在外部访问的对象,空间中的对象通过export进行抛出 (这和上面的模块就很相像了,所以 TypeScript 1.5 之前属于名称是“内部模块”)


TypeScript中命名空间使用 namespace 来定义


命名空间和模块的区别:

  • 命名空间主要防止命名冲突

  • 模块是 ts 外部模块的简称,侧重于代码的复用

  • 一个模块里可能会有多个命名空间

命名空间

下面编写一个例子:

namespace First {    export class Animal {        name: string = '张三'    }}
复制代码


这就是一个简单是命名空间,在空间外部对于空间内 Animal 类的使用方法

let firstname = new First.Animal();console.log(firstname);
复制代码


其实命名空间namespace在经过 tsc 编译后,会变成像下面一样的匿名函数

var First;(function (First) {    var Animal = /** @class */ (function () {        function Animal() {            this.name = '张三';        }        return Animal;    }());    First.Animal = Animal;})(First || (First = {}));
复制代码

命名空间别名

在使用命名空间时,可能会需要简化空间名称,这是可以使用import 别名 = 命名空间的方式来取一个别名


注意: 这里给命名空间取别名的import和导入模块的import是不一样的


给上面的例子中First命名空间取别名:

import f = First;
let firstname = new f.Animal();
复制代码


发布于: 1 小时前阅读数: 3
用户头像

空城机

关注

曾经沧海难为水,只是当时已惘然 2021.03.22 加入

业余作者,在线水文 主要干前端的活,业余会学学python 欢迎各位关注,互相学习,互相进步

评论

发布
暂无评论
从0开始的TypeScriptの十一:模块和命名空间