关于commonjs、AMD、UMD、ESM以及ts模块之间的使用差异
创始人
2024-01-31 00:34:22

commonjs

特点:一个文件就是一个模块,拥有独立的作用域,适用于服务端不适合浏览器端。导出模块内部数据通过module.exports或exports对象默认导出:

// true
const a = 1
const b = 2
module.exports = {a, b
}

或者

// true
const a = 1
const b = 2
exports.a = a
exports.b = b

module.exports等于exports这个对象,不能改变exports对象的指针方向。

// false
const a = 1
const b = 2
exports = {a,b
}

AMD

特点:浏览器端没有具体实现该规范的代码,需要使用define配合requireJS来实现。一个define就是一个模块。


Document

// 导出
// b.js
define(function () {'use strict';const c = 3const d = 4return {c,d}
});
// 或者
define(function (require, exports, module) {'use strict';const c = 3const d = 4module.exports = {c,d}
});// 导入
// a.js 依赖前置
define(['./b'], function (b) {console.log(b);
});
// 或者 后置依赖
define(function (require, exports, module) {const b = require('./b')console.log(b);
});

UMD

UMD的出现是为了同时兼容node端和浏览器端。

(function (root, factory) {if (typeof module === 'object' && typeof module.exports === 'object') {// nodemodule.exports = factory()} else if (typeof define === 'function' && define.amd) {// 浏览器define(factory)} else {// 既不是浏览器也不是noderoot.factory = factory}
})(this, function () {const a = 1const b = 2return {a, b}
})

ESM

一个文件就是模块,拥有独立的作用域,script标签需要声明type=“module”。
导出模块数据:

// 单个导出
export let a = 1
export let b = 2
// 导出列表
export {a,b}
// 重命名导出
export {a as one,b as two}
// 默认导出
export default {a,b}
export {a as default,b as two}
// 重定向导出
export * from './a'
export {a,b} from './a'
export { default } from './a'

TS模块系统

typescript有一套自己的模块系统,类似esm,以一个文件作为模块最小单元:

  • 任何一个包含顶级import或者export的文件都被当成一个模块
  • 如果一个文件不带有import 或者export ,那么它的内容就是全局的

全局模块(不推荐)

// index.ts
let a = 1
let b = 2// index2.ts error
let a = 1// index2.ts true
let a = 1
export default {}

在这里插入图片描述
当我们在两个不同的文件中重复声明同一个变量的时候如果没有使用顶级import或者export 那么就是全局声明导致重复声明。

导入js文件

// b.js commonjs导出方式
module.exports = {a: {b: 1}
}
// a.js 默认引入
import m from './b.js'
console.log(m);
编译后会报错,此时配置allowSyntheticDefaultImports:true:
"use strict";
exports.__esModule = true;
var b_js_1 = require("./b.js");
console.log(b_js_1["default"]);

引入的方式是默认引入,需要默认导出才能引入(或者import * as m from './b.js' m={ a: [Getter], default: { a: { b: 1 } } } )。使用默认导出编译后可以看出获取了该对象的default属性,commonjs的方式没有default。所以tsconfig.json可以配置esModuleInterop:true的方式解决:

"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
var b_js_1 = __importDefault(require("./b.js"));
console.log(b_js_1.default);

模块解析规则

typescript支持两种不同的模块解析策略:Node、Classic。当module为:AMD、System、ES2015的时候,默认为Classic,否则为node。也可以设置moduleResolution为node。typescript现在使用了与Node.js类似的模块解析策略,但是Typescript增加了其他几个源文件扩展名的查找(.ts、.tsx、.d.ts),同时Typescript在package.json里使用types去表示main的意义。

Classic模块解析策略

  1. 相对导入
// src/a.ts
import a from './a.ts'
解析流程:
1.src/a.ts
默认补全后缀
import a from './a'
解析流程:
1./src/a.ts
2./src/a.d.ts
  1. 非相对导入
import a from 'a'
从包含文件目录开始依次向上级目录遍历查找,直到根目录
1./src/a.ts
2./src/a.d.ts
3./a.ts
4./a.d.ts

Node解析策略

  1. 相对导入
// src/a.js
import a from './a'
解析流程:
1.src/a.js
2.src/package.json中指定的文件
3.src/index.js
  1. 非相对导入

非相对导入中会在node_modules里查找,并从当前目录的node_modules目录下逐级向上级文件夹查找。

// src/a.js
import a from 'a'
解析流程:
1.src/node_modules/a.js
2.src/node_modules/package.json中main指定的文件
3.src/node_modules/index.js
4.node_modules/a.js
5.node_modules/package.json中main指定的文件
6.node_modules/index.js

相关内容

热门资讯

中国电信人工电话多少 中国电信... 当我们在使用中国移动、中国电信和中国联通提供的电信业务时,可能会发生争议。建议直接向服务提供商投诉,...
埃菲尔铁塔在哪 中国仿建埃菲尔... 2019年4月26日,广西南宁市,街头惊现一座巨型山寨版埃菲尔铁塔,高约20米,白色塔身,造型逼真,...
苗族的传统节日 贵州苗族节日有... 【岜沙苗族芦笙节】岜沙,苗语叫“分送”,距从江县城7.5公里,是世界上最崇拜树木并以树为神的枪手部落...
北京的名胜古迹 北京最著名的景... 北京从元代开始,逐渐走上帝国首都的道路,先是成为大辽朝五大首都之一的南京城,随着金灭辽,金代从海陵王...
应用未安装解决办法 平板应用未... ---IT小技术,每天Get一个小技能!一、前言描述苹果IPad2居然不能安装怎么办?与此IPad不...
脚上的穴位图 脚面经络图对应的... 人体穴位作用图解大全更清晰直观的标注了各个人体穴位的作用,包括头部穴位图、胸部穴位图、背部穴位图、胳...
长白山自助游攻略 吉林长白山游... 昨天介绍了西坡的景点详细请看链接:一个人的旅行,据说能看到长白山天池全凭运气,您的运气如何?今日介绍...
猫咪吃了塑料袋怎么办 猫咪误食... 你知道吗?塑料袋放久了会长猫哦!要说猫咪对塑料袋的喜爱程度完完全全可以媲美纸箱家里只要一有塑料袋的响...
世界上最漂亮的人 世界上最漂亮... 此前在某网上,选出了全球265万颜值姣好的女性。从这些数量庞大的女性群体中,人们投票选出了心目中最美...
埃菲尔铁塔在哪 中国仿建埃菲尔... 2019年4月26日,广西南宁市,街头惊现一座巨型山寨版埃菲尔铁塔,高约20米,白色塔身,造型逼真,...
坐月子十大禁忌 坐月子的风俗禁... 前段时间,伊能静发微博说生两个孩子都40多天没洗澡,每天都用药水擦了擦身体。但也强调了,月子怎么做是...
苗族的传统节日 贵州苗族节日有... 【岜沙苗族芦笙节】岜沙,苗语叫“分送”,距从江县城7.5公里,是世界上最崇拜树木并以树为神的枪手部落...
北京的名胜古迹 北京最著名的景... 北京从元代开始,逐渐走上帝国首都的道路,先是成为大辽朝五大首都之一的南京城,随着金灭辽,金代从海陵王...