首页 前端知识 Typescript配置文件(tsconfig.json)详解系列三:module(一)

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

2024-08-18 00:08:54 前端知识 前端哥 265 56 我要收藏

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

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

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

Typescript版本

Typescript5.5.2

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

{
    compilerOptions: {
        "module": "commonjs"
    }
}

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

例子

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

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

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

// cjs.ts
// typescript中的commonjs导出方式
export = {
    a: 1
}

// esm.ts
export const b = 2;

// index.ts
import {b} from './esm';
// typescript中的commonjs导入方式
import a = require('./cjs');

console.log(a, b)

编译js的模块系统为commonjs

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

{
    compilerOptions: {
        "module": "commonjs"
    }
}

编译后的代码如下:

// cjs.js
"use strict";
module.exports = {
    a: 1
};

// esm.js
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.b = void 0;
exports.b = 2;

// index.js
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const esm_1 = require("./esm");
// import * as c from './cjs'
const a = require("./cjs");
console.log(a, esm_1.b);

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

编译js的模块系统为ESM

ES2015/ES6

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

{
    compilerOptions: {
        "module": "ES2015" // 或ES6
    }
}

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


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.

1 export = {
  ~~~~~~~~~~
2     a: 1
  ~~~~~~~~
3 }
  ~

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.

3 import a = require('./cjs');
  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~


Found 2 errors in 2 files.

Errors  Files
     1  ts/cjs.ts:1
     1  ts/index.ts:3

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

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

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

 ES2020

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

// index.ts
// 动态import
import('./esm').then(({b}) => {
    console.log(b);
    // import.meta
    console.log(import.meta.url);
});

编译结果如下:

// esm.js
export const b = 2;
// index.js
// 动态import
import('./esm').then(({ b }) => {
    console.log(b);
    // import.meta
    console.log(import.meta.url);
});
export {};

ES2022(ESNext)

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

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

编译结果如下:

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

SystemJS

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

import {b} from './esm';

console.log(b)

代码编译结果如下:

// esm.js
System.register([], function (exports_1, context_1) {
    "use strict";
    var b;
    var __moduleName = context_1 && context_1.id;
    return {
        setters: [],
        execute: function () {
            exports_1("b", b = 2);
        }
    };
});


// index.js
System.register(["./esm"], function (exports_1, context_1) {
    "use strict";
    var esm_1;
    var __moduleName = context_1 && context_1.id;
    return {
        setters: [
            function (esm_1_1) {
                esm_1 = esm_1_1;
            }
        ],
        execute: function () {
            console.log(esm_1.b);
        }
    };
});

AMD

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

import {b} from './esm';
// typescript中的commonjs导入方式
import a = require('./cjs');

console.log(a, b)

代码编译结果如下:

// cjs.js
define(["require", "exports"], function (require, exports) {
    "use strict";
    return {
        a: 1
    };
});

// esm.js
define(["require", "exports"], function (require, exports) {
    "use strict";
    Object.defineProperty(exports, "__esModule", { value: true });
    exports.b = void 0;
    exports.b = 2;
});

// index.js
define(["require", "exports", "./esm", "./cjs"], function (require, exports, esm_1, a) {
    "use strict";
    Object.defineProperty(exports, "__esModule", { value: true });
    console.log(a, esm_1.b);
});

UMD

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

// cjs.js
(function (factory) {
    if (typeof module === "object" && typeof module.exports === "object") {
        var v = factory(require, exports);
        if (v !== undefined) module.exports = v;
    }
    else if (typeof define === "function" && define.amd) {
        define(["require", "exports"], factory);
    }
})(function (require, exports) {
    "use strict";
    return {
        a: 1
    };
});

// esm.js
(function (factory) {
    if (typeof module === "object" && typeof module.exports === "object") {
        var v = factory(require, exports);
        if (v !== undefined) module.exports = v;
    }
    else if (typeof define === "function" && define.amd) {
        define(["require", "exports"], factory);
    }
})(function (require, exports) {
    "use strict";
    Object.defineProperty(exports, "__esModule", { value: true });
    exports.b = void 0;
    exports.b = 2;
});


// index.js
(function (factory) {
    if (typeof module === "object" && typeof module.exports === "object") {
        var v = factory(require, exports);
        if (v !== undefined) module.exports = v;
    }
    else if (typeof define === "function" && define.amd) {
        define(["require", "exports", "./esm", "./cjs"], factory);
    }
})(function (require, exports) {
    "use strict";
    Object.defineProperty(exports, "__esModule", { value: true });
    const esm_1 = require("./esm");
    // typescript中的commonjs导入方式
    const a = require("./cjs");
    console.log(a, esm_1.b);
});

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.qianduange.cn//article/15948.html
标签
评论
发布的文章

jQuery 教程 (一)

2024-08-24 23:08:43

select 多选联动

2024-08-24 23:08:41

jQuery2 高级教程(九)

2024-08-24 23:08:22

使用CDN提高jQuery加载速度

2024-08-24 23:08:21

jQuery2 秘籍(七)

2024-08-24 23:08:20

【ECharts】雷达图

2024-08-24 23:08:18

大家推荐的文章
会员中心 联系我 留言建议 回顶部
复制成功!