CJS

  • 规范代表库:CommonJS

CJSCommonJS 的缩写。

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 直观。我认为 AMDCJS 完全相反

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;
}));
  • 在前端和后端都适用(“通用”因此得名)
  • CJSAMD 不同,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相关推荐

  1. node中模块、AMD与CMD、ES6模块,node中使用ES6

    1.Nodejs 中的模块 在node环境中一个js文件就是一个模块(module) 我们采用的是CommonJS规范,使用require引入模块,使用module.exports导出接口 node的 ...

  2. AMD,CMD,UMD

    前端语言JavaScript和TypeScript,对其中的模块加载很晕,就研究了一下现有的模块加载方式.模块加载从大的方面来说分为服务器端加载和浏览器端加载,下面仔细说明. 一种服务器端模块化的规范 ...

  3. AMD,CMD,UMD 三种模块规范 写法格式

    一下三块均以 foo.js 为示例文件名,以 jQuery,underscore 为需求组件 ADM:异步模块规范, RequireJs 的支持格式 1 // 文件名: foo.js 2 define ...

  4. 前端模块化——彻底搞懂AMD、CMD、ESM和CommonJS

    我们知道,在NodeJS之前,由于没有过于复杂的开发场景,前端是不存在模块化的,后端才有模块化.NodeJS诞生之后,它使用CommonJS的模块化规范.从此,js模块化开始快速发展. 模块化的开发方 ...

  5. Javascript中的CJS、AMD、UMD 、ESM是什么

    ES6之前,JS一直没有自己的模块体交,这一点对于大型项目的开发很不友好,所以社区出现了CommonJs和AMD(本人不熟悉,, CommonJs主要是用于服务器 (Node) ,AMD主要是用于浏览 ...

  6. 前端模块化iife、CJS、AMD、UMD、ESM的区别

    前端模块化 注:以下所有解释完全依照本人的主观思想,如果有不对的地方,请见谅 说到模块化,不得不先了解一下模块的起源,时间顺序方面不要太在意 初始,只是创建一个js文件,里面定义一些方法.常量等,提供 ...

  7. JavaScript模块化 --- Commonjs、AMD、CMD、es6 modules

    随着前端js代码复杂度的提高,JavaScript模块化这个概念便被提出来,前端社区也不断地实现前端模块化,直到es6对其进行了规范,下面就介绍JavaScript模块化. 这篇文章还是希望能给大家一 ...

  8. javascript模块化之CommonJS、AMD、CMD、UMD、ES6

    javascript模块化之CommonJS.AMD.CMD.UMD.ES6 一.总结 一句话总结: CommonJS是同步加载模块,用在服务端:AMD是异步加载模块,用于浏览器端 1.为什么服务器端 ...

  9. AMD、CMD、CommonJS、ES6(import/export)

    AMD.CMD.CommonJS.ES6(import/export) AMD.CMD.CommonJS是ES5模块化解决方案 AMD -- 异步模块 Asynchronous Module Defi ...

  10. Requirejs与r.js打包,AMD、CMD、UMD、CommonJS、ES6模块化

    一:require.js 1.require.js是什么?为什么要用它? require.js是一个JavaScript模块载入框架,实现的是AMD规范.使用require.js有以下优点: ① 异步 ...

最新文章

  1. 从零开始打造自己的PHP框架――第2章
  2. android AsyncTask 的分析与运用
  3. NYOJ 613 免费馅饼
  4. 埃拉托斯特尼筛法(埃筛)
  5. 自动检测iOS网络并可跳转至设置界面设置网络
  6. 分布式中的 transaction log
  7. 这些贷款合同陷阱你知道多少?
  8. 数据结构之基环树——骑士,Island,旅行加强版,Number of Simple Paths,Traffic Network in Numazu,Card Game
  9. 使用BPF进行性能追踪-BPF前世今生
  10. 2021-秋招你准备好了吗?软件测试面试题
  11. java将当前页面隐藏,java 如何将当前程序隐藏到任务栏(类似windows上的其他程序)...
  12. 【Web前端】自制精简版的思源黑体ttf(728kb) - 包含2630个常用汉字+字母+数字+常用符号
  13. comsol matlab script,comsol script
  14. 在网上买衣服如何测量自己衣服尺码?
  15. 密码机分类--签名验签服务器
  16. iOS使用颜色生成图片的暗黑适配
  17. 数据分析实战二:爬取淘宝商品详情页进行分析
  18. 内连接、外连接、全连接
  19. setTimeout 的黑魔法
  20. China Looks To The Sea For Water

热门文章

  1. HDU-2570 迷瘴
  2. (每天一小步,进步一大步)NC291 数字序列中某一位的数字
  3. 1169 二维数组行列互换
  4. python爬取头条图集_Python爬虫基础练习(六) 今日头条街头篮球图片爬取
  5. 微信小程序使用场景延伸:扫码登录、扫码支付
  6. 分享一些舒服的英语表达,更有利于成交!
  7. 如何11 周打造全能Python工程师!
  8. SOAP summarize SOAP概述
  9. 计算机图形学头歌实训平台作业OpenGL立方体三维观察
  10. JavaScript Date对象时间处理