标准的 AMD 模块定义

一个标准的 AMD 模块看起来是这样子:

define(['foo', 'foo/bar'], function (foo, bar) {
return {
doSomething: function () {
console.log(foo + bar);
}
};
});

模块 foofoo/bar 在工厂函数被调用之前完成加载,并作为参数传递给工厂函数。

工作原理:

  1. RequireJS 读取依赖模块数组。
  2. 继而检查当前上下文是否已注册这些依赖模块:
    1. 如果模块已注册,则直接使用;
    2. 否则:
      1. 通过检查 paths.config 和当前模块路径,将模块 ID 解析为 URI。
      2. 加载 URI 指向的源文件。
      3. 如果依赖模块是 AMD 模块,则重复以上过程直至所有依赖模块被加载完毕。
  3. 当所有依赖模块准备妥当,将依赖模块作为参数去调用工厂函数,工厂函数的返回值作为新模块被注册到当前上下文。

Simplified CommonJS wrapper

如果你想让别人像 CommonJS 模块那样使用你的模块,尤其是你的模块拥有大量依赖模块,你可以使用 Simplified CommonJS wrapper。

define (function (require, exports, module) {
var foo = require('foo'),
bar = require('foo/bar'); exports.doSomething = function () {
console.log(foo + bar);
};
});

一个模块被当做 CommonJS 模块,它必须不能包含依赖模块数组,并且工厂函数包含至少一个参数。

工作原理:

  1. RequireJS 检查 define 函数调用是否没有使用依赖模块数组。
  2. 然后通过读取 Function.prototype.length 来检查工厂是否接受参数。
    1. 如果接受参数,则将该模块视为 CommonJS 模块:

      1. 调用 Function.prototype.toString(),并找到所有工厂函数中所有同步的 require() 调用来确定依赖模块。
      2. 加载所有依赖模块。
      3. 完成依赖模块加载后,将特殊模块 require, exportsmodule 作为参数传递给工厂函数,然后将函数返回值或 module.exportsexports 注册为新模块。
    2. 如果不接受参数,则将该模块视为标准 AMD 模块(没有依赖包),执行工厂函数并注册函数返回值为新模块。

同步 require()

对于一个标准的 AMD 模块,只要模块在当前上下文注册,你可以同步调用 require() 函数。

define (['require', 'lorem/ipsum'], function (require) {
// 因为模块 lorem/ipsum 在依赖数组中。
// 它会在工厂函数被调用前完成注册,因此本段代码是可行的。
console.log(require('lorem/ipsum'));
});

但以下代码会因为 dolor/amet 未注册而失败:

define(['require'], function (require) {
console.log(require('dolor/amet'));
});

因为我们在 define 函数中使用了依赖数组,因此新模块将被视为标准 AMD 模块,因此它不会扫描工厂函数代码以获取依赖数组。你将看到以下异常提示:

Uncaught Error: Module name 'dolor/amet' has not been loaded yet for context: _

如果使用 Simplified CommonJS Wrapper,那么 RequireJS 会在工厂函数调用前加载依赖包:

define (function (require) {
console.log(require('dolor/amet'));
});

特殊模块

标准 AMD 模块中同样可以使用特殊模块 require, exportsmodule

exports

define (['exports'], function (exports) {
exports.foo = 'bar';
exports.lorem = function (){
console.log('ipsum');
};
});

添加到 exports 上的属性会自动成为模块的公开接口,工厂函数无需返回值。

module

以下模块记录了模块 ID 和当前模块的路径。

define (['module'], function (module){
console.log(module.id);
console.log(module.uri);
});

require

require 模块除了可以加载依赖模块,还可以指出模块源文件路径。

  • require.toUrl(moduleName): 返回模块源文件路径。

PS:本文译自 Differences between the Simplified CommonJS wrapper and standard AMD define

Simplified CommonJS wrapper 与 AMD 标准定义模块差异的更多相关文章

  1. UMD、CommonJS、ES Module、AMD、CMD模块的写法

    AMD异步模块规范 RequireJS就是AMD的一个典型的实现. 以下是一个只依赖与jQuery的模块代码: // foo.js define(['jquery'], function($){ // ...

  2. Javascript模块化编程之CommonJS,AMD,CMD,UMD模块加载规范详解

    JavaSript模块化 在了解AMD,CMD规范前,还是需要先来简单地了解下什么是模块化,模块化开发?     模块化是指在解决某一个复杂问题或者一系列的杂糅问题时,依照一种分类的思维把问 题进行系 ...

  3. 前端笔记之ES678&Webpack&Babel(下)AMD|CMD规范&模块&webpack&Promise对象&Generator函数

    一.AMD和CMD规范(了解) 1.1传统的前端开发多个js文件的关系 yuan.js中定义了一个函数 function mianji(r){ return 3.14 * r * r } main.j ...

  4. 学习笔记:CommonJS规范、AMD规范

    CommonJS规范 http://wiki.jikexueyuan.com/project/webpack-handbook/commonjs.html CommonJS 规范 http://www ...

  5. AMD规范中模块id的命名规则

    AMD 即 Asynchronous Module Definition, 中文是“ 异步模块定义”的意思. AMD 规范制定了定义模块的规则,这样模块和模块的依赖可以被异步加载. AMD 规范只定义 ...

  6. IT项目角色标准定义

    角色 角色标准定义 项目主管 负责协助项目经理分配资源,确定优先级,协调公司和项目组之间的沟通.保证项目团队一直处于良好的状态中.同时监督项目经理的工作方法,以确保项目以及工件符合公司的发展方向以及用 ...

  7. 浏览器加载和渲染HTML的过程(标准定义的过程以及现代浏览器的优化)

    先看一下标准定义的浏览器渲染过程(网上找的): 浏览器打开网页的过程 用户第一次访问网址,浏览器向服务器发出请求,服务器返回html文件: 浏览器开始载入html代码,发现 head 标签内有一个 l ...

  8. Lua标准库- 模块(Modules)

    Lua包库为lua提供简易的加载及创建模块的方法,由require.module方法及package表组成 1.module (name [, ···]) 功能:建立一个模块. module的处理流程 ...

  9. Python(2.7.6) 标准日志模块 - Logging Handler

    Python 标准日志模块使用 Handler 控制日志消息写到不同的目的地,如文件.流.邮件.socket 等.除了StreamHandler. FileHandler 和 NullHandler ...

随机推荐

  1. paip.抓取网页内容--java php python

    paip.抓取网页内容--java php python.txt 作者Attilax  艾龙, EMAIL:1466519819@qq.com 来源:attilax的专栏 地址:http://blog ...

  2. ServiceStack Web Service 创建与调用简单示列

    目录 ServiceStack 概念 ServiceStack Web Service 创建与调用简单示列 上篇文章介绍了ServiceStack是什么,本章进入主题,如何快速简单的搭建Service ...

  3. Leetcoede 112 Path Sum 二叉树

    二叉树的从叶子到根的和是否存在 /** * Definition for binary tree * struct TreeNode { * int val; * TreeNode *left; * ...

  4. hdu 2844 多重背包coins

    http://acm.hdu.edu.cn/showproblem.php?pid=2844 题意: 有n个硬币,知道其价值A1.....An.数量C1...Cn.问在1到m价值之间,最多能组成多少种 ...

  5. 一个映射到mac风格按键的AHK脚本(替换虚拟机键盘映射)

    Mac键位映射(部分) win+q 退出程序 win+w 关闭当前页面 win+h 隐藏当前窗口 win+shift+h 隐藏其他窗口 win+s 保存 win+o 打开 win+z 撤销 win+s ...

  6. Android 代理服务器为全网提供代理

    Android 代理服务器为全网提供代理 背景:学校WiFI过滤较严,故学生很少有可以上网账号的.而学校又分为俩层验证,第一层可以注册并且拥有访问校内网的权限,第二层为校内密码验证机(非服务器)进行用 ...

  7. #入魔这些年#零度智控&模型控社区大型征文活动,万元大奖等你拿

        玩航模是个好爱好,它能培养严谨的科学态度.超强的DIY动手能力.规范的项目管理习惯.良好的沟通合作技巧.过人的三维空间思维和感知: 你需要的知识储备有力学.空气动力学.电子学.通讯工程.材料学 ...

  8. Swift入门篇-基本类型(2)

    现在我也在学习Swift语言,常常去逛很多苹果社区和论坛,看到了圈子很多奇怪的现象,发现很多人都赶忙去翻译 Swift书籍 和 发布Swift的视频 .他们这种对新知识的探索精神我本人是很佩服的.但是 ...

  9. 如何在maven项目的pom.xml文件中添加jar包

    在使用maven进行项目开发时,我们需要在pom.xml文件中添加自己所需要的jar包.这就要求我们获取jar包的groupId和artifactId. 我们可以在一些maven仓库上搜索我们所需要的 ...

  10. Android系列---JSON数据解析

    您可以通过点击 右下角 的按钮 来对文章内容作出评价, 也可以通过左下方的 关注按钮 来关注我的博客的最新动态. 如果文章内容对您有帮助, 不要忘记点击右下角的 推荐按钮 来支持一下哦 如果您对文章内 ...