[JS-11] JavaScript 模块化

模块是比对象和函数更大的代码单元,使用模块可以将程序进行归类。
ES6模块并未被所有浏览器所兼容,虽然这只是时间问题,但实际工程中还需使用 Bable、Webpack 等工具进行转码。

常见的几种 JavaScript 模块化规范

  • AMD
  • CommonJS
  • ES6
// 使用函数作为模块,jQuery也使用此方法
(function() {
  var numClicks = 0;
  document.addEventListener('click', function() {
    console.log(numClicks++);
  })
})();

AMD 的设计明确基于浏览器
AMD 可以很容易指定模块及其依赖关系。同时,它支持浏览器。
AMD 有以下几项优点:

  • 自动处理依赖,我们无需考虑模块引入顺序
  • 异步加载模块,避免阻塞
  • 在同一个文件中可以定义多个模块
// AMD模式
define('MouseCounterModule', ['jQuery'], function($) {
  var numClick = 0;
  var handleClick = function() {
    console.log(numClick++);
  }

  return {
    countClicks: function() {
      $(document).on('click', handleClick);
    }
  }
})

CommonJS 的设计是面向通用 JavaScript 环境,例如 node.js 服务器
CommonJS 要求一个文件是一个模块,因此不用担心模块中定义的变量会造成全局污染
CommonJS 具有两个优势:

  • 语法简单
  • 是 Node.js 默认的模块格式,我们可以使用 npm 上成千上万的包

CommonJS 最大的缺点是不显示地支持浏览器,需要代码转换工具转换为浏览器支持格式

// 这里该模块的文件名为: MouseCounterModule.js
const $ = require('jQuery');
let numClick = 0;
const handleClick = () => {
  console.log(numClick++);
}

module.exports = {
  countClicks: () => {
    $(document).on('click', handleClick);
  }
}
// 在另一个文件中引用上面的模块
const MouseCounterModule = require('MouseCounterModule.js');

MouseCounterModule.countClicks();

ES6 模块结合了 CommonJS 与 AMD 的优点:

  • 语法简单,基于文件
  • 支持异步模块加载

ES6 模块关键字

  • export 从模块外部指定标识符
  • import 导入模块标识符

export 详解
import 详解

export

  • 命名导出 对导出多个值很有用。在导入期间,必须使用相应对象的相同名称。
  • 默认导出 一个文件中只能有一个,可以使用任何名称导入默认导出
// 命名导出
// 文件 my-module.js
function foo() {
  console.log('foo');
}

const bar = 'bar';

export { foo, bar };
// 导入方式
import { foo, bar } from 'my-module.js';
console.log(foo());   // 'foo'
console.log(bar);   // 'bar'
// 默认导出
// 文件 my-module.js
export default function() {
  console.log('I am default module');
}
// 导入方式
import fn from 'my-module.js';
console.log(fn());   // I am default module

import

// 导入整个模块内容
import * as myModule from '/modules/my-module.js';

myModule.foo();
myModule.bar;

// 导入单个或多个导出
import { foo, bar } from 'my-module.js';

// 导入并重命名
import { myFoo as foo, myBar as bar } from 'my-module.js';

无绑定导入,作为此模块的全局代码

// 文件my-module.js
Array.prototype.pushAll = function(items) {
  if(!Array.isArray(items)) {
    throw new TypeError('参数必须是一个数组!');
  }
  return this.push(...items);
}
// 无绑定导入
import myDefault from 'my-module.js'

let colors = ['red', 'green', 'blue'];
let items = [];

items.pushAll(colors);

加载模块


type="module"支持情况

你可能感兴趣的:([JS-11] JavaScript 模块化)