amd,cmd,commonJS,umd,es6模块规范小结

前言

在进行ts项目的时候,总是报错找不到模块,查了很多资料发现自己这块的内容还是不怎么熟悉,今天总结下方便今后查询

规范

我的理解是amd,cmd,commonJS,umd,es6并不是什么新的语言,他们就是写法上的不一样,从而引出了不同的写法对应这个不同的规范。我们用的最多的应该是commonJS和es6一个用于服务器,一个用于浏览器。下面我们来看看这些规范的写法和使用情况

amd

amd是最早的模块规范,在amd之前我们引入的js文件都是通过script标签,但是这有一些问题,首先引入会导致全局变量冲突,污染。然后就是需要确保顺序。由于这些原因开发者一直在找一个合理的解决方法,此时amd规范应运而生。

amd用法
 // 定义
define('demo', ['helper'] ,function(helper) {
function init() {
 console.log('init')
}

return { init }
})

// 定义
define(function(require, exports, module) {
  exports.init = function(){}
});
// 使用
require(['demo'], function(demo) {
  demo.init();
})
  • 每个js的变量都是定义在function里面不会造成全局的污染,
  • amd是异步加载的,并且加载完之后立马执行
  • 如何确保加载时候的依赖了,模块定义的时候会传入一个依赖数组,根据这个依赖数组去加载依赖
  • amd推崇依赖前置,先把依赖写好

cmd

cmd的写法其实和amd很像的是推广 seajs孕畜出的一种规范

  define(function(require, exports, module) {
      const test = require('./test.js');
     
      // exports.test = test; 
     module.exports.test = test;
 })

// cmd也可以写成amd的依赖形式
define('demo', ['helper'] ,function(helper) {
function init() {
 console.log('init')
}

return { init }
})
// 使用
require(['demo'], function(demo) {
  demo.test();
})
  • cmd只能写成局部的reqiure,不能像amd那样可以引入require,生成全局的require
  • cmd默认是同步加载的,当然让我们也可以设置异步加载 require.async
  • 其实amd,cmd都需要和require打交道,我们的例子是最简单的用法,require中有许多比较重要的配置比如paths, shim, map等,因为现在的amd,cmd用的比较少,今后遇到实际项目再去讲require相关的配置
  • cmd推荐就近依赖,依赖下载完之后遇到require才去执行
  • cmd规范推崇一个文件就是一个模块,所以模块名一般定义为文件名

commonJs

commonJs规范是定义在node里面的,node环境提供了一个全局变量exports,后来又允许了module.exports的写法,以下是commonJS规范的写法

// test.js
function test() {
  console.log('test');
}
exports.test = test;

// 使用
const test = require('./test');
  • 这样的写法就更加的简洁了,但是记住在浏览器不借助其他工具,直接运行时会报错的,因为没有exports
  • commonJs虽然是同步加载,但是运行在服务器端,读取文件更快
  • 我们经常在react项目里面写的const style = require('./index.less');能这么写是因为你有webpack工具帮你转换了,查看打包之后的结果你会发现,他其实把commonJS语法打包成了浏览器可识别的amd语法
exports 和module.exports的区别

说到他们的区别你只需要记住以下三点就行

  • module.exports默认是空对象{}
  • exports 是module.exports的引用
  • 模块导出的是module.exports的内容
    所以以下代码就是这样
exports.init  等价于 module.exports.init

exports.init = function() {};
module.exports = { name: 2};  // 由于module.exports地址更新,默认又是导出module.exports,所以exports.init 无效,最终结果是{ name: 2}

umd

umd就比较简单一点,就是amd规范和commonJS规范的合并,判断支不支持define,支持的话就用amd,不支持的话在看看支持module.exports么,支持的话就用coomonJS,以下是他的代码

(function (root, factory) {
    if (typeof define === 'function' && define.amd) {
        // AMD. Register as an anonymous module.
        define(['b'], factory);
    } else if (typeof module === 'object' && module.exports) {
        // Node. Does not work with strict CommonJS, but
        // only CommonJS-like environments that support module.exports,
        // like Node.
        module.exports = factory(require('b'));
    } else {
        // Browser globals (root is window)
        root.returnExports = factory(root.b);
    }
}(this, function (b) {
    //use b in some fashion.

    // Just return a value to define the module export.
    // This example returns an object, but the module
    // can return a function as the exported value.
    return {};
}));

es6模块

es6的语法应该是我们最熟悉的了,不过低版本的浏览器不会识别,所以需要借助打包工具去解析。以下是es6模块的代码

// 定义test.js
export var a = 3;

// 引入
import { a } from './test'

es6 export的讲解

之前对export比较了解,但是看了阮一峰老师的es6模块讲解,觉得还是有必要在总结下。

export必须要一个接口

这个是什么意思,就是说export出去的东西,是要具有名字的,一个特定的值。你需要给名字,import才能接收,看以下代码

var a = 2;
export a; // error 错误a还是一个值

var a = function() {}
export a; // erro 错误a是一个匿名函数,但是如果是一个具名函数就行

export function a () {};; // right 这样就是可以的

export const a = function() {} // right 或者这样也是可以的

// 如果要写成匿名函数抛出的话可以放在{}里面
var a = function() {}
var b = 4;
export { a, b } // 此时接口就是a, b了;

// export可以抛出多个
export var a = 1;
export var b = 2;

// 对应的接收就是
import * as demo from './test';

// 接收一个就是
import {  a } from './test';
export default

上面说了export的几种情况,在来看看export default,他和export正好相反不需要接口因为default就是接口。并且只能有一个export default,看以下代码的讲解

var a = 1;

export default a; // right
export default var a = 1; // error 错误default已经是接口了,不需要再定义接口

// 只能有一个export default
export default 1;
export default 2; // 错误只能有一个export default

// import的接收
import test from './test'; test可以是任意的 

疑问

注意:测试都是在webpack打包环境下测试的

  • demo文件里面既有export var demo = 12还有export default 13那么import demo from返回的是什么

解释import demo返回的是export default 的内容,如果没有export default了?没有export default返回的是undefined,记住返回undefined是因为demo文件里面写了 export var demo = 12,如果都没写的话返回{}

  • 文件里面既有export还有export default那么import * 返回的是什么

import * 返回的是export和export default的合集,形式如这样{a: 1, default: 2};,因为default也是一个默认接口

  • 文件里面既没有export也没有export default。import * , import test from 和import { test } from 返回什么

都没有的话import *会返回一个空对象, import test from也会返回一个{},import {test} from 会返回undefined

  • 文件里面是module.exports={test: 12},import *, impoert test from , import { test } from 返回什么

import * 返回{test: 12}, import test from返回{test: 12}, import { test } from 返回12

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,222评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,455评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,720评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,568评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,696评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,879评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,028评论 3 409
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,773评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,220评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,550评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,697评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,360评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,002评论 3 315
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,782评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,010评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,433评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,587评论 2 350

推荐阅读更多精彩内容