浅学一下模块化

138 阅读3分钟

CommonJs

说明

  • node采用的是CommonJS模块规范
  • 每一个文件就是一个模块,有自己的作用域,模块内的函数和数据都是私有的,对外不可见
  • 在服务端,模块的加载是同步的
  • 在浏览器端,模块需要提前编译打包处理
  • 模块可以加载多次,但是只在第一次加载时执行,后面再加载时,就行缓存中取,如果要重新执行,必须清除缓存
  • CommonJS模块的加载机制是,输入的是被输出的值的拷贝。也就是说,一旦输出一个值,模块内部的变化就影响不到这个值。

基本语法

  • 暴露模块

    • module.exports = value

    • exports.xxx = value

  • 引入模块

    • require(xxx)

      • 第三方模块,xxx为模块名
      • 自定义模块,xxx为模块文件路径
      • require命令的基本功能是,读入并执行一个JavaScript文件,然后返回该模块的exports对象。如果没有发现指定模块,会报错。
  • 疑问:CommonJS暴露的模块到底是什么?

实现

  • 服务器端

    • 下载安装nodejs
    • 创建项目结构
    • 下载第三方模块
    • 定义模块代码
    • 通过node运行app.js
  • 浏览器端

    • 创建项目结构
    • 下载browserify
    • 定义模块代码
    • 打包处理js
    • 页面使用引入

AMD

说明

  • 异步加载模块
  • 适用于浏览器端

基本语法

  • 暴露模块
 //定义没有依赖的模块

define(function(){

    return 模块

})

//定义有依赖的模块

define(['module1', 'module2'], function(m1, m2){

    return 模块

})
  • 引入模块

  require(['module1', 'module2'], function(m1, m2){

          使用m1/m2
    })

实现

  • require.js

CMD

说明

  • 专门用于浏览器端
  • 模块加载是异步的
  • 模块使用时才会加载

基本语法

  • 暴露模块

   //定义没有依赖的模块

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 m4 = require('./module4')

    m1.show()

    m4.show()

})

实现

  • sea.js

es6模块化

说明

  • 浏览器和服务器通用的模块解决方案
  • 依赖模块需要编译打包处理

基本语法

  • 导出模块:export
  • 引入模块:import

实现

  • 使用babel将es6转化为es5

区别

  • ES6 模块是动态引用,并且不会缓存值,模块里面的变量绑定其所在的模块。CommonJS 是静态引用
  • CommonJS 模块输出的是一个值的拷贝。export里面值的修改不影响require里面的值。ES6 模块输出的是值的引用。export里面的值修改了会影响import里面的值
  • CommonJS 模块是运行时加载,ES6 模块是编译时输出接口。

模块化理解

将一个复杂的程序依据一定的规则封装成几个块,并组合在一起,块的内部的数据和方法都是私有的,只向外暴露接口与外部进行通信

好处:可以提高代码的复用性,每一个模块都可以是一个文件,提高了项目的可维护性,更好的分离,按需加载,避免了命名冲突

总结的脑图: