模块化类型
admin
2024-05-02 10:07:59
0

前端模块化类型

在看 Babel 的时候,里面介绍了四种模块化的插件,AMD、Commonjs、SystemJS、UMD,还有 CMD、EMS 没有涉及,在这里总结一下调查的内容。

目前使用的模块化协议有 AMD、CMD、CommonJS、UMD、SystemJS、ESM

AMD、CMD

AMD(Asynchronous Moudle Definition)异步模块定义;CMD(Common Module Definition)通用模块定义;它们都是一种在浏览器端模块化开发的规范,并没有被JS原生支持。

在使用AMD 规范进行页面开发,需要使用到对应的 RequireJS 库函数,实际上 AMD 也是 RequireJS 在推广过程中对模块定义的规范化的产出。
Require.js 官网 https://requirejs.org/

在使用CMD 规范进行开发,用到的是 SeaJS 库函数,它是国内发展出来的。
Sea.js 官网 https://seajs.github.io/seajs/docs/

看了两个官网样式,都有历史的味道。

Require.js

例子🌰:

// 引入 require.js
// 定义 myModule.js 模块
define(['dependency'], function() {var name = "Byron";function printName() {console.log(name);}return {printName: printName}
});//加载模块
require(['myModule'], function(my) {my.printName();
})

语法:
Require.js 定义全局函数 define 用来定义模块,require 加载模块

define(id?: string, dependencies?: string[], factory: Function)

  • id 定义模块标识符,默认是脚本文件名(去除扩展名)

  • dependencied 当前模块依赖的模块名称数组

  • factory 模块初始化执行的函数或对象,函数之被执行一次,对象是为模块的输出值

require(dependencies: string[], callback: Function)

  • dependencies 依赖的模块

  • callback 回调函数,在指定模块加载完成后被调用

require() 函数在加载以来的函数是异步加载,指定的回调函数,在前面模块都加载完成后才会运行。

Sea.js

例子🌰:

// 引入 Sea.Sea
// 定义模块 myModule.js
define(function(require, exports, module) {var math = require('math');exports.add = function(left, right) {return math.add(left, right);}
});// 加载模块
require(['myModule'], function(my) {console.log(my.add(1, 1));
})

define(id?: string, dependencies?: string[], factory: (require: Function, exports: Object, module: Object) => {})

CMD 推崇的是依赖就近,所以一般不在 define 的参参数写依赖

  • id 定义模块标识符,默认是脚本文件名(去除扩展名)

  • dependencied 当前模块依赖的模块名称数组

factory 回调函数的参数有三个:

  • require 接受模块标识,用来获取其他模块提供的接口

  • exports 用来向外提供模块的对象

  • 存储当前模块信息的对象

AMD 和 CMD 的区别

在浏览器中使用

明显的区别在于模块定义时候依赖的处理方式:

  • AMD 推崇依赖前置,在定义模块的时候就要声明依赖的模块
  • CMD 推崇就近依赖,只有在用到某个模块的时候再通过 require 引入

这种区别只是在语法上的差距。实现库 Require.js 和 Sea.js 都支持对方的写法。

CommonJS

在服务器使用

这个规范在 Node 中被原生支持
协议 https://www.commonjs.org/

协议规范,一个单独的文件就是一个模块,每个模块都是一个单独的作用域。达到的效果就是咋模块内部定义的变量是无法被其他模块读取的,除非是定义为 global 对象的作用域。

通过 exports 和 module.exports 来暴露模块内容
通过 require 来加载模块

例子🌰:

通过 exports 暴露

// 模块定义
var hello = function () {console.log('hello studygd.com.');
}
exports.hello = hello;// 模块加载
const studygd = require('./study');
studygd.hello();

通过 module.exports 暴露

module.exports = {add: function(left, right) {return left + right;},subtract: function(left, right) {return left - right;}
}

UMD

上面已经介绍的协议实现上 AMD、CMD 被限制在浏览器中使用,CommonJS 被限制在服务端使用,两种协议的不同必然带来复用问题,UMD 解决了这个问题。

根据官网介绍,它是使用了 AMD 作为基础,添加了包裹函数来处理 CommonJS 的兼容性。

Github 地址 https://github.com/umdjs/umd

例子🌰:

(function (global, factory) {if (typeof define === "function" && define.amd) {// amddefine(["exports"], factory);} else if (typeof exports !== "undefined") {factory(exports);} else {// commonjsvar mod = {exports: {}};factory(mod.exports);global.test_umd = mod.exports;}
})(typeof globalThis !== "undefined" ? globalThis : typeof self !== "undefined" ? self : this, function (_exports) {"use strict";Object.defineProperty(_exports, "__esModule", {value: true});_exports.default = void 0;var _default = 42;_exports.default = _default;
});

SystemJS

诞生于 2015 年,那时候 ES Module 还没有成熟,已经开始使用 require.js 和 sea.js,system.js 为了做一个通用的模块加载器应运而生。

SystemJS 是目前浏览器(浏览器尚未正式支持 importMap)原生 ES Module 的替代品,把 ES Module 编译成 System.register 格式然后运行在旧版本的浏览器中。

引入模块方式,例子🌰:

// 通过标签引入 moment 和 lodash 模块

// 因为大部分浏览器不支持(也就 chrome 支持) importmap 需引入额外的库做兼容

内部解析,例子🌰:

// ESM 方式
export  default 42;
// Babel 中给出的转换成 SystemJS 协议的产物
System.register([], function(_export, _context) {return {setters: [],execute: function() {_export("default", 42);},};
});

ESM

是 ECMAScript 标准化的模块化协议,目前已经被浏览器和 Node 6+ 中支持

通过 export 导出,import 导入,这应该是我平时接触的最多的场景了。

最后

介绍的内容都是作为粗略了解,大部分还没遇到使用场景,先记一下。

相关内容

热门资讯

春晚,合作上市公司曝光!科技新... 导读:“四十余载春晚路,半部中国商业史。”回顾历届春晚合作伙伴,从八十年代的手表、自行车,到九十年代...
【财经早报】关于AI应用等,华... 重要新闻提示 四部门:加大农村地区企业上市辅导培育力度,帮助更多企业利用多层次资本市场进行融资 市场...
阿里发布新一代基模千问3.5,... 大象新闻记者 李莉 张迪驰 2月16日除夕当天,阿里巴巴开源全新一代大模型千问Qwen3.5-Plu...
原创 德... “一年前,我们还对来自中国的热泵设备将信将疑。现在,我们的订单已经排到半年后了。”一位德国热泵经销商...
春节教养课:五句箴言,让孩子成... 每逢春节,本应温馨的团圆时刻,却常因孩子的行为失当蒙上阴影。知乎上“过年有哪些现象让你感到不悦?”的...
4.2亿关联项目:滨海能源子公... 来源:财中社 2月13日,滨海能源(000695)发布公告,控股子公司邢台旭阳新能源科技有限公司与旭...
逆差暴跌,美元信用要崩?美国人... 美国一直保持着巨大的逆差,而且已经几十年都如此。画一张图如下: 所以美国为什么常年如此?答曰这是与...
平安基金总经理肖宇鹏:持续提升... 一元复始,岁月展新。在马年春节到来之际,我谨代表平安基金恭祝各位投资者和合作伙伴新春快乐,万事顺意!...
原创 非... 联合国秘书长刚喊完话,中国对53个非洲国家的零关税政策就冲上热搜。别以为这只是国际新闻——你家超市的...
视频丨机器人手术与传统手术的对... 专访嘉宾: 刘合利 中南大学湘雅医院胃肠外科主任 医学博士 主任医师 博士研究生导师 Q:机器人手术...
当AI入驻春晚,红包、技术、场... 每经记者:毕媛媛 每经编辑:魏官红 "" 除夕夜,白酒广告还在,手机厂商也没有缺席。但和往年不同,今...
港股除夕交易日人工智能大爆发,... 极目新闻记者 吕少峰 爆竹声中一岁除,春风送暖入屠苏。丙午马年春节的脚步越来越近,港股也迎来了春节前...
除了自嗨锅,其他自热火锅品牌如... 来源:新浪财富汇 随着自嗨锅的破产清算成为行业收缩的缩影,自热火锅市场正经历深度调整,而颐海国际作为...
重阳投资董事长王庆:“四辩”股... 岁序更迭,骏马奔腾。值此丙午马年新春佳节来临之际,我谨代表上海重阳投资管理股份有限公司,向中国基金报...
龙建路桥股份有限公司 关于控股... 本公司董事会及全体董事保证本公告内容不存在任何虚假记载、误导性陈述或者重大遗漏,并对其内容的真实性、...
原创 1... 曾几何时,高耸入云的高层住宅,无论是对于精打细算的开发商,还是追求生活品质的普通居民,都曾是令人心驰...
超级干货!谁在定义黄金的价格 人类最早发现黄金的历史,可以追溯到新石器时代晚期。截至目前,我们花了几千年的时间,总共收集了22万吨...
《求是》杂志编辑部:开局之年经... 开局之年经济工作怎么干 《求是》杂志编辑部 过去的2025年,面对国内外经济环境复杂变化,我国经济顶...
原创 中... 朋友们大家好!今天小界来和大家聊聊关于中国稀土的话题!七国联手发难,剑指中国稀土!美国、日本、英德法...
全线跳水,超11万人爆仓!金银... 加密货币全线跳水,黄金白银又跌了!2月16日,现货黄金、白银盘中再度下探。现货黄金盘中跌超1%,跌破...