本文将从以下三点来做一个详细讲解:
在早期的前端开发中,并没有模块的概念,模块只在服务端存在,用于处理复杂的业务通信等。 直到 AJAX 被提出,前端能够像后端请求数据,前端逻辑越来越复杂,就出现了许多问题:全局变量,函数名冲突,依赖关系不好处理... 随着业务逻辑的增加,对模块需求越来越大,所以才有了后续一系列 AMD、commonJS、ES6Module 规范。
两种解决方法:
下面一个简单的例子
// 新闻板块 let newMOdel = (function(){ let time = new Date() const query = function query() {} const handle = function handel() {} return { query, handle } }()) // 皮肤板块 let skinModel = (function() { let time = ‘2021-07-05‘ const hanle = function handel(){ } newMOdel.query() }())
最早期的模块编程思想就是这种 “高级单例设计模式”「闭包+对象」的组合 模块块化编程思想:就是各个板块/模块 /功能 拼接成一起的东西 ,提出公共的模块。
带来的好处?
公用&复用性、提供开发效率、方便管理、团队协作开发 ; 问题:需要自己构建、根据模块间的依赖关系,需要明确导出顺序。 所以就产生了一些其他的模块化规范。
AMD 即 Asynchronous Module Definition:异步模块加载,代表 require.js
RequireJS是一个遵守AMD规范的工具库,用于客户端的模块管理。它通过 define 方法,将代码定义为模块;通过 require 方法,实现代码的模块加载,使用时需要下载和导入项
文件目录
├── AMD
├── moduleA.js
├── moduleB.js
├── main.js
└── require.min.js
简单实现一个require.js
let factories = {} function define(moduleName,factory) { factories[moduleName] = factory } function require(modules,callback) { modules = modules.map(function(item){ let factory = factories[item]; // 定义好每一个 然后把它执行 return factory() // 执行之后返回的东西 放到modules }); callback(...modules) // 然后回掉函数执行这些modules } /**使用AMD */ define(‘moduleA‘, function() { return { fn() { console.log(‘moduleA‘) } } }); define(‘moduleB‘, function() { return { fn() { console.log(‘moduleB‘) } } }); require([‘moduleB‘,‘moduleA‘],function(moduleB,moduleA) { moduleB.fn() moduleA.fn() })
CMD即 Common Module Definition : 通用模块加载。
CMD(Sea.js )& CommonJs规范(Node.js)。
问题:CommonJs只能在 node 环境下支持,客户端/浏览器不支持 CommonJS 规范
那如何让浏览器支持CommonJs规范? 所以有了 Sea.js ,也就产生了CMD规范(Sea.js 就是Commonjs规范直接搬到浏览器上 )
AMD 是 RequireJS 在推广过程中对模块定义的规范化产出 CMD是SeaJS在推广过程中对模块化定义的规范化产出
区别:
ModuleA.js
const sum = function sum(...args){ let len = args.length let firstItem = args[0] if(len === 0) return 0; if(len === 1) return firstItem; return args.reduce((total,item) => { return total + item }) } export default { sum }
moduleB.js
import A from ‘./a.js‘ const average = function average(...args) { let len = args.length let firstItem = args[0] if(len === 0) return 0; if(len === 1) return firstItem; return (A.sum(...args) / args.length).toFixed(2) } export default { average }
main.js
import A from ‘./a.js‘ import B from ‘./b.js‘ console.log(A.sum(1,2,3)) console.log(B.average(1,2,3))
index.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <script type="module" src="./main.js"></script> </body> </html>
注意:
ES6 在语言标准的层面上,实现了模块功能,而且实现得相当简单,完全可以取代 CommonJS 和 AMD 规范,成为浏览器和服务器通用的模块解决方案。
特点:webpack 支持、浏览器也支持.
第二个差异是因为 CommonJS 加载的是一个对象(即module.exports属性),该对象只有在脚本运行完才会生成。而 ES6 模块不是对象,它的对外接口只是一种静态定义,在代码静态解析阶段就会生成。
原文:https://www.cnblogs.com/imMeya/p/15011834.html