当前位置:   article > 正文

Typescript配置文件(tsconfig.json)详解系列三:module(一)_tsconfig.json module

tsconfig.json module

系列文章会一直更新,大家可以收藏加关注。不懂的可以在评论区留言。

在*.ts文件中我们应该使用什么模块化方式去编写代码。

在正式介绍这个配置参数之前我们先看一下这个问题。

Typescript版本

Typescript5.5.2

module用来设置Typescript编译成javascript后所使用的模块系统。

  1. {
  2. compilerOptions: {
  3. "module": "commonjs"
  4. }
  5. }

所以这个值要设置为你编译后的代码所在的运行环境的模块系统

例子

我们看一下这个例子,我们有两个文件分别为:

  • cjs.ts:commonjs导出(typescript中使用commonjs导出的语法和正常的不太一样
  • esm.ts: esm导出

我们的index.ts导入这两个模块,代码如下:

  1. // cjs.ts
  2. // typescript中的commonjs导出方式
  3. export = {
  4. a: 1
  5. }
  6. // esm.ts
  7. export const b = 2;
  8. // index.ts
  9. import {b} from './esm';
  10. // typescript中的commonjs导入方式
  11. import a = require('./cjs');
  12. console.log(a, b)

编译js的模块系统为commonjs

当我们的运行js的模块系统为commonjs时(比如node低版本的环境,新版本Node现在更推荐使用module: "Node16" 或 module: "NodeNext")

  1. {
  2. compilerOptions: {
  3. "module": "commonjs"
  4. }
  5. }

编译后的代码如下:

  1. // cjs.js
  2. "use strict";
  3. module.exports = {
  4. a: 1
  5. };
  6. // esm.js
  7. "use strict";
  8. Object.defineProperty(exports, "__esModule", { value: true });
  9. exports.b = void 0;
  10. exports.b = 2;
  11. // index.js
  12. "use strict";
  13. Object.defineProperty(exports, "__esModule", { value: true });
  14. const esm_1 = require("./esm");
  15. // import * as c from './cjs'
  16. const a = require("./cjs");
  17. console.log(a, esm_1.b);

所以在编写Typescript代码的时候,是可以使用esm和cjs的。

编译js的模块系统为ESM

ES2015/ES6

当我们运行js的环境为浏览器,并且浏览器只支持ES6语法时,我们可以设置为ES2015或ES6(一样)

  1. {
  2. compilerOptions: {
  3. "module": "ES2015" // 或ES6
  4. }
  5. }

例子的代码编译后会报错:

  1. ts/cjs.ts:1:1 - error TS1203: Export assignment cannot be used when targeting ECMAScript modules. Consider using 'export default' or another module format instead.
  2. 1 export = {
  3. ~~~~~~~~~~
  4. 2 a: 1
  5. ~~~~~~~~
  6. 3 }
  7. ~
  8. ts/index.ts:3:1 - error TS1202: Import assignment cannot be used when targeting ECMAScript modules. Consider using 'import * as ns from "mod"', 'import {a} from "mod"', 'import d from "mod"', or another module format instead.
  9. 3 import a = require('./cjs');
  10. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  11. Found 2 errors in 2 files.
  12. Errors Files
  13. 1 ts/cjs.ts:1
  14. 1 ts/index.ts:3

在这里我们可以看到commonjs的模块导入导出会报错。(这个错误在ES2015(ES6),ES2020,ES2022,ESNext都会报)。

去掉cjs.ts的引用后,代码可以正常编译,编译结果如下:

  1. // esm.js
  2. export const b = 2;
  3. // index.js
  4. import { b } from './esm';
  5. console.log(b);

 ES2020

ES2020比ES2015多了dynamic imports和import.meta的支持,Typescript代码如下:

  1. // index.ts
  2. // 动态import
  3. import('./esm').then(({b}) => {
  4. console.log(b);
  5. // import.meta
  6. console.log(import.meta.url);
  7. });

编译结果如下:

  1. // esm.js
  2. export const b = 2;
  3. // index.js
  4. // 动态import
  5. import('./esm').then(({ b }) => {
  6. console.log(b);
  7. // import.meta
  8. console.log(import.meta.url);
  9. });
  10. export {};

ES2022(ESNext)

现在ES2022和ESNext是相同的(如果以后js有大更新,则ES2022将会被冻结, ESNext指向下一个版本),ES2022比ES2020多了顶级await(top-level await)的支持,Typescript代码如下:

  1. // 顶级await
  2. const { b } = await import('./esm');
  3. export {};

编译结果如下:

  1. // esm.js
  2. export const b = 2;
  3. // index.js
  4. // 顶级await
  5. const { b } = await import('./esm');
  6. export {};

SystemJS

SystemJS也不支持CommonJS语法,Typescript代码如下:

  1. import {b} from './esm';
  2. console.log(b)

代码编译结果如下:

  1. // esm.js
  2. System.register([], function (exports_1, context_1) {
  3. "use strict";
  4. var b;
  5. var __moduleName = context_1 && context_1.id;
  6. return {
  7. setters: [],
  8. execute: function () {
  9. exports_1("b", b = 2);
  10. }
  11. };
  12. });
  13. // index.js
  14. System.register(["./esm"], function (exports_1, context_1) {
  15. "use strict";
  16. var esm_1;
  17. var __moduleName = context_1 && context_1.id;
  18. return {
  19. setters: [
  20. function (esm_1_1) {
  21. esm_1 = esm_1_1;
  22. }
  23. ],
  24. execute: function () {
  25. console.log(esm_1.b);
  26. }
  27. };
  28. });

AMD

AMD支持CommonJS和ESM,Typescript代码如下:

  1. import {b} from './esm';
  2. // typescript中的commonjs导入方式
  3. import a = require('./cjs');
  4. console.log(a, b)

代码编译结果如下:

  1. // cjs.js
  2. define(["require", "exports"], function (require, exports) {
  3. "use strict";
  4. return {
  5. a: 1
  6. };
  7. });
  8. // esm.js
  9. define(["require", "exports"], function (require, exports) {
  10. "use strict";
  11. Object.defineProperty(exports, "__esModule", { value: true });
  12. exports.b = void 0;
  13. exports.b = 2;
  14. });
  15. // index.js
  16. define(["require", "exports", "./esm", "./cjs"], function (require, exports, esm_1, a) {
  17. "use strict";
  18. Object.defineProperty(exports, "__esModule", { value: true });
  19. console.log(a, esm_1.b);
  20. });

UMD

UMD支持CommonJS和ESM,代码编译结果如下:

  1. // cjs.js
  2. (function (factory) {
  3. if (typeof module === "object" && typeof module.exports === "object") {
  4. var v = factory(require, exports);
  5. if (v !== undefined) module.exports = v;
  6. }
  7. else if (typeof define === "function" && define.amd) {
  8. define(["require", "exports"], factory);
  9. }
  10. })(function (require, exports) {
  11. "use strict";
  12. return {
  13. a: 1
  14. };
  15. });
  16. // esm.js
  17. (function (factory) {
  18. if (typeof module === "object" && typeof module.exports === "object") {
  19. var v = factory(require, exports);
  20. if (v !== undefined) module.exports = v;
  21. }
  22. else if (typeof define === "function" && define.amd) {
  23. define(["require", "exports"], factory);
  24. }
  25. })(function (require, exports) {
  26. "use strict";
  27. Object.defineProperty(exports, "__esModule", { value: true });
  28. exports.b = void 0;
  29. exports.b = 2;
  30. });
  31. // index.js
  32. (function (factory) {
  33. if (typeof module === "object" && typeof module.exports === "object") {
  34. var v = factory(require, exports);
  35. if (v !== undefined) module.exports = v;
  36. }
  37. else if (typeof define === "function" && define.amd) {
  38. define(["require", "exports", "./esm", "./cjs"], factory);
  39. }
  40. })(function (require, exports) {
  41. "use strict";
  42. Object.defineProperty(exports, "__esModule", { value: true });
  43. const esm_1 = require("./esm");
  44. // typescript中的commonjs导入方式
  45. const a = require("./cjs");
  46. console.log(a, esm_1.b);
  47. });

Node16(NodeNext)

当前版本Node16和NodeNext表现一致(如果以后Node做出重大改变,Node16将会被冻结,NodeNext则指向下一个个版本),当我们js的运行环境为Node12及以上版本(CJS和ESM双模块系统)的时候,可以使用。

模块解析规则如下

当package.json中没有设置type字段,或者type字段等于commonjs,则所有.ts文件模块系统被转换为CommonJS系统。

当package.json中设置type字段等于module,则.ts文件被解析为ESM模块。且.ts文件禁止使用commonjs。

.cts文件的导出系统必须是commonjs,且编译后的js文件后缀为.cjs。

.ets文件的导出系统必须是ESM,且编译后的js文件后缀为.ejs。

本文内容由网友自发贡献,转载请注明出处:https://www.wpsshop.cn/w/从前慢现在也慢/article/detail/903721
推荐阅读
相关标签
  

闽ICP备14008679号