CJS、ESM、AMD、CMD、UMD
CJS
- 规范代表库:CommonJS
CJS
是 CommonJS
的缩写。
nodejs里的规范,环境变量:
- module
- exports
- require
- global
每一个文件是一个模块,有自己的作用域。在文件内定义的变量、函数、类都是私有的,对其他文件不可见。
global是全局变量,多个文件内可以共同分享变量。
commonjs规定:
每个模块内部,module变量代表当前模块,该变量是一个对象。他有一个exports属性,这个属性是对外的接口。加载某一个模块,其实就是加载该模块的module.exports属性。
经常我们这么使用:
// importing
const doSomething = require('./doSomething.js'); // exporting
module.exports = function doSomething(n) {// do something
}
- 所有代码运行在模块作用域内,不会污染全局变量
CJS
是同步导入模块- 模块可以加载多次,但是只有第一次加载时运行一次。然后运行结果就被缓存下来,以后再加载,就是直接读取缓存的结果。
CJS
不能在浏览器中工作。它必须经过转换和打包
Module对象
node内部提供一个Module构建函数。每一个模块内部都有一个module对象,代表当前模块。它有以下属性:
- id 模块标识符,通常是带有绝对路径的模块文件名
- path 模块的文件名,绝对路径
- exports 模块对外输出的值
- parent 调用该模块的模块
- children 该模块用到的其他模块
- loaded 该模块是否已经加载完(在父模块中require一个子模块之后,子模块的loaded才变为true)
module.exports
表示对外输出的接口,其他文件加载该模块其实就是读取module.exports变量
exports
为了方便,Node为每一个模块提供了exports变量,指向module.exports。等同于
var exports = module.exports
所以切记,不可以直接给exports赋值,这样就是切断了 exports和module.exports的联系。
exports = () => {}
只可以在exports上添加属性。 如果该模块对外输出的是一个简单类型的值。那么不可以用exports去输出了,只能用module.exports = ‘xx’
加载模式 - 同步/运行时加载
首先,commonjs加载模块的方式是同步的。在输入时先加载整个模块,生成一个对象。再从这个对象上读取方法,这种加载被成为运行时加载。只有对应子模块加载完成,才能执行后面的操作。 为什么是同步的?因为Nodejs是用于服务端编程,模块文件存在于硬盘中,读取非常快。
加载时机
输入的值是被输出的值的拷贝。 父模块引入了一个子模块,其实引入的是这个子模块输出的值的拷贝,一旦输出了这个值,模块内部的变化就影响不到这个值了。
loadsh 是CJS模块化规范的发布包
AMD
- 规范代表库:require.js
AMD
代表异步模块定义,浏览器环境要加载资源,需要从服务器端加载模块,依靠网络下载,时间比较长。所以需要采用非同步的模块。下面是一个示例代码
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 () {};
});
AMD
是异步(asynchronously
)导入模块的(因此得名)- 一开始被提议的时候,
AMD
是为前端而做的(而CJS
是后端) AMD
的语法不如CJS
直观。我认为AMD
和CJS
完全相反
UMD
UMD
代表通用模块定义(Universal Module Definition
),是一种思想,兼容commonjs、AMD、CMD。
先判断是否支持Nodejs模块(exports是否存在),如果存在就使用Nodejs模块。不支持的话,再判断是否支持AMD/CMD(判断define是否存在),都不行就挂载在window全局对象上
下面是它可能的样子(来源)
(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 implementationvar Requester = { // ... };return Requester;
}));
- 在前端和后端都适用(“通用”因此得名)
- 与
CJS
或AMD
不同,UMD
更像是一种配置多个模块系统的模式。这里可以找到更多的模式 - 当使用
Rollup/Webpack
之类的打包器时,UMD
通常用作备用模块
js-cookie 是UMD模块化规范的发布包
ESM
- esm规范是es6原生支持的,很多浏览器开始支持,类似commonjs的写法和同、异步加载机制
ESM
代表 ES
模块。这是 Javascript
提出的实现一个标准模块系统的方案,其模块功能由两个命令组成:export 和 import。
我相信你们很多人都看到过这个:
import React from 'react';
或者其他更多的
import {foo, bar} from './myLib';...export default function() {// your Function
};
export const function1() {...};
export const function2() {...};
ES6模块的特征:
- import 是只读属性,不能赋值。相当于const
- 它兼具两方面的优点:具有
CJS
的简单语法和AMD
的异步 - 得益于
ES6
的静态模块结构,可以进行 Tree Shaking ESM
允许像Rollup
这样的打包器,删除不必要的代码,减少代码包可以获得更快的加载- export/import 提升,import/export必须位于模块的顶级,不可以位于作用域内,其次对于模块内的import/export都会提升到模块的顶部。
- 可以在
HTML
中调用,只要如下
<script type="module">import {func1} from 'my-lib';func1();
</script>
但是不是所有的浏览器都支持(来源)。
ES6 Module 加载时机
import 是静态命令的方式,js引擎对脚本静态分析时,遇到模块加载命令import,会生成一个只读引用。等到脚本真正执行时,再根据这个只读引用,到被记载的那么模块中去取值。模块内部引用的变化会反应在外部。
在import时可以指定加载某个输出值,而不是加载整个模块,这种加载称为编译时加载。在编译时就引入模块代码,而不是在代码运行时加载,所以无法实现条件加载。也正因为这个,使得静态分析成为可能。
loadsh-es 是ESM模块化规范的发布包
CMD
- 规范代表库:sea.js
sea.js 都是异步加载, AMD推崇的是前置依赖,提前执行。CMD推崇的是就近依赖,延迟执行
CJS、ESM、AMD、CMD、UMD相关推荐
- node中模块、AMD与CMD、ES6模块,node中使用ES6
1.Nodejs 中的模块 在node环境中一个js文件就是一个模块(module) 我们采用的是CommonJS规范,使用require引入模块,使用module.exports导出接口 node的 ...
- AMD,CMD,UMD
前端语言JavaScript和TypeScript,对其中的模块加载很晕,就研究了一下现有的模块加载方式.模块加载从大的方面来说分为服务器端加载和浏览器端加载,下面仔细说明. 一种服务器端模块化的规范 ...
- AMD,CMD,UMD 三种模块规范 写法格式
一下三块均以 foo.js 为示例文件名,以 jQuery,underscore 为需求组件 ADM:异步模块规范, RequireJs 的支持格式 1 // 文件名: foo.js 2 define ...
- 前端模块化——彻底搞懂AMD、CMD、ESM和CommonJS
我们知道,在NodeJS之前,由于没有过于复杂的开发场景,前端是不存在模块化的,后端才有模块化.NodeJS诞生之后,它使用CommonJS的模块化规范.从此,js模块化开始快速发展. 模块化的开发方 ...
- Javascript中的CJS、AMD、UMD 、ESM是什么
ES6之前,JS一直没有自己的模块体交,这一点对于大型项目的开发很不友好,所以社区出现了CommonJs和AMD(本人不熟悉,, CommonJs主要是用于服务器 (Node) ,AMD主要是用于浏览 ...
- 前端模块化iife、CJS、AMD、UMD、ESM的区别
前端模块化 注:以下所有解释完全依照本人的主观思想,如果有不对的地方,请见谅 说到模块化,不得不先了解一下模块的起源,时间顺序方面不要太在意 初始,只是创建一个js文件,里面定义一些方法.常量等,提供 ...
- JavaScript模块化 --- Commonjs、AMD、CMD、es6 modules
随着前端js代码复杂度的提高,JavaScript模块化这个概念便被提出来,前端社区也不断地实现前端模块化,直到es6对其进行了规范,下面就介绍JavaScript模块化. 这篇文章还是希望能给大家一 ...
- javascript模块化之CommonJS、AMD、CMD、UMD、ES6
javascript模块化之CommonJS.AMD.CMD.UMD.ES6 一.总结 一句话总结: CommonJS是同步加载模块,用在服务端:AMD是异步加载模块,用于浏览器端 1.为什么服务器端 ...
- AMD、CMD、CommonJS、ES6(import/export)
AMD.CMD.CommonJS.ES6(import/export) AMD.CMD.CommonJS是ES5模块化解决方案 AMD -- 异步模块 Asynchronous Module Defi ...
- Requirejs与r.js打包,AMD、CMD、UMD、CommonJS、ES6模块化
一:require.js 1.require.js是什么?为什么要用它? require.js是一个JavaScript模块载入框架,实现的是AMD规范.使用require.js有以下优点: ① 异步 ...
最新文章
- 从零开始打造自己的PHP框架――第2章
- android AsyncTask 的分析与运用
- NYOJ 613 免费馅饼
- 埃拉托斯特尼筛法(埃筛)
- 自动检测iOS网络并可跳转至设置界面设置网络
- 分布式中的 transaction log
- 这些贷款合同陷阱你知道多少?
- 数据结构之基环树——骑士,Island,旅行加强版,Number of Simple Paths,Traffic Network in Numazu,Card Game
- 使用BPF进行性能追踪-BPF前世今生
- 2021-秋招你准备好了吗?软件测试面试题
- java将当前页面隐藏,java 如何将当前程序隐藏到任务栏(类似windows上的其他程序)...
- 【Web前端】自制精简版的思源黑体ttf(728kb) - 包含2630个常用汉字+字母+数字+常用符号
- comsol matlab script,comsol script
- 在网上买衣服如何测量自己衣服尺码?
- 密码机分类--签名验签服务器
- iOS使用颜色生成图片的暗黑适配
- 数据分析实战二:爬取淘宝商品详情页进行分析
- 内连接、外连接、全连接
- setTimeout 的黑魔法
- China Looks To The Sea For Water