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

Javascript 在我提到文件名之前,requirejs如何知道加载所需的js文件?,javascript,requirejs,Javascript,Requirejs,我在看@Domenic使用requirejs的简单示例,答案如下: 我把它包括在这里 shirt.js: logger.js: main.js: main.html: 发生了一些非常奇怪的事情: 在main.js中使用shirt.color的位置, shirt.js和logger.js刚刚被安排异步加载(我猜想), 所以shirt.js实际上还没有被阅读过。我之所以认为加载是异步的,是因为我的印象是,在chrome的javascript中,同步加载几乎是非法的(XMLHttpRequ

我在看@Domenic使用requirejs的简单示例,答案如下: 我把它包括在这里

shirt.js:

logger.js:

main.js:

main.html:


发生了一些非常奇怪的事情: 在main.js中使用
shirt.color
的位置, shirt.js和logger.js刚刚被安排异步加载(我猜想), 所以shirt.js实际上还没有被阅读过。我之所以认为加载是异步的,是因为我的印象是,在chrome的javascript中,同步加载几乎是非法的(XMLHttpRequest仍然有一个同步选项,但如果使用,它会在chrome控制台上发出警告主线程上的同步XMLHttpRequest会因其对最终用户体验的有害影响而被弃用。)

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

这怎么可能

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

这里似乎有一些非常鬼鬼祟祟的魔法。 所以我很想知道:

  • requirejs是如何在任何请求之前加载shirt.js的
  • 这在多大程度上可以依赖
  • 如何修改此示例以避免依赖鬼鬼祟祟的魔法
  • 对于我们这些不相信鬼鬼祟祟的魔法的人来说,在使用requirejs时有没有办法禁用它
  • requirejs是如何在任何请求之前加载shirt.js的

    这是您的模块:

    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
    的回调中调用时才能工作。否则,就会出现可怕的错误。)

    此功能称为“CommonJS sugar”因为CommonJS本机支持使用单个参数(字符串)并返回模块的
    require
    调用。本机AMD
    require
    调用将依赖项数组作为第一个参数,并将解析的模块传递给可选回调

    这在多大程度上可以依赖

    我已经依赖CommonJS sugar完成了数百个模块,没有问题

    此模式的一个限制是,如果您尝试将字符串文字以外的内容传递给
    require
    。例如,如果您这样做:

    define(function (require) {
        var shirtName = "./shirt";
        var shirt = require(shirtName);
    
    这将抛出RequireJS。它不会检测到您的模块需要
    /shirt
    模块,您将得到上面提到的错误

    如何修改此示例以避免依赖鬼鬼祟祟的魔法

    对于我们这些不相信鬼鬼祟祟的魔法的人来说,在使用requirejs时有没有办法禁用它

    没有可以用来阻止RequireJS支持CommonJS sugar的标志。如果您不想在自己的代码中依赖它,您可以像我在前面的代码片段中所示那样对模块进行编码:call
    define
    ,将依赖项列表作为第一个参数,并将模块作为回调的参数

    话虽如此,我看不出有什么好的理由这么做。我已经使用RequireJS多年了,如果有什么问题的话,我一直在将使用
    define
    的代码与依赖CommonJS的代码列表一起移动。我发现后者更适合各种开发工具

    <script data-main="../js/main" src="../js/require.js"></script>
    
    define(function (require) {
        var shirt = require("./shirt");
        var logger = require("./logger");
    
        alert("Shirt color is: " + shirt.color);
        logger.logTheShirt();
    });
    
    define(["require", "./shirt", "./logger"], function (require) {
        var shirt = require("./shirt");
        var logger = require("./logger");
    
        alert("Shirt color is: " + shirt.color);
        logger.logTheShirt();
    });
    
    define(function (require) {
        var shirtName = "./shirt";
        var shirt = require(shirtName);
    
    define(["./shirt", "./logger"], function (shirt, logger) {
        alert("Shirt color is: " + shirt.color);
        logger.logTheShirt();
    });