前端工程师必备:前端的模块化

JS模块化

模块化的明白

  • 什么是模块?

    • 将一个庞杂的递次依据肯定的划定规矩(范例)封装成几个块(文件), 并举行组合在一同;
    • 块的内部数据/完成是私有的, 只是向外部暴露一些接口(要领)与外部别的模块通讯;
  • 一个模块的构成

    • 数据—>内部的属性;
    • 操纵数据的行动—>内部的函数;
  • 模块化是指处置惩罚一个庞杂的题目时自顶向下把体系划分红多少模块的进程,有多种属性,离别反应其内部特性;
  • 模块化编码:编码时是依据模块一个一个编码的, 悉数项目就是一个模块化的项目;

非模块化的题目

  • 页面加载多个js的题目:
<script type="text/javascript" src="module1.js"></script>
<script type="text/javascript" src="module2.js"></script>
<script type="text/javascript" src="module3.js"></script>
<script type="text/javascript" src="module4.js"></script>
  • 发作题目:

    • 难以保护 ;
    • 依靠隐约;
    • 请求过量;
  • 所以,这些题目可以经由过程当代模块化编码和项目构建来处置惩罚;

模块化的长处

  • 更好地星散:防止一个页面中安排多个script标签,而只需加载一个须要的团体模块即可,如许关于HTML和JavaScript星散很有优点;
  • 更好的代码构造体式格局:有利于后期更好的保护代码;
  • 按需加载:进步运用性能,和下载速率,按需求加载须要的模块
  • 防止定名争执:JavaScript自身是没有定名空间,常常会有定名争执,模块化就可以使模块内的任何情势的定名都不会再和其他模块有争执。
  • 更好的依靠处置惩罚:运用模块化,只须要在模块内部说明好依靠的就行,增添删除都直接修正模块即可,在挪用的时刻也不必管该模块依靠了哪些其他模块。

模块化的生长进程

原始写法

  • 只是把差别的函数简朴地放在一同,就算一个模块;
function fun1(){
  //...
}
function fun2(){
  //...
}
//上面的函数fun1,fun2构成了一个模块,运用的时刻直接挪用某个函数就好了。
  • 瑕玷:

    • “污染”了全局变量,没法保证不与其他模块发作变量名争执;
    • 模块成员之间看不出直接关联。

对象写法

  • 为了处置惩罚污染全局变量的题目,可以把模块写成一个对象,一切的模块成员都放到这个对象内里。
 var module1 = new Object({
    count : 0,
    fun1 : function (){
     //...
    },
  fun2 : function (){
     //...
   }
 });
 //这个内里的fun1和fun2都封装在一个赌侠宁里,可以经由过程对象.要领的情势举行挪用;
 module1.fun1();
  • 长处:

    • 减少了全局上的变量数量;
  • 瑕玷:

    • 实质是对象,而这个对象会暴露一切模块成员,内部状况可以被外部改写。

马上实行函数(IIFE形式)

  • 防止暴露私有成员,所以运用马上实行函数(自调函数,IIFE);
  • 作用: 数据是私有的, 外部只能经由过程暴露的要领操纵
var module1 = (function(){
    var count = 0;
    var fun1 = function(){
        //...
    }
    var fun2 = function(){
        //...
    }
    //将想要暴露的内容安排到一个对象中,经由过程return返回到全局作用域。
    return{
        fun1:fun1,
        fun2:fun2
    }
})()
//如许的话只能在全局作用域中读到fun1和fun2,然则读不到变量count,也修正不了了。
//题目:当前这个模块依靠另一个模块怎么办?

IIFE的加强(引入依靠)

  • 假如一个模块很大,必需分红几个部份,或许一个模块须要继续另一个模块,这时候就有必要采纳”加强形式”;
  • IIFE形式加强:引入依靠;
  • 这就是当代模块完成的基石;
var module1 = (function (mod){
  mod.fun3 = function () {
   //...
    };
    return mod;
})(module1);
//为module1模块增加了一个新要领fun3(),然后返回新的module1模块。

//引入jquery到项目中;
var Module = (function($){
    var _$body = $("body");     // we can use jQuery now!
    var foo = function(){
    console.log(_$body);    // 特权要领
    }
  // Revelation Pattern
      return {
          foo: foo
      }
})(jQuery)
Module.foo();

js模块化须要处置惩罚那些题目:

  • 1.怎样平安的包装一个模块的代码?(不污染模块外的任何代码)
  • 2.怎样唯一标识一个模块?
  • 3.怎样文雅的把模块的API暴漏出去?(不能增添全局变量)
  • 4.怎样轻易的运用所依靠的模块?

模块化范例

  • Node: 服务器端
  • Browserify : 浏览器端

CommonJS:服务器端

  • 概述

    • Node 运用由模块构成,采纳 CommonJS 模块范例。
    • CommonJS范例划定,每一个模块内部,module变量代表当前模块。这个变量是一个对象,它的exports属性(即module.exports)是对外的接口。加载某个模块,实际上是加载该模块的module.exports属性。
  • 特性

    • 一切代码都运转在模块作用域,不会污染全局作用域。
    • 模块可以屡次加载,然则只会在第一次加载时运转一次,然后运转效果就被缓存了,今后再加载,就直接读取缓存效果。要想让模块再次运转,必需消灭缓存。
    • 模块加载的递次,依据其在代码中涌现的递次。
  • 基本语法:

    • 定义暴露模块 : exports
    exports.xxx = value
    // 经由过程module.exports指定暴露的对象value
    module.exports = value
    • 引入模块 : require
    var module = require('模块相对途径')
  • 引入模块发作在什么时刻?

    • Node:运转时, 动态同步引入;
    • Browserify:在运转前对模块举行编译/转译/打包的处置惩罚(已将依靠的模块包括进来了), 运转的是打包天生的js, 运转时不须要再从长途引入依靠模块;

CommonJS通用的模块范例(同步)

  • Node内部供应一个Module构建函数。一切模块都是Module的实例。
  • 每一个模块内部,都有一个module对象,代表当前模块。
  • module.exports属性示意当前模块对外输出的接口,其他文件加载该模块,实际上就是读取module.exports变量。
  • Node为每一个模块供应一个exports变量,指向module.exports。
  • 假如一个模块的对外接口,就是一个单一的值,不能运用exports输出,只能运用module.exports输出。
  • Modules/1.0范例包括内容:

    1. 模块的标识应遵照的划定规矩(誊写范例)
    2. 定义全局函数require,经由过程传入模块标识来引入其他模块,实行的效果即为模块暴露出来的API;
    3. 假如被require函数引入的模块中也包括依靠,那末顺次加载这些依靠;
    4. 假如引入模块失利,那末require函数应该报一个非常;
    5. 模块经由过程变量exports来向外暴露API,exports赋值暴露的只能是一个对象exports = {Obj},暴露的API须作为此对象的属性。exports实质是引入了module.exports的对象。不能直接将exports变量指向一个值,因为如许即是切断了exports与module.exports的联络。
    6. 假如暴露的不是变量exports,而是module.exports。module变量代表当前模块,这个变量是一个对象,它的exports属性(即module.exports)是对外的接口。加载某个模块,实际上是加载该模块的module.exports属性。exports=module.exports={Obj}
node中的commonJS教程
  • 1.装置node.js;
  • 2.建立项目构造
//构造以下
|-modules
    |-module1.js//待引入模块1
    |-module2.js//待引入模块2
    |-module3.js//待引入模块3
|-app.js//主模块
|-package.json
    {
      "name": "commonjsnode",
      "version": "1.0.0"
    }
  • 3.下载第三方模块:举例express

    npm i express --save
  • 4.模块化编码
// module1 
// 运用module.exports = value向外暴露一个对象
module.exports = {
    name: 'this is module1',
    foo(){
        console.log('module1 foo()');
    }
}
// module2 
// 运用module.exports = value向外暴露一个函数 
module.exports = function () {
    console.log('module2()');
}
// module3 
// 运用exports.xxx = value向外暴露一个对象
 exports.foo = function () {
     console.log('module3 foo()');
 };
 exports.bar = function () {
     console.log('module3 bar()');
 };
 exports.name = 'this is module3'

//app.js文件
var uniq = require('uniq');
//援用模块
let module1 = require('./modules/module1');
let module2 = require('./modules/module2');
let module3 = require('./modules/module3');
//运用模块
module1.foo();
module2();
module3.foo();
module3.bar();
module3.name;
  • 5.经由过程node运转app.js

    • 敕令:node.app.js
    • 东西:右键–>运转
浏览器中的commonJS教程
  • 借助Browserify
  • 步骤

    1. 建立项目构造
    |-js
         |-dist //打包天生文件的目次
         |-src //源码地点的目次
               |-module1.js
               |-module2.js
               |-module3.js
               |-app.js //运用主源文件
    |-index.html //浏览器上的页面
    |-package.json
        {
           "name": "browserify-test",
           "version": "1.0.0"
        }
    1. 下载browserify

      • 全局: npm install browserify -g
      • 部分: npm install browserify –save-dev
    2. 定义模块代码:index.html文件要运转在浏览器上,须要借助browserify将app.js文件打包编译,假如直接在index.html引入app.js就会报错。
    3. 打包处置惩罚js:根目次下运转browserify js/src/app.js -o js/dist/bundle.js
    4. 页面运用引入:
    <script type="text/javascript" src="js/dist/bundle.js"></script> 

AMD : 浏览器端

  • CommonJS范例加载模块是同步的,也就是说,只要加载完成,才实行背面的操纵。
  • AMD范例则是非同步加载模块,许可指定回调函数,可以完成异步加载依靠模块,并且会提早加载;
  • 因为Node.js重要用于服务器编程,模块文件平常都已存在于当地硬盘,所以加载起来比较快,不必斟酌非同步加载的体式格局,所以CommonJS范例比较实用。
  • 假如是浏览器环境,要从服务器端加载模块,这时候就必需采纳非同步形式,因而浏览器端平常采纳AMD范例。

语法

AMD范例基本语法
  • 定义暴露模块: define([依靠模块名], function(){return 模块对象})
  • 引入模块: require(['模块1', '模块2', '模块3'], function(m1, m2){//运用模块对象})
兼容CommonJS范例的输出模块
define(function (require, exports, module) { 
    var reqModule = require("./someModule");
    requModule.test();
    exports.asplode = function () {
        //someing
    }
}); 

AMD:异步模块定义范例(预加载)

  • AMD范例:https://github.com/amdjs/amdj…
  • AMD是”Asynchronous Module Definition”的缩写,意义就是”异步模块定义”。
  • 它采纳异步体式格局加载模块,模块的加载不影响它背面语句的运转。一切依靠这个模块的语句,都定义在一个回调函数中,比及加载完成以后,这个回调函数才会运转。
  • AMD也采纳require()语句加载模块,然则差别于CommonJS,它请求两个参数:

    require([module], callback);
    • 第一个参数[module],是一个数组,内里的成员就是要加载的模块;
    • 第二个参数callback,则是加载胜利以后的回调函数。
  • 现在,重要有两个Javascript库完成了AMD范例:RequireJS和curl.js。

RequireJS

  • 长处

    • 完成js文件的异步加载,防止网页落空相应;
    • 治理模块之间的依靠性,便于代码的编写和保护。
require.js运用教程
  1. 下载require.js, 并引入

  2. 建立项目构造
|-js
  |-libs
    |-require.js // 引入的require.js
  |-modules
    |-alerter.js
    |-dataService.js
  |-main.js
|-index.html
  1. 定义require.js的模块代码

    • require.js加载的模块,采纳AMD范例。也就是说,模块必需依据AMD的划定来写。
    • 详细来说,就是模块必需采纳特定的define()函数来定义;

      • 假如一个模块不依靠其他模块,那末可以直接定义在define()函数当中。
define(['myLib'], function(myLib){
  function foo(){
    myLib.doSomething();
  }
  // 暴露模块
  return {foo : foo};
});
//当require()函数加载上面这个模块的时刻,就会先加载myLib.js文件。
    - 假如这个模块还依靠其他模块,那末define()函数的第一个参数,必需是一个数组,指明该模块的依靠性;

    ```
    // dataService.js
    define(function () {
      let msg = 'this is dataService'
      function getMsg() {
        return msg.toUpperCase()
      }
      return {getMsg}
    })
    
    // alerter.js
    define(['dataService', 'jquery'], function (dataService, $) {
      let name = 'Tom2'
      function showMsg() {
        $('body').css('background', 'gray')
        alert(dataService.getMsg() + ', ' + name)
      }
      return {showMsg}
    })
    ```
  1. 运用主(进口)js: main.js

    • 运用require.config()要领,我们可以对模块的加载行动举行自定义。require.config()就写在主模块main.js的头部,参数就是一个对象,这个对象的paths属性指定各个模块的加载途径。
     (function () {
        //设置
        require.config({
          //基本途径
          baseUrl: "js/",
          //模块标识名与模块途径映照
          paths: {
            "alerter": "modules/alerter",//此处不能写成alerter.js,会报错
            "dataService": "modules/dataService",
          }
        })
        
        //引入运用模块
        require( ['alerter'], function(alerter) {
          alerter.showMsg()
        })
      })()
  2. 页面运用模块:
<script data-main="js/main" src="js/libs/require.js"></script>
定义模块
  • require.config()吸收一个设置对象,这个对象除了有前面说过的paths属性以外,另有一个shim属性,特地用来设置不兼容的模块。
  • 详细来说,每一个模块要定义:

    • 1、exports值(输出的变量名),表明这个模块外部挪用时的称号;
    • 2、deps数组,表明该模块的依靠性。
  • 支撑的设置项:

    • baseUrl :一切模块的查找根途径。

      • 当加载纯.js文件(依靠字串以/开首,或许以.js末端,或许含有协定),不会运用baseUrl。
      • 如未显式设置baseUrl,则默许值是加载require.js的HTML所处的位置。假如用了data-main属性,则该途径就变成baseUrl。
      • baseUrl可跟require.js页面处于差别的域下,RequireJS剧本的加载是跨域的。唯一的限定是运用text! plugins加载文本内容时,这些途径应跟页面同域,至少在开辟时应如许。优化东西会将text! plugin资本内联,因而在运用优化东西以后你可以运用跨域援用text! plugin资本的那些资本。
    • paths:path映照那些不直接安排于baseUrl下的模块名。

      • 设置path时肇端位置是相关于baseUrl的,除非该path设置以”/”开首或含有URL协定(如http:)。
      • 用于模块名的path不该含有.js后缀,因为一个path有可以映照到一个目次。途径剖析机制会自动在映照模块名到path时增加上.js后缀。在文本模版之类的场景中运用require.toUrl()时它也会增加适宜的后缀。
      • 在浏览器中运转时,可指定途径的备选(fallbacks),以完成诸如起首指定了从CDN中加载,一旦CDN加载失利则从当地位置中加载这类的机制;
    • shim: 为那些没有运用define()来声明依靠关联、设置模块的”浏览器全局变量注入”型剧本做依靠和导出设置。
运用第三方基于require.js的框架(jquery)
  • 将jquery的库文件导入到项目: js/libs/jquery-1.10.1.js
  • 在main.js中设置jquery途径
paths: {
   'jquery': 'libs/jquery-1.10.1'
}
  • 在alerter.js中运用jquery
define(['dataService', 'jquery'], function (dataService, \$) {
     var name = 'xfzhang'
     function showMsg() {
         $('body').css({background : 'red'})
         alert(name + ' '+dataService.getMsg())
     }
     return {showMsg}
 })
运用第三方不基于require.js的框架(angular)
  • 将angular.js导入项目:js/libs/angular.js

    • 盛行的函数库(比方jQuery)相符AMD范例,更多的库并不相符。如许的模块在用require()加载之前,要先用require.config()要领,定义它们的一些特性。
// main.js中设置
(function () {
 //设置
 require.config({
   //基本途径
   baseUrl: "js/",
   //模块标识名与模块途径映照
   paths: {
     //第三方库作为模块
     'jquery' : './libs/jquery-1.10.1',
     'angular' : './libs/angular',
     //自定义模块
     "alerter": "./modules/alerter",
     "dataService": "./modules/dataService"
   },
   /*
    设置不兼容AMD的模块
    exports : 指定与相对应的模块名对应的模块对象
    */
   shim: {
     'angular' : {
       exports : 'angular'
     }
   }
 })
 //引入运用模块
 require( ['alerter', 'angular'], function(alerter, angular) {
     alerter.showMsg()
     console.log(angular);
 })
})()

CMD : 浏览器端

  • CMD范例:https://github.com/seajs/seaj…
  • CMD范例特地用于浏览器端,模块的加载是异步的,模块运用时才会加载实行。
  • CMD范例整合了CommonJS和AMD范例的特性。
  • 在 Sea.js 中,一切 JavaScript 模块都遵照 CMD模块定义范例
  • 基本语法

    • 定义暴露模块:

      // 没有依靠的模块
      define(function(require, module, exports){
         let value = 'xxx';
         //经由过程require引入依靠模块
         //经由过程module.exports/exports来暴露模块
         exports.xxx = value
         module.exports = value
      })
      // 有依靠的模块
      define(function(require, exports, module){
         //引入依靠模块(同步)
         var module2 = require('./module2')
         //引入依靠模块(异步)
         require.async('./module3', function (m3) {
             ......
         })
         //暴露模块
         exports.xxx = value
      })
    • 运用模块seajs.use([‘模块1’, ‘模块2’])

sea.js简朴运用教程

  1. 下载sea.js, 并引入

    define()
    exports
    module.exports
    • 怎样依靠模块:require()
    • 怎样运用模块: seajs.use()
  2. 建立项目构造
|-js
  |-libs
    |-sea.js
  |-modules
    |-module1.js
    |-module2.js
    |-module3.js
    |-module4.js
    |-main.js
|-index.html
  1. 定义sea.js的模块代码

    • module1.js

      define(function (require, exports, module) {
        //内部变量数据
        var data = 'this is module1'
        //内部函数
        function show() {
          console.log('module1 show() ' + data)
        }
        //向外暴露
        exports.show = show
      })
    • module2.js

      define(function (require, exports, module) {
        module.exports = {
          msg: 'I Will Back'
        }
      })
    • module3.js

      define(function (require, exports, module) {
       const API_KEY = 'abc123'
       exports.API_KEY = API_KEY
      })
    • module4.js

      define(function (require, exports, module) {
       //引入依靠模块(同步)
       var module2 = require('./module2');
       function show() {
         console.log('module4 show() ' + module2.msg)
       }
       exports.show = show
       //引入依靠模块(异步)
       require.async('./module3', function (m3) {
         console.log('异步引入依靠模块3  ' + m3.API_KEY)
       })
      })
    • main.js : 主(进口)模块
define(function (require) {
  var m1 = require('./module1')
  var m4 = require('./module4')
  m1.show()
  m4.show()
})
  1. index.html:
<script type="text/javascript" src="js/libs/sea.js"></script>
<script type="text/javascript">
  seajs.use('./js/modules/main')
</script>

ES6模块化

  • 模块化的范例:CommonJS和AMD两种。前者用于服务器,后者用于浏览器。
  • 而ES6 中供应了简朴的模块体系,完全可以庖代现有的CommonJS和AMD范例,成为浏览器和服务器通用的模块处置惩罚计划。
  • ES6 模块的设想头脑,是只管的静态化,使得编译时就可以肯定模块的依靠关联,以及输入和输出的变量。CommonJS 和 AMD 模块,都只能在运转时肯定这些东西。

基本用法

  • es6 中新增了两个敕令 export 和 import ;

    • export 敕令用于划定模块的对外接口;
    • import 敕令用于输入其他模块供应的功用。
    • 一个模块就是一个自力的文件。该文件内部的一切变量,外部没法猎取。
    • 假如你愿望外部可以读取模块内部的某个变量,就必需运用export关键字输出该变量。
    • 下面是一个JS文件,内里运用export敕令输出变量。
    // math.js
    export const add = function (a, b) {
        return a + b
    }
    export const subtract = function (a, b) {
        return a - b
    }
    • 运用export敕令定义了模块的对外接口今后,其他JS文件就可以够经由过程import敕令加载这个模块(文件)。
    // main.js
    import { add, subtract } from './math.js'
    add(1, 2)
    substract(3, 2)
  • 定义暴露模块 : export

    • 暴露一个对象:

      • 默许暴露,暴露恣意数据类型,暴露什么数据类型,吸收什么数据类型
      export default 对象
    • 暴露多个:

      • 通例暴露,暴露的实质是对象,吸收的时刻只能以对象的解构赋值的体式格局来吸收值
      export var xxx = value1
      export let yyy = value2
      // 暴露一个对象
      var xxx = value1
      let yyy = value2
      export {xxx, yyy}
  • 引入运用模块 : import

    • default模块:
    import xxx  from '模块途径/模块名'
    • 别的模块
    import {xxx, yyy} from '模块途径/模块名'
    import * as module1 from '模块途径/模块名'

export 细致用法

  • export不止可以导出函数,还可以导出,对象、类、字符串等等;
  • 暴露多个:

    1. 离别暴露
    export const obj = {test1: ''}
    export const test = ''
    export class Test {
       constuctor() {
       }
    }
    // 或许,直接在暴露的处所定义导出函数或许变量
    export let foo = ()=>{console.log('fnFoo');return "foo"},bar="stringBar"
    1. 一同暴露,引荐运用这类写法,如许可以写在剧本尾部,一眼就看清晰输出了哪些变量。
    let a=1
    let b=2
    let c=3
    export { a,b,c }
    1. 还可以经由过程as转变输出称号
    // test.js
    let a = 1
    let b = 2
    let c = 3
    export {
        a as test,
        b,
        c
    };
    import { test, b, c } from './test.js' // 转变定名后只能写 as 后的定名
    1. 经由过程通配符暴露其他引入的模块
    // test.js
    let a = 1
    let b = 2
    let c = 3
    export {
        a as test,
        b,
        c
    };
    // lib.js引入test.js的内容
    export * from './test.js'
    // 引入
    import {test,b,c} from './lib.js'
  • 暴露一个对象,默许暴露

    • export default指定默许输出,import无需晓得变量名就可以够直接运用
    // test.js
    export default function () {
        console.log('hello world')
    }
    //引入
    import say from './test.js' // 这里可以指定恣意变量名
    say() // hello world
    • 经常使用的模块
    import $ from 'jQuery'   // 加载jQuery 库
    import _ from 'lodash'   // 加载 lodash
    import moment from 'moment' // 加载 moment

import细致用法

  • import 为加载模块的敕令,基本运用体式格局和之前一样
// main.js
import { add, subtract } from './test'

// 关于export default 导出的
import say from './test'
  • 经由过程 as 敕令修正导入的变量名
import {add as sum, subtract} from './test'
sum (1, 2)
  • 加载模块的悉数,除了指定输出变量名或许 export.default 定义的导入, 还可以经由过程 * 号加载模块的悉数。
// math.js
export const add = function (a, b) {
    return a + b
}
export const subtract = function (a, b) {
    return a - b
}

//引入
import * as math from './test.js'
math.add(1, 2)
math.subtract(1, 2)

ES6-Babel-Browserify运用教程

  • 题目: 一切浏览器还不能直接辨认ES6模块化的语法
  • 处置惩罚:

    • 运用Babel将ES6—>ES5(运用了CommonJS) —-浏览器还不能直接实行;
    • 运用Browserify—>打包处置惩罚js—-浏览器可以运转
  1. 定义package.json文件
{
  "name" : "es6-babel-browserify",
  "version" : "1.0.0"
}
  1. 装置babel-cli, babel-preset-es2015和browserify
npm install babel-cli browserify -g
npm install babel-preset-es2015 --save-dev 
  1. 定义.babelrc文件,这是一个babel的设置文件
{
   "presets": ["es2015"]
 }
  1. 编码
// js/src/module1.js
export function foo() {
     console.log('module1 foo()');
};
export let bar = function () {
     console.log('module1 bar()');
};
export const DATA_ARR = [1, 3, 5, 1];

// js/src/module2.js
let data = 'module2 data'; 
function fun1() {
    console.log('module2 fun1() ' + data);
};
function fun2() {
    console.log('module2 fun2() ' + data);
};
export {fun1, fun2};

// js/src/module3.js
export default {
  name: 'Tom',
  setName: function (name) {
    this.name = name
  }
}

// js/src/app.js
import {foo, bar} from './module1'
import {DATA_ARR} from './module1'
import {fun1, fun2} from './module2'
import person from './module3'
import $ from 'jquery'
//引入终了
$('body').css('background', 'red')
foo()
bar()
console.log(DATA_ARR);
fun1()
fun2()
person.setName('JACK')
console.log(person.name);
  1. 编译

    • 运用Babel将ES6编译为ES5代码(但包括CommonJS语法) : babel js/src -d js/lib
    • 运用Browserify编译js : browserify js/lib/app.js -o js/lib/bundle.js
  2. 页面中引入测试
<script type="text/javascript" src="js/lib/bundle.js"></script>
  1. 引入第三方模块(jQuery)

    • 1). 下载jQuery模块:
    npm install jquery@1 --save

- 2). 在app.js中引入并运用

```
import $ from 'jquery'
$('body').css('background', 'red')
```

总结

模块化计划长处瑕玷
commonJS复用性强;
运用简朴;
完成简朴;
有不少可以拿来即用的模块,生态不错;
同步加载不合适浏览器,浏览器的请求都是异步加载;
不能并行加载多个模块。
AMD异步加载合适浏览器可并行加载多个模块;
模块定义体式格局不文雅,不相符规范模块化
ES6可静态剖析,提早编译面向未来的规范;
浏览器原生兼容性差,所以平常都编译成ES5;
现在可以拿来即用的模块少,生态差

AMD和CMD辨别:

  • 威望参考:https://github.com/seajs/seaj…
  • 关于依靠的模块,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()   
         ...})
    • 虽然 AMD 也支撑 CMD 的写法,同时还支撑将 require 作为依靠项通报,但 RequireJS 的作者默许是最喜欢上面的写法,也是官方文档里默许的模块定义写法。
  • AMD 的 API 默许是一个当多个用,CMD 的 API 严厉辨别,推重职责单一。比方 AMD 里,require 分全局 require 和部分 require,都叫 require。CMD 里,没有全局 require,而是依据模块体系的完整性,供应 seajs.use 来完成模块体系的加载启动。CMD 里,每一个 API 都简朴地道。
  • 另有一些细节差别,详细看这个范例的定义就好,就不多说了。

参考:
运用 AMD、CommonJS 及 ES Harmony 编写模块化的 JavaScript

    原文作者:木头房子
    原文地址: https://segmentfault.com/a/1190000018843655
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞