Javascript 在我提到文件名之前,requirejs如何知道加载所需的js文件?
我在看@Domenic使用requirejs的简单示例,答案如下: 我把它包括在这里 shirt.js: logger.js: main.js: main.html: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
发生了一些非常奇怪的事情:
在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
这里似乎有一些非常鬼鬼祟祟的魔法。
所以我很想知道:
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
调用。本机AMDrequire
调用将依赖项数组作为第一个参数,并将解析的模块传递给可选回调
这在多大程度上可以依赖
我已经依赖CommonJS sugar完成了数百个模块,没有问题
此模式的一个限制是,如果您尝试将字符串文字以外的内容传递给require
。例如,如果您这样做:
define(function (require) {
var shirtName = "./shirt";
var shirt = require(shirtName);
这将抛出RequireJS。它不会检测到您的模块需要/shirt
模块,您将得到上面提到的错误
如何修改此示例以避免依赖鬼鬼祟祟的魔法
对于我们这些不相信鬼鬼祟祟的魔法的人来说,在使用requirejs时有没有办法禁用它
没有可以用来阻止RequireJS支持CommonJS sugar的标志。如果您不想在自己的代码中依赖它,您可以像我在前面的代码片段中所示那样对模块进行编码:calldefine
,将依赖项列表作为第一个参数,并将模块作为回调的参数
话虽如此,我看不出有什么好的理由这么做。我已经使用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();
});