Skip to content

JavaScript模块化方案介绍

Published:

本文梳理了主流的 JS 模块化方案。

ESM(ES Modules)

现代 JavaScript 推荐方式。支持静态分析、异步加载和 Tree Shaking。

使用环境node(需要加 "type": "module".mjs 后缀)、浏览器(现代浏览器原生支持)

语法

// 导入模块
import React from 'react';
import {foo, bar} from './myLib';

// 导出模块
export default function() {
 // your Function
};
export const function1() {...};
export const function2() {...};

CJS(CommonJS)

Node.js 默认的模块系统,同步加载。

使用环境Node.js(默认支持)

语法

// 导入模块
const React = require('react');
const { foo, bar } = require('./myLib');

// 导出模块
module.exports = function () {
  // your Function
};
exports.function1 = () => {...};
exports.function2 = () => {...};

AMD(Asynchronous Module Definition)

异步加载,常与 RequireJS 搭配。

使用环境浏览器,通常配合 RequireJS

语法

define(['react', './myLib'], function (React, myLib) {
  function function1() {...}
  function function2() {...}

  return {
    function1,
    function2,
  };
});

UMD(Universal Module Definition)

为了解决多种加载环境兼容问题(AMD、CJS、浏览器全局),常用于库的发布。

使用环境
兼容 Node.js浏览器AMD 加载器(如 RequireJS)

语法

((global, factory) => {
  //如果 当前的上下文有define函数,并且AMD  说明处于AMD 环境下
  if (typeof define === "function" && define.amd) {
    define(["moduleA"], factory);
  } else if (typeof exports === "object") {
    //commonjs
    let moduleA = require("moduleA");
    modules.exports = factory(moduleA);
  } else {
    global.moduleA = factory(global.moduleA); //直接挂载成 windows 全局变量
  }
})(this, moduleA => {
  //本模块的定义
  return {};
});

IIFE(Immediately Invoked Function Expression)

立即执行函数表达式,早期模拟模块私有作用域的做法。

使用环境
浏览器,适用于简单模块或早期模块化场景

语法

(function foo() {
  console.log("立即执行函数");
})();

SystemJS

动态模块加载器,支持多种模块格式,常用于微前端等场景。

使用环境浏览器(需要引入 SystemJS 库)

语法

// 动态加载模块
System.import("/js/main.js")
  .then(() => {
    // 执行初始化逻辑
  })
  .catch(error => {
    // 处理加载错误
  });

总结

方案适用环境优点缺点
ESMNode/浏览器标准、静态、原生支持兼容性需注意
CJSNode简单、生态丰富仅同步、非浏览器友好
AMD浏览器异步、依赖明确语法繁琐
UMD通用兼容性强实现复杂
IIFE浏览器简单无依赖管理
SystemJS浏览器动态、格式兼容性强依赖库、体积大

参考


Previous Post
Playwright 备忘录
Next Post
H5支付前端接入