模块化类型
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 导入,这应该是我平时接触的最多的场景了。

最后

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

相关内容

热门资讯

嘉兴银行“新帅”确定:行长王芳... 嘉兴银行“新帅”确定:行长王芳升任党委书记 人民财讯5月19日电,据嘉兴银行消息,嘉兴市委常委、常务...
这届年轻人的置业逻辑变了!报告... 5月18日,58同城、安居客发布《2026青年置业报告》。这份基于数千名20-35岁年轻人的调研,揭...
金融让生活更美好|上银财富“5... 为更好地满足广大客户多元化、多层次的财富保值增值需求,上海银行于5月18日正式启动“518财富理想节...
追觅俞浩回应设立上百个BU:A... 来源:中国企业家 做企业不是开故事会,发展才能解释问题,发展才能解决问题 文|《中国企业家》记者 ...
原创 强... 2026年5月13日,深圳。华为和总资产1.5万亿的中国中化,正式签下一份深化战略合作协议。 一家...
金价,还在跌!警惕骗局—— 5月18日早盘,现货黄金短时下跌,失守4500美元/盎司,为3月底以来首次。 【此前报道:】5月19...
中国电信:选举柯瑞文为董事长;... 据每日经济新闻:5月19日,中国电信(601728.SH)公告称,公司第九届董事会第一次会议选举柯瑞...
2026第六届中国贵州国际能源... 5月18日,2026第六届中国贵州国际能源产业博览交易会(简称“贵州能博会”)在贵阳国际会议展览中心...
华为轮值董事长徐直军访问东风汽... 2026年5月19日,华为轮值董事长徐直军,华为公司高级副总裁、引望公司CEO靳玉志一行到访东风汽车...
20cm股热度渐升!涨停数追平... 财联社5月19日讯(编辑 梓隆),近期,创业板、科创板股热度较高,截至今日(5月19日)收盘,累计共...
原创 告... 1499,这个数字陪了我们好几年。买飞天茅台的人,对它太熟悉了。可就在3月30日晚上,贵州茅台一纸公...
美国30年期国债收益率升至20... 美国30年期国债收益率上升至5.177%,为2007年以来的最高水平。 (本文来自第一财经)
一人掌控2家国产存储龙头,57... 一个老板,左手握着国内芯片设计龙头兆易创新,右手攥着国产DRAM市场第一的长鑫科技,57亿关联交易深...
跟宇树一比,云深处太贵了? 营收仅宇树五分之一,估值倍数贵了约60%。 AIX财经(AIXcaijing)原创 作者|王汉星 编...
华曦达将在港交所上市:业绩波动... 来源|贝多商业&贝多财经 5月18日,深圳市华曦达科技股份有限公司(下称“华曦达”,HK:00901...
微纳星空科创板IPO拟募资50... 上交所&深交所 新 股 上 市 5月12日-5月18日,上交所无公司上市;深交所主板有2家公司上市。...
突发!伊朗股市,重新开市!特朗... 刚刚,伊朗股市恢复交易! 据央视新闻报道,当地时间5月19日,伊朗德黑兰证券交易所恢复股票交易。目前...
龙湖完成“21龙湖04”本息兑... 5月19日,龙湖集团如期完成“21龙湖04”的本金兑付与付息,涉及总金额约15.54亿元,包含本金1...
600759,连续12个跌停 【导读】市场情绪整体不错! 中国基金报记者 泰勒 大家好啊,今天的市场,尽管外围行情似乎风雨飘摇,但...