模块化 CJS 、AMD、UMD、ESM 简述

这是我参与8月更文挑战的第1天,活动详情查看:8月更文挑战javascript

模块化的优势:1. 避免全局变量被污染 2. 便于代码编写和维护html

CommonJS(CJS)

  每一个文件就是一个模块,有本身的做用域,文件内的变量、函数、类都是私有的,对其余文件不可见。模块内部,module变量表明当前模块,这个变量是一个对象,它的exports属性(即module.exports)是对外的接口。加载某个模块,实际上是加载该模块的module.exports属性。 例如:前端

module.exports.x = x;
module.exports.addX = addX;
// 或者
module.exports={x,addX}
复制代码

  若是某个变量或者函数想要被成公共变量,可以在其余文件中获取,就须要挂在global上。(这么写并不推荐) 例如:java

global.warning = true;
复制代码

  CJS 是同步导入模块,能够从 modules 中引入一个库或者从本地目录引入一个文件,使用require方法用于加载模块node

当 CJS 导入时,它会给你一个导入对象的副本。jquery

const { sequelize } = require("../../core/db");
复制代码

  CJS 不能在浏览器中工做,必须通过转换和打包。 node.js 就是使用 commonJs 的模块规范,能够在 js 文件中直接使用。webpack

特色

  • 全部代码都运行在模块做用域,不会污染全局做用域。
  • 模块能够屡次加载,可是只会在第一次加载时运行一次,而后运行结果就被缓存了,之后再加载,就直接读取缓存结果。要想让模块再次运行,必须清除缓存。
  • 模块加载的顺序,按照其在代码中出现的顺序。

参考: javascript.ruanyifeng.com/nodejs/modu…web

ESM ES 模块

  这是 Javascript 提出的实现一个标准模块系统的方案,在不少现代浏览器可使用. 能够在 HTML 中调用,可是须要在 script 标签上添加属性 type=‘module’json

<script type="module">
 import {func1} from 'my-lib';
 func1();
</script>
复制代码

  能够导入本地的文件、库或者远程模块。(静态)redux

import { createStore } from "https://unpkg.com/redux@4.0.5/es/redux.mjs";
import * as myModule from './util.js';
复制代码

  除了可以静态导入,还能够动态导入。ES模块其实是JavaScript对象:咱们能够解构它们的属性以及调用它们的任何公开方法。 例如:

btn.addEventListener("click", () => {
  // loads named export
  import("./util.js").then(({ funcA }) => {
    funcA();
  });
});
或
const loadUtil = () => import("./util.js"); 
// 返回的是一个 promise。因此也可使用可使用 `async/await`

btn.addEventListener("click", () => {
  loadUtil().then(module => {
    module.funcA();
    module.default();
  })
})
// 使用 async/await 的写法
btn.addEventListener("click", async () => {
  const utilsModule = await loadUtil();
  utilsModule.funcA();
  utilsModule.default();
})

复制代码

  使用动态导入能够拆分代码,只在适当的时候加载重要的代码。在 JavaScript 引入动态导入以前,这种模式是webpack(模块绑定器)独有的。 像ReactVue经过动态导入代码拆分来加载响应事件的代码块,好比用户交互或路由更改。

  当导入的json文件时,导出的直接是json文件中的数据

优势

具备 CJS 的简单语法和 AMD 的异步,ESM 容许像 Rollup 这样的打包器,删除没必要要的代码,减小代码包能够得到更快的加载。

参考: blog.csdn.net/hpc_kiven/a…

AMD 异步模块定义

  AMD 是为前端而作的(而 CJS 是后端),AMD 的语法不如 CJS 直观。 示例:

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

// "simplified CommonJS wrapping" https://requirejs.org/docs/whyamd.html
define(function (require) {
   var dep1 = require('dep1'),
       dep2 = require('dep2');
   return function () {};
});
复制代码

UMD 通用模块定义(Universal Module Definition)

  在前端和后端都适用,与 CJS 或 AMD 不一样,UMD 更像是一种配置多个模块系统的模式,当使用 Rollup/Webpack 之类的打包器时,UMD 一般用做备用模块

(function (root, factory) {
   if (typeof define === "function" && define.amd) {
       define(["jquery", "underscore"], factory);
   } else if (typeof exports === "object") {
       module.exports = factory(require("jquery"), require("underscore"));
   } else {
       root.Requester = factory(root.$, root._);
   }
}(this, function ($, _) {
   // this is where I defined my module implementation

   var Requester = { // ... };

   return Requester;
}));
复制代码
相关文章
相关标签/搜索