Require.js 甚至在 IF 语句中加载模块

Bar*_*eby 1 javascript jquery amd requirejs

我在通过 require.js 加载某些 .js 模块时发现了一些问题 问题是:我只需要加载某些页面中的某些模块,而不是整个网站。因此,我以这种方式放置代码:

if($('.module-news').length > 0 + $('.module-ticket-euromillones-multiple').length + $('.module-news-page').length > 0) {
            require('_modules/news-grid').init();
        }
Run Code Online (Sandbox Code Playgroud)

如果class="module-news"存在(新闻页面),则此代码在 HTML 中搜索。如果是这样,则使用 javascript 加载模块。

那是行不通的。IF 评估正确,但无论 .module-news 是否存在,模块news-grid总是在加载。

我发现如果我更改变量的模块路径字符串,则 requires 行为正确,但这没有意义。这如何,以下代码有效:

var name = "_modules/news-grid";

if($('.module-news').length > 0 + $('.module-ticket-euromillones-multiple').length + $('.module-news-page').length > 0) {
                require(name).init();
            }
Run Code Online (Sandbox Code Playgroud)

这是需要的已知问题吗?我错过了什么吗?(也许在 requirejs.config 设置中?

帮助表示赞赏

Lou*_*uis 5

解决方案

您应该使用常规的 RequireJS 习语来调用require

if (...) {
    require(['_modules/news-grid'], function (news_grid) {
        news_grid.init();
    });
}
Run Code Online (Sandbox Code Playgroud)

为什么失败

您正在使用 RequireJS 的功能,它允许您require以 CommonJS 格式编写调用var module = require("module name")您不能使用它来有条件地加载模块。

调用require('module name')(使用字符串作为第一个参数而不是依赖数组)很方便。它将返回一个模块,但当且仅当该模块已加载。如果模块尚未加载,则调用将失败。您不必担心在调用之前预加载模块的唯一原因require('module name')是 RequireJS 为您做这件事。

define(function (require) {
    var foo = require('foo');
});
Run Code Online (Sandbox Code Playgroud)

被 RequireJS 解释为:

define(['require', 'foo'], function (require) {
    var foo = require('foo');
});
Run Code Online (Sandbox Code Playgroud)

它扫描函数以查找requireCommonJS 惯用法中的调用,并生成在执行模块之前加载的模块列表。条件对这个过程是完全透明的。任何require将字符串作为第一个参数的调用都将被检测到,并且它意味着要加载的模块将被添加到define调用 的回调之前加载的依赖项中...

RequireJS 不会检测传递给require. 如果你写:

var name = "foo";
var foo = require(name);
Run Code Online (Sandbox Code Playgroud)

RequireJS 不会知道您要加载foo,也不会添加foo到依赖项列表中。这是一个解决方案吗?不,因为请记住我之前所说的require('module name')将返回一个模块,并且不会失败,仅当该模块已加载时

如果你希望你的模块有条件地加载,那么放弃 CommonJS 习惯用法。