js模块化

145 阅读3分钟

JavaScript中模块化相关内容

概念

  1. 模块化概念:

    JavaScript在早期设计时,并没有模块、类、包等概念,开发者需要模拟出类似的功能,用来分散复杂的JavaScript代码,称之为模块化。

    模块化,就是将独立的功能代码封装成一个独立的文件,其他模块需要使用,在进行引用。

  2. 模块化需要解决的问题:

    模块化需要实现:模块封装和模块加载,在这两个过程中会有以下问题:

    2.1 如何确保定义的各模块之间作用域独立,避免命名冲突;

    2.2 如何处理模块间依赖关系;

    2.3 模块化后,代码如何部署,如何减低HTTP请求次数;

    2.4 如何实现模块按需加载;

    2.5 如何保证性能以及后期调试debug等;

    模块化开发,需要紧扣上述问题来进行,避免后期出现问题。

  3. 原始解决方案的局限性:

    原始解决方案:命名空间、立即执行函数、script标签。

    局限性: 3.1 全局空间污染; 3.2 无法按需加载; 3.3 可扩展性低;

分类

后面在JavaScript不断的发展过程中,主要形成了以下几种模块化规范:

  1. 浏览器端:

    1.1 AMD(异步模块规范) RequireJs

    1.2 CMD(普通模块规范) SeaJs

  2. Node端:

    CommonJS(同步模块规范)

  3. 通用:

    浏览器和Node兼容端 UMD(通用模块规范)

  4. ECMAScript官方:

    ES Module即ESM

AMD

AMD是RequireJS在推广过程中对模块定义的规范化产出。

AMD是异步加载模块。它的模块支持对象、函数、构造器、字符串、JSON等各类型的模块。

define(['dep1', 'dep2'], function (dep1, dep2) {
    //Define the module value by returning a value.
    return function () {};
});

CMD

CMD是SeaJS 在推广过程中对模块定义的规范化产出

CMD和AMD的区别有以下几点:

  1. 对于依赖的模块AMD是提前执行,CMD是延迟执行。不过RequireJS从2.0开始,也改成可以延迟执行(根据写法不同,处理方式不通过)。

  2. CMD推崇依赖就近,AMD推崇依赖前置。

CommonJS

CommonJS就是一个JavaScript模块化的规范,该规范最初是用在服务器端NodeJS中,前端的webpack也是对CommonJS原生支持的。

CommonJS 提供了一套模块加载的规范,其核心语法是通过 module.exports 暴露接口,通过 require() 加载资源。

模块定义及导出:

// importing 
const doSomething = require('./doSomething.js'); 
 
// exporting
module.exports = function doSomething(n) {
  // do something
}

UMD

UMD是AMD和CommonJS的综合产物。

AMD 浏览器第一的原则发展 异步加载模块。

CommonJS 模块以服务器第一原则发展,选择同步加载,它的模块无需包装。

UMD先判断是否支持Node.js的模块(exports)是否存在,存在则使用Node.js模块模式。

再判断是否支持AMD(define是否存在),存在则使用AMD方式加载模块。

(function (window, factory) {
    if (typeof exports === 'object') {
        module.exports = factory();
    } else if (typeof define === 'function' && define.amd) {
        define(factory);
    } else {
        window.eventUtil = factory();
    }
})(this, function () {
    // module ...
});

ES Module

ECMA推出了官方标准的模块化解决方案,使用 export 导出,import 导入,编码简洁,从语义上更加通俗易懂。

ES6 支持异步加载模块 的模块不是对象,而是在编译的时候就完成模块的引用,所以是编译时才加载的。

ES Module特性:

  • ESM 自动采用严格模式,忽略 'use strict'

  • 每个 ES Module 都是运行在单独的私有作用域中

  • ESM 是通过 CORS 的方式请求外部 JS 模块的

  • ESM 的 script 标签会延迟执行脚本(浏览器页面渲染后执行)

import {foo, bar} from './myLib';
 
...
 
export default function() {
  // your Function
};
export const function1() {...};
export const function2() {...};