博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Simplified CommonJS wrapper 与 AMD 标准定义模块差异
阅读量:6708 次
发布时间:2019-06-25

本文共 2216 字,大约阅读时间需要 7 分钟。

标准的 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:本文译自

转载地址:http://tkilo.baihongyu.com/

你可能感兴趣的文章
Linux磁盘分区
查看>>
渠道统计比较的优缺点
查看>>
实现MySQL分库分表备份的脚本
查看>>
Confluence 6 找到你的支持识别代码(SEN)
查看>>
Confluence 6 配置手动备份
查看>>
网络互连
查看>>
Linux系统,分区错误,根分区磁盘满了
查看>>
员工如何在人工智能时代证明其IT工作价值
查看>>
DevExpress 小贴士
查看>>
在流行的PHP库中发现了用于创建PDF文件的严重安全漏洞
查看>>
仿百思不得其姐项目开发(粗略笔记,后期规范排版和更新)
查看>>
iOS开发之网络编程--小文件下载
查看>>
Nginx配置之location模块和proxy模块
查看>>
Convert SVG to PDF by using iText in Java(ZT)
查看>>
Mybatis分页插件 - PageHelper很好很强大,转载
查看>>
Java,php,Python连接并操作redis实例
查看>>
研磨设计模式之工厂方法模式-3 ——跟着cc学设计系列
查看>>
军哥独家QCIE(囊括CCIE和HCIEv3.0)的全新课程。请大家参阅
查看>>
我的友情链接
查看>>
Openstack组建部署 — Glance Install
查看>>