AMD && CMD ES6 module

Preface

The original intention of JavaScript : to implement simple page interaction logic, just a few words;

With the advent of the web2.0 era, Ajax technology has been widely used, front-end libraries such as jQuery are emerging in an endless stream, and the front-end code is expanding day by day.

problem:

At this time , the positioning of JavaScript as an embedded scripting language was shaken, but JavaScript did not provide any obvious help for organizing code, even without the concept of classes. JavaScript's extremely simple code organization specifications are not enough to control such a large-scale code.

1. Module

Modularization: It is a way to deal with the decomposition of complex systems into manageable modules with a more reasonable code structure and higher maintainability.

In an ideal state, we only need to complete part of our core business logic code, and other dependencies can be used by directly loading modules that have already been written.

No module

<script src="jquery.js"></script>   
<script src="jquery_scroller.js"></script>   
<script src="main.js"></script>   
<script src="other1.js"></script>   
<script src="other2.js"></script>   
<script src="other3.js"></script>

advantage:

Compared to using one js file, the idea of ​​achieving the simplest modularization with multiple js files is an improvement. 

Disadvantages:

Pollution of the global scope. Because every module is exposed globally, simple use will lead to global variable naming conflicts. Of course, we can also use namespaces to resolve it. For large-scale projects, there are many kinds of js, and developers must manually resolve the dependencies between modules and code libraries, and subsequent maintenance costs are high. The dependency is not obvious, which is not conducive to maintenance. For example, main.js needs to use jquery, but from the above file, we can't see it. If jquery is forgotten, then an error will be reported.

Two, CommonJS

CommonJs  is a specification for server-side modules, and Node.js adopts this specification.

According to the CommonJS specification, a single file is a module . The load module uses the require method, which reads a file and executes it, and finally returns the exports object inside the file.

var math = require('math');
math.add(2, 3);

The second line math.add(2, 3) runs after the first line require('math'), so you must wait for math.js to load. In other words, if the loading time is long, the entire application will stop there and wait. You will notice that it  require is synchronized.

CommonJS loading modules are synchronous , so the subsequent operations can only be performed after the loading is complete . Like Node.js is mainly used for server programming, the loaded module files generally already exist on the local hard disk, so it is faster to load, and there is no need to consider the way of asynchronous loading, so the CommonJS specification is more applicable. But if it is a browser environment, to load the module from the server, this is necessary to adopt the asynchronous mode. So there is the AMD CMD solution.

Three, AMD

AMD stands for Asynchronous Module Definition, and the Chinese name means asynchronous module definition. It is a specification for modular development on the browser side

AMD also uses the require() statement to load modules, but unlike CommonJS, it requires two parameters:

require([module], callback);

The first parameter [module] is an array, and the members in it are the modules to be loaded; the second parameter callback is the callback function after successful loading. If the previous code is rewritten into AMD form, it is as follows:

require(['math'], function (math) {
  math.add(2, 3);
});

math.add() is not synchronized with the math module loading, and the browser will not be suspended. So obviously, AMD is more suitable for the browser environment. Currently, there are two main Javascript library implements the AMD specification: require.js and curl.js .

With RequireJS

AMD is the standardized output of RequireJS's module definition in the promotion process

AMD loads modules asynchronously. Its modules support various types of modules such as object function constructor string JSON.

//通过数组引入依赖 ,回调函数通过形参传入依赖

define(['Module1', ‘Module2’], function (Module1, Module2) {

    function foo () {
        /// someing
        Module1.test();
    }

    return {foo: foo}
});
第一个参数 id 为字符串类型,表示了模块标识,为可选参数。若不存在则模块标识应该默认定义为在加载器中被请求脚本的标识。如果存在,那么模块标识必须为顶层的或者一个绝对的标识。
  • The second parameter, dependencies, is an array literal of the module identifier that the current module depends on and has been defined by the module.
  • The third parameter, factory, is a function or an object that needs to be instantiated.

    Create a module identified as Module1, which depends on require, export, and a module identified as beta  

The AMD specification allows the output module to be compatible with the CommonJS specification. At this time, the define method is as follows:

define(function (require, exports, module) {
    
    var reqModule = require("./someModule");
    requModule.test();
    
    exports.asplode = function () {
        //someing
    }
});
优点:

It is suitable for loading modules asynchronously in the browser environment. Multiple modules can be loaded in parallel. Disadvantages:

Increased development costs, and can not be loaded on demand, but must load all dependencies in advance.

Four, CMD

CMD is the standardized output of SeaJS's module definition in the promotion process

The differences between CMD and AMD are as follows:

1. AMD is executed in advance for dependent modules, and CMD is executed later. However, since RequireJS 2.0, it has also been changed to delay execution (depending on the writing method, the processing method is not passed).

2. AMD respects pre-dependency ( declare the dependent modules when defining a module ), and CMD respects the proximity of dependencies ( require only when a certain module is used-load on demand ).

//AMD
define(['./a','./b'], function (a, b) {

    //依赖一开始就写好
    a.test();
    b.test();
});

//CMD
define(function (requie, exports, module) {
    
    //依赖可以就近书写
    var a = require('./a');
    a.test();
    
    ...
    //软依赖
    if (status) {
    
        var b = requie('./b');
        b.test();
    }
});

3. AMD's api is one for multiple purposes by default, and CMD strictly distinguishes and respects single responsibilities. For example: require in AMD is divided into global and local. There is no global require in CMD, seajs.use() is provided to realize the loading and starting of the module system. Every API in CMD is simple and pure.

AMD is the standardized output of RequireJS's module definition in the promotion process, and CMD is the widely recognized SeaJS in the promotion process. RequireJs comes from James Burke, the author of the dojo loader, and SeaJs comes from the domestic front-end master Yu Bo. The difference between the two, Yu Bo said in 12 years :

Both RequireJS and SeaJS are very good module loaders. The differences between the two are as follows:

1. 两者定位有差异。RequireJS 想成为浏览器端的模块加载器,同时也想成为 Rhino / Node 等环境的模块加载器。SeaJS 则专注于 Web 浏览器端,同时通过 Node 扩展的方式可以很方便跑在 Node 服务器端

2. 两者遵循的标准有差异。RequireJS 遵循的是 AMD(异步模块定义)规范,SeaJS 遵循的是 CMD (通用模块定义)规范。规范的不同,导致了两者API 的不同。SeaJS 更简洁优雅,更贴近 CommonJS Modules/1.1 和 Node Modules 规范。

3. 两者社区理念有差异。RequireJS 在尝试让第三方类库修改自身来支持 RequireJS,目前只有少数社区采纳。SeaJS 不强推,而采用自主封装的方式来“海纳百川”,目前已有较成熟的封装策略。

4. 两者代码质量有差异。RequireJS 是没有明显的 bug,SeaJS 是明显没有 bug。

5. 两者对调试等的支持有差异。SeaJS 通过插件,可以实现 Fiddler 中自动映射的功能,还可以实现自动 combo 等功能,非常方便便捷。RequireJS无这方面的支持。

6. 两者的插件机制有差异。RequireJS 采取的是在源码中预留接口的形式,源码中留有为插件而写的代码。SeaJS 采取的插件机制则与 Node 的方式一致开放自身,让插件开发者可直接访问或修改,从而非常灵活,可以实现各种类型的插件。

Advantages: Modular loading on the browser side is also realized. It can be loaded on demand, and the dependency is nearby.

Disadvantages: relying on SPM packaging, the loading logic of the module is biased.

 Five, ES6 modules

CommonJS

  • For basic data types, it belongs to replication. It will be cached by the module. At the same time, another module can re-assign the variables output by the module.
  • For complex data types, it is a shallow copy. Since the objects referenced by the two modules point to the same memory space, modifying the value of the module will affect the other module.
  • When a module is loaded with the require command, the code of the entire module will be run.
  • When using the require command to load the same module, the module will not be executed again, but the value in the cache will be fetched. In other words, no matter how many times the CommonJS module is loaded, it will only run once when it is loaded for the first time, and when it is loaded later, the result of the first run will be returned, unless the system cache is manually cleared.
  • When cyclic loading, it belongs to the execution during loading. That is, the script code will all be executed when it is required. Once a module is "cyclically loaded", only the part that has been executed will be output, and the part that has not been executed will not be output.

ES6 module

  • The value in the ES6 module belongs to [dynamic read-only reference].
  • For read-only, that is, it is not allowed to modify the value of the imported variable, and the imported variable is read-only, regardless of the basic data type or the complex data type. When a module encounters an import command, it generates a read-only reference. When the script is actually executed, the read-only reference is used to get the value in the loaded module.
  • For dynamics, the original value changes, and the value loaded by import also changes. Whether it is a basic data type or a complex data type.
  • When loading loops, ES6 modules are dynamically referenced. As long as there is a reference between the two modules, the code can be executed.

reference:

About CommonJS AMD CMD UMD

JavaSript Module Specification-Introduction to AMD Specification and CMD Specification

JavaScript modularity --- Commonjs, AMD, CMD, ES6 modules

Guess you like

Origin blog.csdn.net/lianjiuxiao/article/details/114368933