JS模块化规范

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JS模块化规范相关的知识,希望对你有一定的参考价值。

参考技术A 我们在开发及接触新技术的时候,总会接触到该技术以何种规范编写,为了更加系统了解这些规范,本文总结了AMD,CMD,CommonJs,UMD,ESM几种规范,供大家学习了解。

AMD 是 RequireJS 在推⼴过程中对 模块定义的规范化 产出,它是⼀个概念,RequireJS是对这个概念的实现,就好⽐javascript语⾔是对ECMAScript规范的实现。AMD是⼀个组织,RequireJS是在这个组织下⾃定义的⼀套脚本语⾔

RequireJS:是⼀个AMD框架,可以异步加载JS⽂件,按照模块加载⽅法,通过define()函数定义。第⼀个参数是⼀个数组,⾥⾯定义⼀些需要依赖的包,第⼆个参数是⼀个回调函数,通过变量来引⽤模块⾥⾯的⽅法,最后通过return来输出()。

是⼀个 依赖前置 、 异步定义 的AMD框架(在参数⾥⾯引⼊js⽂件),在定义的同时如果需要⽤到别的模块,在最前⾯定义好即在参数数组⾥⾯进⾏引⼊,在回调⾥⾯加载

AMD 定义了一套 JavaScript 模块依赖异步加载标准,来解决同步加载的问题。模块通过 define 函数定义在闭包中,格式如下:
define(id?: String, dependencies?: String[], factory: Function|Object);

一些栗子:

注意:在 webpack 中,模块名只有局部作用域,在 Require.js 中模块名是全局作用域,可以在全局引用。

定义一个没有 id 值的匿名模块,通常作为应用的启动函数:

依赖多个模块的定义:

模块输出:

在模块定义内部引用依赖:

SeaJS 在推⼴过程中对模块定义的规范化产出,是⼀个同步模块定义,是SeaJS的⼀个标准,SeaJS是CMD概念的⼀个实现,SeaJS是淘宝团队提供的⼀个模块开发的js框架.

通过define()定义, 没有依赖前置 ,通过require加载模块,CMD是 依赖就近 ,在什么地⽅使⽤到模块就在什么地⽅require该模块,即⽤即返,这是⼀个 同步 的概念

在前端浏览器⾥⾯并不⽀持module.exports,CommonJS 是以在浏览器环境之外构建 JavaScript 生态系统为目标而产生的项目,比如在服务器和桌面环境中。

Nodejs端是使⽤CommonJS规范的,前端浏览器⼀般使⽤AMD、CMD、ES6等定义模块化开发的。输出⽅式有2种:默认输出module export 和带有名字的输出exports.area

CommonJS 规范是为了解决 JavaScript 的作用域问题而定义的模块形式,可以使每个模块它自身的命名空间中执行。该规范的主要内容是,模块必须通过 module.exports 导出对外的变量或接口,通过 require() 来导入其他模块的输出到当前模块作用域中。

兼容AMD和commonJS规范的同时,还兼容全局引⽤的⽅式

js模块规范

 1 //CommonJS模块规范,
 2 //每个模块存在着require、exports、module 这3个变量,nodejs对获取的js文件内容进行了头尾包装    
 3 (function (exports, require, module, __filename, __dirname) { 
 4   var math = require(‘math‘); 
 5   exports.area = function (radius) { 
 6     return Math.PI * radius * radius; 
 7   }; 
 8 }); 
 9  
10 //AMD(Asynchronous Module Definition)规范是CommonJS规范延伸,
11 //https://github.com/amdjs/amdjs-api/wiki/AMD
12 //模块定义如下define(id?, dependencies?, factory); 它的模块id和依赖是可选的,
13 //第一个参数 id 为字符串类型,表示了模块标识,为可选参数。若不存在则模块标识应该默认定义为在加载器中被请求脚本的标识。如果存在,那么模块标识必须为顶层的或者一个绝对的标识。
14 //第二个参数,dependencies ,是一个当前模块依赖的,已被模块定义的模块标识的数组字面量。
15 //第三个参数,factory,是一个需要进行实例化的函数或者一个对象。
16  
17 //创建模块标识为 alpha 的模块,依赖于 require, export,和标识为 beta 的模块  
18 define("alpha", [ "require", "exports", "beta" ], function( require, exports, beta ){
19     export.verb = function(){
20         return beta.verb();
21         // or:
22         return require("beta").verb();
23     }
24 });
25 
26 //一个返回对象字面量的异步模块
27 define(["alpha"], function( alpha ){
28     return {
29         verb : function(){
30             return alpha.verb() + 1 ;
31         }
32     }
33 });
34  
35 //无依赖模块可以直接使用对象字面量来定义
36 define( {
37     add : function( x, y ){
38         return x + y ;
39     }
40 } );
41  
42 //类似与 CommonJS 方式定义
43 define( function( require, exports, module){
44     var a = require(‘a‘),
45          b = require(‘b‘);
46  
47     exports.action = function(){};
48 } );
49  
50 define(function() { 
51   var exports = {}; 
52   exports.sayHello = function() { 
53     alert(‘Hello from module: ‘ + module.id); 
54   }; 
55   return exports; 
56 });  
57  
58 define([‘dep1‘, ‘dep2‘], function (dep1, dep2) { 
59   return function () {}; 
60 }); 
61  
62  
63 //CMD(Common Module Definition)规范
64 define(function(require, exports, module) { 
65   // The module code goes here 
66 }); 
67  
68 兼容多种模块规范
69  ;(function (name, definition) { 
70   // 检测上下文环境是否为AMD或CMD 
71   var hasDefine = typeof define === ‘function‘, 
72     //  检查上下文环境是否为Node 
73     hasExports = typeof module !== ‘undefined‘ && module.exports; 
74  
75   if (hasDefine) { 
76     //  AMD环境或CMD环境 
77     define(definition); 
78   } else if (hasExports) { 
79     //  定义为Node模块 
80     module.exports = definition(); 
81   } else { 
82     //  将模块的执行结果挂在window变量中,在浏览器中this指向window 对象 
83     this[name] = definition(); 
84   } 
85 })(‘hello‘, function () { 
86   var hello = function () {}; 
87   return hello; 
88 }); 

 

以上是关于JS模块化规范的主要内容,如果未能解决你的问题,请参考以下文章

js模块化规范—AMD规范

js模块化规范

Sea.js学习3——Sea.js的CMD 模块定义规范

node.js 的模块化开发规范

CMD (sea.js)模块定义规范

JS模块化编程---按照AMD规范扩展全局对象