在我提到文件名之前,requirejs 是如何知道加载所需的 js 文件的?
how does requirejs know to load a required js file before I ever mention the file name?
我正在查看@Domenic 使用 requirejs 的简单示例,来自这个答案:
simple example for using require.js
我把它包括在这里。
shirt.js:
define({
color: "black",
size : "large"
});
logger.js:
define(function (require) {
var shirt = require("./shirt");
return {
logTheShirt: function () {
console.log("color: " + shirt.color + ", size: " + shirt.size);
}
};
});
main.js:
define(function (require) {
var shirt = require("./shirt");
var logger = require("./logger");
alert("Shirt color is: " + shirt.color);
logger.logTheShirt();
});
main.html:
<script data-main="../js/main" src="../js/require.js"></script>
发生了一些非常奇怪的事情:
在 main.js 中使用 shirt.color
的地方,
shirt.js 和 logger.js 刚刚被安排异步加载(我想),
所以 shirt.js 还没有真正被阅读过。我认为加载是异步的原因是我的印象是同步加载在 javascript in chrome 中几乎是非法的(XMLHttpRequest 仍然可以选择同步,但如果使用,它会警告chrome 控制台 Synchronous XMLHttpRequest on the main thread is deprecated because of its detrimental effects to the end user's experience.
).
然而,这个小应用程序似乎运行可靠。
如果我将 "./shirt.js"
替换为 url 引用另一个资源,它甚至可以可靠地工作
在世界的另一端,我在加载 html 页面之前清除了浏览器缓存。
怎么会这样??
如果我查看 chrome 开发控制台中的计时,似乎耗时的 shirt.js 加载
实际上 在 请求它的函数甚至启动之前发生了。
IE。它以某种方式知道在程序中任何引用“./shirt”的内容之前加载 shirt.js。
这里似乎发生了一些非常狡猾的魔法。
所以我很想知道:
- requirejs 怎么知道在任何请求之前加载 shirt.js?
- 这在多大程度上可以依赖?
- 如何修改此示例以避免依赖偷偷摸摸的魔法?
- 对于我们这些不相信偷偷摸摸的魔法的人来说,有没有办法在使用 requirejs 时禁用它?
how did requirejs know to load shirt.js before anything asked for it?
这是你的模块:
define(function (require) {
var shirt = require("./shirt");
var logger = require("./logger");
alert("Shirt color is: " + shirt.color);
logger.logTheShirt();
});
当调用 define
时,RequireJS 检测到它是在没有依赖列表的情况下调用的。因此,它会扫描您传递的 require
调用实例的回调,该调用采用单个参数(字符串文字),然后获取单个参数并制作这些参数的列表,并将其作为模块的依赖项列表.您的模块在功能上等同于此:
define(["require", "./shirt", "./logger"], function (require) {
var shirt = require("./shirt");
var logger = require("./logger");
alert("Shirt color is: " + shirt.color);
logger.logTheShirt();
});
因此 ./shirt
和 ./logger
在实际调用回调之前加载。然后当执行 require("./shirt")
和 require("./logger")
时,它们只是在已加载模块的映射中查找。 (并且,因此,在传递给 [=14= 的回调中调用时,使用单个字符串参数调用 require
只能 工作。否则,你会得到可怕的 "Module has not been loaded yet for context" 错误。)
此功能称为 "CommonJS sugar",因为 require
使用单个参数(字符串)和 returns 模块的调用是 CommonJS 本机支持的。本机 AMD require
调用将依赖项数组作为第一个参数和一个可选的回调,已解析的模块将传递给该回调。
to what extent can this be relied on?
我已经在数百个模块中使用 CommonJS 糖,没有任何问题。
此模式的一个限制是,如果您尝试将字符串文字以外的其他内容传递给 require
。例如,如果您这样做:
define(function (require) {
var shirtName = "./shirt";
var shirt = require(shirtName);
这将抛出 RequireJS。它不会检测到您的模块需要 ./shirt
模块,您会收到我上面提到的错误。
how would one modify this example to avoid relying on the sneaky magic?
define(["./shirt", "./logger"], function (shirt, logger) {
alert("Shirt color is: " + shirt.color);
logger.logTheShirt();
});
for those of us who don't trust sneaky magic, is there a way to disable it when using requirejs?
没有标志可以用来阻止 RequireJS 支持 CommonJS 糖。如果你想避免在你自己的代码中依赖它,你可以像我在前面的代码片段中展示的那样编写你的模块:调用 define
并将依赖项列表作为第一个参数,并将模块作为参数你的回调。
话虽这么说,但我认为没有充分的理由这样做。我已经使用 RequireJS 多年,如果有的话,我一直在将使用 define
和依赖项列表的代码移动到依赖 CommonJS 糖的代码。我发现后者与各种开发工具配合使用效果更好。
我正在查看@Domenic 使用 requirejs 的简单示例,来自这个答案: simple example for using require.js 我把它包括在这里。
shirt.js:
define({
color: "black",
size : "large"
});
logger.js:
define(function (require) {
var shirt = require("./shirt");
return {
logTheShirt: function () {
console.log("color: " + shirt.color + ", size: " + shirt.size);
}
};
});
main.js:
define(function (require) {
var shirt = require("./shirt");
var logger = require("./logger");
alert("Shirt color is: " + shirt.color);
logger.logTheShirt();
});
main.html:
<script data-main="../js/main" src="../js/require.js"></script>
发生了一些非常奇怪的事情:
在 main.js 中使用 shirt.color
的地方,
shirt.js 和 logger.js 刚刚被安排异步加载(我想),
所以 shirt.js 还没有真正被阅读过。我认为加载是异步的原因是我的印象是同步加载在 javascript in chrome 中几乎是非法的(XMLHttpRequest 仍然可以选择同步,但如果使用,它会警告chrome 控制台 Synchronous XMLHttpRequest on the main thread is deprecated because of its detrimental effects to the end user's experience.
).
然而,这个小应用程序似乎运行可靠。
如果我将 "./shirt.js"
替换为 url 引用另一个资源,它甚至可以可靠地工作
在世界的另一端,我在加载 html 页面之前清除了浏览器缓存。
怎么会这样??
如果我查看 chrome 开发控制台中的计时,似乎耗时的 shirt.js 加载 实际上 在 请求它的函数甚至启动之前发生了。 IE。它以某种方式知道在程序中任何引用“./shirt”的内容之前加载 shirt.js。
这里似乎发生了一些非常狡猾的魔法。 所以我很想知道:
- requirejs 怎么知道在任何请求之前加载 shirt.js?
- 这在多大程度上可以依赖?
- 如何修改此示例以避免依赖偷偷摸摸的魔法?
- 对于我们这些不相信偷偷摸摸的魔法的人来说,有没有办法在使用 requirejs 时禁用它?
how did requirejs know to load shirt.js before anything asked for it?
这是你的模块:
define(function (require) {
var shirt = require("./shirt");
var logger = require("./logger");
alert("Shirt color is: " + shirt.color);
logger.logTheShirt();
});
当调用 define
时,RequireJS 检测到它是在没有依赖列表的情况下调用的。因此,它会扫描您传递的 require
调用实例的回调,该调用采用单个参数(字符串文字),然后获取单个参数并制作这些参数的列表,并将其作为模块的依赖项列表.您的模块在功能上等同于此:
define(["require", "./shirt", "./logger"], function (require) {
var shirt = require("./shirt");
var logger = require("./logger");
alert("Shirt color is: " + shirt.color);
logger.logTheShirt();
});
因此 ./shirt
和 ./logger
在实际调用回调之前加载。然后当执行 require("./shirt")
和 require("./logger")
时,它们只是在已加载模块的映射中查找。 (并且,因此,在传递给 [=14= 的回调中调用时,使用单个字符串参数调用 require
只能 工作。否则,你会得到可怕的 "Module has not been loaded yet for context" 错误。)
此功能称为 "CommonJS sugar",因为 require
使用单个参数(字符串)和 returns 模块的调用是 CommonJS 本机支持的。本机 AMD require
调用将依赖项数组作为第一个参数和一个可选的回调,已解析的模块将传递给该回调。
to what extent can this be relied on?
我已经在数百个模块中使用 CommonJS 糖,没有任何问题。
此模式的一个限制是,如果您尝试将字符串文字以外的其他内容传递给 require
。例如,如果您这样做:
define(function (require) {
var shirtName = "./shirt";
var shirt = require(shirtName);
这将抛出 RequireJS。它不会检测到您的模块需要 ./shirt
模块,您会收到我上面提到的错误。
how would one modify this example to avoid relying on the sneaky magic?
define(["./shirt", "./logger"], function (shirt, logger) {
alert("Shirt color is: " + shirt.color);
logger.logTheShirt();
});
for those of us who don't trust sneaky magic, is there a way to disable it when using requirejs?
没有标志可以用来阻止 RequireJS 支持 CommonJS 糖。如果你想避免在你自己的代码中依赖它,你可以像我在前面的代码片段中展示的那样编写你的模块:调用 define
并将依赖项列表作为第一个参数,并将模块作为参数你的回调。
话虽这么说,但我认为没有充分的理由这样做。我已经使用 RequireJS 多年,如果有的话,我一直在将使用 define
和依赖项列表的代码移动到依赖 CommonJS 糖的代码。我发现后者与各种开发工具配合使用效果更好。