JavaScript模块化最全总结

JavaScript模块化最全总结

没有模块化规范的时候

在没有CommonJS,AMD,CMD等规范的时候,人们为了让代码模块化,采用了下面这个链接里的方法:http://www.ruanyifeng.com/blog/2012/10/javascript_module.html

在这里插入图片描述

CommonJS

NodeJS 是 CommonJS 规范的实现,webpack 也是以 CommonJS 的形式来书写。CommonJS 是一种只适用于 JavaScript 的静态模块化规范。只适用于 Node.js 开发,但是不适合浏览器环境。

原因:

  1. 浏览器环境的前端资源不仅仅是 JavaScript ,还包括 CSS 、图片等, CommonJS 无法处理 JavaScript 以外的资源。
  2. CommonJS 所有模块均是同步阻塞式加载,无法实现按需异步加载。


特点:

  • 同步加载;
  • 主要用于服务器端,不适合前端;
  • 在服务器端,模块的加载是运行时同步加载的;
  • 在浏览器端,无法直接运行在浏览器端上,需要通过工具转换成标准的 ES5 ;
  • 所有代码都运行在模块作用域,不会污染全局作用域;
  • 模块可以多次加载,但是只会在第一次加载时运行一次,然后运行结果就被缓存了,以后再加载,就直接读取缓存结果。要想让模块再次运行,必须清除缓存;
  • 模块加载的顺序,按照其在代码中出现的顺序。

实现:
NodeJS

使用:
加载模块/引入模块:
如果是第三方模块,xxx 为模块名;如果是自定义模块, xxx 为模块文件路径。

require(xxx)

暴露模块:

module.exports = value
// 或
exports.xxx = value

加载机制:
输入的是被输出的值的拷贝。也就是说,一旦输出一个值,模块内部的变化就影响不到这个值。

AMD

AMD,异步模块定义。浏览器的模块,不能采用“同步加载”,只能采用“异步加载”,因此 AMD 产生了。与 CommonJS 最大的不同在于它采用异步的方式去加载依赖的模块。
特点:

  • 专门用于浏览器端;
  • 模块的加载是异步的, 模块的加载不影响它后面语句的运行。所有依赖这个模块的语句,都定义在一个回调函数中,等到加载完成之后,这个回调函数才会运行;
  • 依赖前置。

优点:

  • 可在不转换代码的情况下直接在浏览器中运行;
  • 可异步加载依赖;
  • 可并行加载多个依赖;
  • 代码可运行在浏览器环境和 Node.js 环境下。

缺点:

  • JS 运行环境没有原生支持 AMD,需要先导入实现了 AMD 的库后才能正常使用。

使用:
加载模块/引入模块:

require([module], callback);

// 例子
require(['moduleA', 'moduleB', 'moduleC'], function(moduleA, moduleB, moduleC) {
  // ...
});

定义模块:
模块必须采用特定的 define() 函数来定义。

  1. 定义的模块不依赖其他模块
// math.js
define(function() {
  var add = function(x, y) {
    return x + y;
  };
  return {
    add: add
  };
});
  1. 定义的模块依赖其他模块,那么 define() 函数的第一个参数,必须是一个数组,指明该模块的依赖性。
define(['myLib'], function(myLib) {
  function foo() {
    myLib.doSomething();
  }
  return {
    foo: foo
  };
});

实现:

  • RequireJS

RequrieJS 是一个工具库,只要用于客户端的模块。它的模块管理遵守 AMD 规范。RequireJS 的基本思想是,通过 define 方法,将代码定义为模块;通过 require 方法,实现代码的模块加载。出自 dojo 加载器的作者 James Burke

  • 依赖前置。RequireJS 会先尽早地执行(依赖)模块,相当于所有的 require 都被提前了,但是模块的执行顺序不一定是 require 的顺序。
  • RequireJS 引入的文件(模块),只会解释执行一次,所以引入的模块也可用作全局变量。
  • RequireJS 要求,每个模块是一个单独的 js 文件。
  • curlJS

CMD

特点:

  • 依赖就近
  • 在浏览器端使用
  • 异步加载
  • 整合了 CommonJS 和 AMD 规范的特点

使用:
定义模块:

  1. 定义没有依赖的模块
define(function(require, exports, module) {
  exports.xxx = value
  module.exports = value
})
  1. 定义有依赖的模块
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()
})

实现:

  • SeaJS
    • 出自玉伯
    • 懒执行
    • SeaJS 只会在真正需要使用(依赖)模块时才执行该模块
    • SeaJS 执行模块的顺序是严格按照模块在代码中出现(require)的顺序。
    • 依赖就近

## ES6模块化 ES6 模块化是 ECMA 提出的 JavaScript 模块化规范,它在语言的层面上实现了模块化。浏览器厂商和 Node.js 都宣布要原生支持该规范。它将逐渐取代 CommonJS 和 AMD 规范,称为浏览器和服务器通用的模块解决方案。
**特点:**
  • 每一个模块只加载一次,每一个 js 只执行一次,如果下次再去加载同一个文件,直接从内存中读取。一个模块就是一个单例,或者说就是一个对象。
  • 每一个模块内声明的变量都是局部变量,不会污染全局作用域。
  • 模块内部的变量或者函数可以通过 export 导出。
  • 一个模块可以导入别的模块。


使用:
导出模块:export 命令用于规定模块的对外接口。
引入模块:import 命令用于输入其他模块提供的功能。
例子:

// 定义模块math.js
var basicNum = 0;
var add = function(a, b) {
  return a + b;
};
export { basicNum, add };

// 引用模块
import { basicNum, add } from './math';
function test(ele) {
  ele.textContent = add(99 + basicNum);
}

ES6模块 VS CommonJS

模块输出加载方式
CommonJS值拷贝对象
ES6引用(符号链接)静态解析

注意:由于 ES6模块化 目前无法在浏览器中执行,所以,我们只能通过 babel 将不被支持的 import 编译为当前受到广泛支持的 require

UMD

特点:

  • UMD 是 AMD 和 CommonJS 的糅合
  • UMD 先判断是否支持 Node.js 的模块(exports)是否存在,存在则使用 Node.js 模块模式;再判断是否支持AMD(define)是否存在,存在则使用 AMD 方式加载模块。
  • 常用的场景就是当你封装的模块需要适配不同平台(浏览器、node.js)

原文链接:js模块化

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值