zoukankan      html  css  js  c++  java
  • js模块化规范AMD、CMD、CommonJS...

    1. AMD 

    1.1 什么是AMD?

    • AMD 英文名 Asynchronous Module Definition ,中文名 异步模块定义 。这是一个浏览器模块化开发的规范。
    • 由于浏览器环境执行环境的限制,加载js文件相对于服务器端执行环境比较慢,所以采用模块加载的方式,即解释加载依赖的文件时,浏览器不会停止页面渲染或因为加载文件太大而失去响应。
    • AMD不是javascript标准支持的,使用AMD规范进行页面开发需要用到对应的库函数,也就是RequireJS,实际上AMD是RequireJS在推广过程中对模块化定义的规范化的产出。    

    1.2 为什么要用RequireJS

    早期的时候,所有js代码在一个文件中,浏览器只需加载一个文件就够了,后来,一个文件不够了,必须分成多个文件,依次加载。例如以下代码:
    1 <script src="1.js"></script>
    2 <script src="2.js"></script>
    3 <script src="3.js"></script>
    4 <script src="4.js"></script>
    5 <script src="5.js"></script>
    6 <script src="6.js"></script>
    这样写有很大的缺点,首先,浏览器加载js的时候会停止对html的渲染,文件越多,页面卡住时间越长;其次由于js文件的依赖关系,必须保证加载顺序,当依赖关系变得复杂的时候,代码编写和维护变得非常困难。
    RequireJS的诞生,就是为了解决这两个问题
    • 多个js文件可能有依赖关系,被依赖的文件需要早于依赖它的文件加载到浏览器
    • 实现文件异步加载,避免页面失去响应 
        
    1.2.1 RequireJS模块的加载
    1. 在页面底部加载requirejs.js 文件<script src="/js/require.js"></script>
    2. 加载require.js 后,再加载自定义主文件main.js 按如下写法放在步骤1的后面 <script src="js/require.js" data-main="js/main"></script> 。 data-main 属性指定网页主模块文件路径,main.js 简写为main
    3. main.js 中模块定义:
      require(['moduleA', 'moduleB', 'moduleC'], function (moduleA, moduleB, moduleC){
           // some code here
         });

      require()函数接受两个参数。第一个参数是一个数组,表示所依赖的模块,上例就是['moduleA', 'moduleB', 'moduleC'],即主模块依赖这三个模块;第二个参数是一个回调函数,当前面指定的模块都加载成功后,它将被调用。加载的模块会以参数形式传入该函数,从而在回调函数内部就可以使用这些模块。require()异步加载moduleA,moduleB和moduleC,浏览器不会失去响应;它指定的回调函数,只有前面的模块都加载成功后,才会运行,解决了依赖性的问题。一个实际的例子:假定主模块依赖jquery、underscore和backbone这三个模块,main.js就可以这样写:

      require(['jquery', 'underscore', 'backbone'], function ($, _, Backbone){
          // some code here
        });

      require.js会先加载jQuery、underscore和backbone,然后再运行回调函数。主模块的代码就写在回调函数中。

    1.2.2 require.config()

    使用require.config()方法,我们可以对模块的加载行为进行自定义。require.config()就写在主模块(main.js)的头部。参数就是一个对象,这个对象的paths属性指定各个模块的加载路径。
    require.config({
        paths: {
          "jquery": "jquery.min",
          "underscore": "underscore.min",
          "backbone": "backbone.min"
        }
      });

     

    1.3 AMD 规范写法

    模块的定义,必须采用define()函数定义。如果一个模块不依赖其他模块,可以直接定义在define()函数中。

    加载非规范的模块,对于不按define()规范定义的模块,通过require,.config()定义后再导入

    举例来说,underscore和backbone这两个库,都没有采用AMD规范编写。如果要加载它们的话,必须先定义它们的特征。 
    require.config({
        shim: {
          'underscore':{
            exports: '_'
          },
          'backbone': {
            deps: ['underscore', 'jquery'],
            exports: 'Backbone'
          }
        }
      }); 
      
    require.config()接受一个配置对象,这个对象除了有前面说过的paths属性之外,还有一个shim属性,专门用来配置不兼容的模块。具体来说,每个模块要定义(1)exports值(输出的变量名),表明这个模块外部调用时的名称;(2)deps数组,表明该模块的依赖性。 
    比如,jQuery的插件可以这样定义: 
     
     shim: {
        'jquery.scroll': {
          deps: ['jquery'],
          exports: 'jQuery.fn.scroll'
        }
      }

     2. CMD

    2.1 概述

    CMD Common Module Definition 中文名:通用模块定义,也是浏览器端模块定义的规范。
    CMD 是 SeaJS 在推广过程中对模块定义的规范化产出

    2.2 AMD&CMD异同:

    • 对于依赖的模块,AMD 是提前执行,CMD 是延迟执行。不过 RequireJS 从 2.0 开始,也改成可以延迟执行(根据写法不同,处理方式不同)。CMD 推崇 as lazy as possible.
    • CMD 推崇依赖就近,AMD 推崇依赖前置。看代码:
    // CMD
    define(function(require, exports, module) {
    var a = require('./a')
    a.doSomething()
    // 此处略去 100 行
    var b = require('./b') // 依赖可以就近书写
    b.doSomething()
    // ...
    })
    // AMD 默认推荐的是
    define(['./a', './b'], function(a, b) { // 依赖必须一开始就写好
    a.doSomething()
    // 此处略去 100 行
    b.doSomething()
    ...
    })
     

     3.CommonJS

    3.1 概述

    CommonJS 是服务器端模块定义的规范,由Node推广使用,使用方法如下:
    //math.js
    exports.add = function() {
    var sum = 0, i = 0, args = arguments, l = args.length;
    while (i < l) {
    sum += args[i++];
    }
    return sum;
    };
    //increment.js
    var add = require('math').add;
    exports.increment = function(val) {
    return add(val, 1);
    };
     
    //index.js
    var increment = require('increment').increment;
    var a = increment(1); //2

    3.2 CommonJS规范

    • 一个js文件就是一个模块
    • 输出模块变量最好的办法是export
    • 加载模块是require()方法,返回模块的exports对象
     
     

    4. UMD与ES6 Module

      Universal Module Definition 统一模块定义
      ES6 从语法层面对模块化进行了支持,编写方式借鉴了流行的JavaScript模块加载器(AMD, CommonJS)。由宿主环境的默认加载器定义模块运行时的行为,采取隐式异步模式——在模块可以被获取和加载前不会有代码执行。
    // lib/math.js
     export function sum(x, y) { return x + y; } 
    export var pi = 3.141593;
     
     //app.js 
    import * as math from "lib/math"; 
    console.log("2π = " + math.sum(math.pi, math.pi));
    // other App.js 
    import {sum, pi} from "lib/math"; 
    console.log("2π = " + sum(pi, pi));
    //其他功能包括:export default and export *:
    // lib/mathplusplus.js 
    export * from "lib/math"; export var e = 2.71828182846; 
    export default function(x) { return Math.exp(x); }
    // app.js
     import exp, {pi, e} from "lib/mathplusplus";
     console.log("e^π = " + exp(pi));

     以上内容只是只为个人学习总结,部分摘自网络,如有侵权,联系即删。

    参考:
     
     
     
  • 相关阅读:
    jpa @onetomany 级联查询时会有重复数据,去重问题
    jpa/hibernate @onetomany 使用left join 添加多条件,可以使用过滤器filters (with-clause not allowed on fetched associations; use filters异常信息)
    如何使用多数据源,同时使用jpa和jdbctemplate
    mysql中使用enum,如何获取所有可能的值
    jpa返回List<Map<String, Object>>相当于jdbctemplate的queryForlist
    git bash各种乱码问题,已解决
    Kafka学习整理五(Consumer配置)
    创建Kafka0.8.2生产者与消费者
    Kafka消费组(consumer group)
    Kafka学习之四 Kafka常用命令
  • 原文地址:https://www.cnblogs.com/aimigi/p/9072747.html
Copyright © 2011-2022 走看看