CommonJs & AMD & CMD & ESM

2019-03-22  本文已影响0人  Veycn

CommonJs

CommonJs 规定每个 js 文件都能被看作是一个模块, 其内部定义的变量是私有的, 不会对外暴露。不会污染全局。
CommonJs 采用同步(一个接着一个)的加载模块, 适用于服务器,不适合在浏览器端使用。
CommonJs 不被浏览器端支持, 因为浏览器没有 module, exports, require, global 四个环境变量。
如果要在浏览器使用CommonJs , 需要使用工具转换(browserify)
主要有以下方式对模块进行导入导出:

  1. module.exports = { a: 12, foo: function(){ console.log(this.a) } }
    导出为一个对象
    var obj = require('./m1.js')
    obj.a = 34
    obj.foo()
  2. module.exports = function(){ return {a: 12} }
    导出是一个函数, 可以直接执行
    var foo = require('./m2.js')
    foo()
  3. exports.foo = function(){ return {a: 12}}
    导出为一个对象, 对象里面的属性为foo
    var obj = require('./m3.js')
    obj.foo()
    注意: 不是使用import, importES6的语法
    想要在浏览器环境中使用:
    index.js中将模块导入, 然后node使用如下命令:
    browserify index.js -o bundle.js 前提是安装了browserify这个包。
    然后在html里面引入bundle.js

AMD

不同于CommonJsAMD是异步加载, 名称就是Asynchronous Module Difinition, 允许指定回调函数, 等异步加载完成之后即可调用回调函数。
AMD的核心思想就是通过define来定义模块, 然后通过require来加载模块, 它依赖于require.js
html文件里面引入script
<script src="require.js" data-main="./index.js"></script>
定义模块 m1:

define([模块名称], [依赖模块], function(){
  name: 'vey-module-1',
  getName: function(){
    return name
  }
  return {getName: getName}
})

模块名称定义此模块的名称, 不写则默认为文件名去掉后缀
依赖模块指定此模块依赖的模块, 类型为数组。
此模块的内容定义在function里面
再定义一个模块 m2

define(['m1'], function(m1){
  name: 'vey-module-2',
  function show() {
    console.log(name, m1.getName())
  }
  return { show }
})

定义index.js

(function(){
  // 配置模块的路径
  require.config({
    paths: {
      m1: './m1'
      m2: './m2'
    }
  })
  require(['m2'], function(m2){
    m2.show()
  })
})()

然后就可以看到执行结果了。
AMD是依赖前置的, 即不管你用没用到, 只要你设置了依赖, 就会去加载。不是按需加载的。

CMD

相比AMD, CMD也同样是异步加载, AMD是依赖前置, CMD是就近加载, 按需加载的。主要产物就是sea.js
核心思想与AMD高度类似, 通过define定义模块, require加载模块
<script src="sea.js"></script>
<script> seajs.use('./index.js') </script>
定义 m1:

define(function (require, exports, module) {
    var msg = 'm1'
    function foo() {
        console.log(msg);
    }
    module.exports = {
        foo
    }
})

定义 m2:

define(function (require, exports, module) {
    var msg = 'm2'
    function bar() {
        console.log(msg);
    }
    module.exports = bar
})

定义 m3:

define(function (require, exports, module) {
    var msg = 'm3'
    function fun() {
        console.log(msg);
    }
    exports.fun = fun
})

定义 m4:

define(function (require, exports, module) {
    var msg = 'm4'
    var m2 = require('./m2')
    m2()
    require.async('./m3', function(m3){
        m3.fun()
    })
    function func () {
        console.log(msg)
    }
    exports.func = func
})

定义 index.js:

define(function (require, exports, module) {
  var m1 = require('./m1')
  m1.foo()
  var m4 = require('./m4')
  m4.func()
})

ESM

所谓ESM, 即ECMAScript2015 Module. 也就是ES6中的模块化。
ES6自带模块化, 从语言的标准上实现了模块化, 使用export导出, import导入。

let a = 10
let b = 20
let c = 'aaa'
export function myFun(){}
export default foo(){} 

export default 默认导出, 不管是否导出其他, 这个后面跟的东西一定会被导出, 而且只能写一个默认导出
ES6 的导入导出平时用的最多, 也比较熟悉, 这里就不再啰嗦。

上一篇下一篇

猜你喜欢

热点阅读