JS模块化CommonJS、AMD、CMD知识总结

1. 什么是模块化?

将一个复杂的程序依据一定的规则封装成几个块(文件),并最终组合在一起。块(文件)的内部数据/实现是私有的,只是向外部暴露一些接口(方法)与外部其他模块通信。

2.模块的进化史

1.最早的代码风格,全局被污染,容易造成命名冲突。

function foo(){
    
    
    //...
}

function bar(){
    
    
    //...
}

2.简单封装:namespace模式。虽然减少了全局变量的数目,但本质是对象,不安全。

var myApp={
    
    
    foo:function(){
    
    
        //...
    },
    bar:function(){
    
    
        //...
    }
}

myApp.foo()

3.匿名闭包:IIFE模式,立即执行函数是局部作用域,不污染全局作用域。

var module=(function(){
    
    
    var _private="安全作用域";
    var foo=function(){
    
    
        console.log(_private)
    }
    return {
    
    
        foo
    }
})()

module.foo();
module._private;//undefined

4.在立即执行函数中引入依赖:这也是现代模块实现的基石。

var module = (function ($) {
    
    
  var _$body = $('body')
  var foo = function () {
    
    
    console.log(_$body)
  }
  return {
    
    
    foo,
  }
})(jQuery)

module.foo()

模块化的好处:

  • 避免命名冲突,减少命名空间污染
  • 更好的分离,按需加载
  • 更高的复用性
  • 更容易维护

缺点:

  • 由于一个文件被分割成多个文件,造成页面加载时需要更多的请求数,而往往我们需要减少发起请求的数量。
  • 依赖模糊,拆分的文件往往需要按照一定的顺序引入,这容易造成犯错。
  • 难以维护

3.CommonJS

说明:

  • 服务器端:模块的加载是运行时同步加载
  • 浏览器端:模块需要提前编译打包处理

基本语法

暴露模块:

  • module.exports=value
  • exports.xxx=value

引入模块:

  • require(xxx)

注意:

  • 当引入的模块是第三方模块,则xxx是模块名,比如(const jQuery = require('jQuery'))
  • 当引入的模块是自定义模块,则xxx是自定义模块的路径,比如(let myModule = require('./myModule.js'))

CommonJS常用于NodeJs中。

示例:

创建四个文件:module1.js、 module2.js、module3.js、app.js文件

module1.js

function foo() {
    
    
  console.log('module1  foo()')
}

module.exports = {
    
    
  foo,
}

module2.js

module.exports = function () {
    
    
  console.log('module2()')
}

module3.js

exports.foo = function () {
    
    
  console.log('module3 foo()')
}

exports.bar = function () {
    
    
  console.log('module3 bar()')
}

app.js用于引入模块

const module1 = require('./module1') //const { foo } = require('./module1');//使用了es6语法,进行对象解构
const module2 = require('./module2')
const module3 = require('./module3') //const {foo,bar} = require('./module3')

module1.foo()
module2()
module3.foo()
module3.bar()

4.AMD(Asynchronous Module Definition 异步模块定义)

说明:

  • 专门用于浏览器端,模块的加载是异步的。
  • require.js实现

基本语法

定义模块

  • 定义没有依赖的模块:
define(function(){
    
    
	return 模块
})
  • 定义有依赖的模块:
define(['module1','module2'],function(m1,m2){
    
    
	return 模块
})

引入模块

require(['module1','module2'],function(m1,m2){
    
    
	使用m1/m2模块
})

require.js使用教程

1.下载require.js, 并引入

  • 官网: http://www.requirejs.cn/
  • github : https://github.com/requirejs/requirejs
  • 将require.js导入项目: js/libs/require.js

2.创建项目结构

  |-js
    |-libs
      |-require.js
    |-modules
      |-alerter.js
      |-dataService.js
    |-main.js
  |-index.html

3.定义require.js的模块代码

  • dataService.js
   define(function () {
    
    
      let msg = 'atguigu.com'
    
      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}
    })

4.应用主(入口)js: main.js

  (function () {
    
    
    //配置
    requirejs.config({
    
    
      //基本路径
      baseUrl: "js/",
      //模块标识名与模块路径映射
      paths: {
    
    
        "alerter": "modules/alerter",
        "dataService": "modules/dataService",
      }
    })
    //引入使用模块
    requirejs( ['alerter'], function(alerter) {
    
    
      alerter.showMsg()
    })
  })()

5.index.html

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>AMD示例</title>
  </head>
  <body>
    <script data-main="js/main.js" src="js/libs/require.js"></script>
  </body>
</html>

5.CMD (Common Module Definition 通用模块定义)–少用

说明:

  • 专门用于浏览器端,模块的加载是异步的。
  • sea.js实现
  • CMD是common.js与AMD的集合

基本语法

定义暴露模块:

  • 定义没有依赖的模块
define(function(require,exports,module){
    
    
	exports.xxx=value
	module.exports=value
})
  • 定义有依赖的模块
define(function(require,exports,module){
    
    
    //同步引入依赖模块
	var module2 = require('./module2')
	//异步引入依赖模块
	require.async('./module3',function(m3){
    
    
		//...
	})
	//暴露模块
	exports.xxx=value
})

引入模块:

define(function(require){
    
    
	var m1 = require('./module1')
	var m3 = require('./module3')
	//使用m1/m3
})
sea.js简单使用教程
  1. 下载sea.js, 并引入
  • 官网: http://seajs.org/
  • github : https://github.com/seajs/seajs
  • 将sea.js导入项目: js/libs/sea.js
  1. 创建项目结构
  |-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 = 'atguigu.com'
      //内部函数
      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>

猜你喜欢

转载自blog.csdn.net/weixin_43334673/article/details/113717809