Skip to content

Latest commit

 

History

History
99 lines (83 loc) · 2.99 KB

js-module.md

File metadata and controls

99 lines (83 loc) · 2.99 KB

JS 模块化

#Front-End/JS

JS模块化

Common JS

  • 模块可以多次加载,只会在第一次加载时运行一次,运行结果就会缓存下来,要再次运行模块,必须清除缓存
  • 同步加载,模块加载会阻塞后面代码的执行
  • 用于服务器环境(nodejs)

exports只是对module.exports的引用,相当于Node为每个模块提供了一个exports变量,指向module.exports,相当于每个模块头部都有这么一行代码

var exports = module.exports

模块导出与引用

// common-js-a.js 暴露模块
// 默认加了一行 var exports = module.exports
exports.a = 'hello world';

// common-js-b.js 引入模块
const moduleA = require('./common-js-a');
console.log(moduleA.a)

AMD

  • 异步加载
  • 浏览器环境,依赖前置
// a.js 暴露模块, module1和module2 是其他前置依赖
define(['module1', 'module2'], function (m1, m2) {
	return { a: 'hello world' };
})

// b.js 引入模块
require(['./a.js'], function (moduleA) {
	console.log(moduleA.a)
})

CMD

  • 浏览器环境
  • 异步加载,就近依赖
// 异步加载 就近依赖

// a.js 导出
define(function(require, exports, module) {
    exports.a = 'hello CMD'
})

// b.js 导入
define(function(require, exports, module) {
	var moduleA = require('./a.js') // 依赖就近
	console.log(moduleA.a)
})

UMD

兼容AMD、commonJS、全局引用 同时支持运行在浏览器和Node环境

(function webpackUniversalModuleDefinition(root, factory) {
  // Test Comment
  if(typeof exports === 'object' && typeof module === 'object')
    module.exports = factory(require('lodash'));
  // Test Comment
  else if(typeof define === 'function' && define.amd)
    define(['lodash'], factory);
  // Test Comment
  else if(typeof exports === 'object')
    exports['someLibName'] = factory(require('lodash'));
  // Test Comment
  else
    root['someLibName'] = factory(root['_']);
})(this, function(__WEBPACK_EXTERNAL_MODULE_1__) {
  // ...
});

ES6 Module

// a.js
export const a = 'hello es6 module'

// b.js
import { a } from './a.js'
  • 浏览器环境,目前仍需要babel编译为ES5代码
  • export只支持对象形式导出,不支持值的导出,export default指定默认输出,本质上是一个叫做default的变量

总结

  • CommonJS的同步加载机制主要用于服务器端,也就是Node,但与之相伴的阻塞加载特点并不适用于浏览器资源的加载,所以诞生了AMD、CMD规范
  • AMD与CMD都可以在浏览器中异步加载模块,但实际上这两种规范的开发成本都比较高
  • UMD同时兼容AMD、commonJS、全局引用等规范,算是目前打包JS库的主流吧
  • ES6在语言标准的层面上实现了模块化,使用起来非常舒服,目前算是浏览器端的标准方案,再加上现代打包工具的加持,称霸Node服务端也指日可待