模块可以组织我们的代码,在本文中,我们将介绍如何创建和使用模块,模块的格式,默认导出,通配符导入以及重新导入等知识。
导出和导入
到目前为止,我们写的代码都在一个文件里,当文件逐渐增大时,维护就会变得困难,可以将其分隔成多个文件或者叫模块,每个模块负责一个功能。
我们有两个类,Circle 和 Square。
现在我们想把它们移到模块里,创建一个文件shapes.ts,然后将这两个类移入其中,并且在这两个类的前面加上 export 关键字表示可以导出给其他模块使用。
index.ts使用这两个类,可以使用 import 关键字从shapes.ts中导入,注意不加后缀 .ts,仅使用文件名shapes。
import { Circle, Square } from “./shapes”
如果index.ts同时从其它模块导入,名字有重名,可以通过 as 关键字进行改名。
import { Circle as MyCircle } from “./shapes”
模块格式
以前JavaScript没有模块概念,有很多第三方解决方案,于是出现了很多格式,比如commonJS,AMD等。
JavaScript在ES6版本时有了内置的模块语法,就是前面的export和import等语法,该格式现在几乎被所有的浏览器和JavaScript运行引擎支持,所以现在真的不需要了解其他的模块格式了。
我们来看看。
查看tsconfig.json,我们看到模块的配置还是commonJS,这是Node初始的模块格式。我们用tsc编译下,看到shapes.js里是没有import和export语法的,而是使用exports对象的解决方法。
我们修改tsconfig.json的module选项,选择ES2015,这是被广泛支持的。
然后再看看生成的JavaScript模块的代码。
默认导出
有时我们只需要从模块里导出某个单独的东西,这种情况就比较适合用默认导出。
看下例子。
模块里有Store类用于持久化某些数据,还有Compressor类和Encryptor类分别用于压缩和加密。对使用该模块的用户而言,只需知道Store类即可,Compressor和Encryptor只是模块内部实现,没必要导出让外部知道并产生可能的耦合。我们只需导出Store。
使用前面介绍的知识,在Store类加 export 关键字,再在使用的地方用 import 关键字导入该类,当然是可以的,不过更好的方法是使用默认导入,即在 export 后再添加 default 关键字。
export default class Store { }
使用默认导出,在使用 import 关键字导入时,我们不再需要大括号,代码更简洁。默认导出可与前面介绍的用大括号命名的导出共存,比如在该模块中我们还需要导出一个枚举Format也是可以的。
通配符导入
有时候我们要从一个模块导入不少对象,导入1个,2个可能还好。
import { Square, Circle } from “./shapes”;
但要是导入10个或更多呢,就会显得很冗长且不清晰,可以使用通配符导入(*)简化代码。
import * as Shapes from “./shapes”;
我们导入 * 表示模块里的所有东西并重命名为Shapes, Shapes相当于一个容器。后面就可以加Shapes前缀指定具体的类。
let square = new Shapes.Square(1);
重导出
重导出可以用单个模块来合并不同的几个模块的导出,从而简化代码。
我们新建shapes文件夹,将shapes.ts移入其中,再将shapes.ts文件的Circle类和Square类分别移到新建的Circle.ts和Square.ts文件中,再将shapes.ts改名为 index.ts,我们在新命名的index.ts中,导入Circle和Square,然后再进行导出。这样之后,使用这两个类的模块只需要从index导入即可。
实际上,导入时可省略掉index,直接从shapes文件夹导入即可,shapes相当于一个包,不过这种方式我们需要修改tsconfig.json的配置,启用
“moduleResolution”: “node10”,
还可以进一步简化。
在index.ts里,我们是先从其他模块导入,然后导出,我们可以直接重新导出。如下。
小结
本文介绍了如何创建和使用模块,模块的格式,默认导出,通配符导入以及重导入等知识。
下一篇介绍TypeScript与JavaScript的集成。