gpt4 book ai didi

javascript - 在我提到文件名之前,requirejs 如何知道加载所需的 js 文件?

转载 作者:行者123 更新时间:2023-12-03 05:02:14 25 4
gpt4 key购买 nike

我正在寻找 @Domenic 使用 requirejs 的简单示例,来自这个答案: simple example for using require.js我将其包含在这里。

衬衫.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 刚刚被安排异步加载(我猜),所以衬衫.js实际上还没有被读取。我认为加载是异步的原因是我的印象是同步加载在chrome中的javascript中几乎是非法的(XMLHttpRequest仍然有一个同步选项,但如果使用,它会在chrome控制台上发出警告 Synchronous XMLHttpRequest在主线程上已被弃用,因为它会对最终用户的体验产生不利影响。)。

然而,这个小应用程序似乎运行可靠。如果我用引用另一个资源的 url 替换 "./shirt.js" ,它甚至可以可靠地工作在加载 html 页面之前,我会清除浏览器缓存。

怎么会这样?

如果我查看 chrome 开发控制台中的计时,就会发现耗时的shirt.js 加载实际上发生在请求它的函数启动之前。IE。不知何故,它知道在程序中引用“./shirt”的任何内容之前加载shirt.js。

这里似乎发生了一些非常狡猾的魔法。所以我有兴趣知道:

  1. requirejs 如何知道在任何请求之前加载衬衫.js?
  2. 这在多大程度上可以信赖?
  3. 如何修改此示例以避免依赖鬼鬼祟祟的魔法?
  4. 对于我们这些不相信鬼鬼祟祟的魔法的人来说,有没有办法在使用 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") 时,它们只是在已加载模块的映射中查找。 (因此,使用单个字符串参数调用 require 只能在传递给 define 的回调中调用时才有效。否则,你会得到可怕的 "Module has not been loaded yet for context" 错误。)

此功能称为“CommonJS 糖”,因为使用单个字符串参数并返回模块的 require 调用是 CommonJS 本身支持的功能。 native 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 糖的代码。我发现后者与各种开发工具配合使用效果更好。

关于javascript - 在我提到文件名之前,requirejs 如何知道加载所需的 js 文件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42172792/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com