Странное поведение с RequireJS с использованием синтаксиса CommonJS

У меня странное поведение с RequireJS, использующим синтаксис CommonJS. Я постараюсь как можно лучше объяснить контекст, над которым я работаю.

У меня есть файл JS с именем Controller.js, который регистрирует события ввода (щелчок) и использует серию операторов if для выполнения правильного действия. Типичный блок операторов if может быть следующим.

if(something) {

    // RequireJS syntax here

} else if(other) { // ...

Чтобы реализовать синтаксис RequireJS, я попробовал два разных шаблона. Первый из них следующий. Это стандартный способ загрузки модулей.

if(something) {
    require(['CompositeView'], function(CompositeView) {

        // using CompositeView here... 

    });

} else if(other) { // ...

Вместо этого второй использует синтаксис CommonJS, например

if(something) {
    var CompositeView = require('CompositeView');

    // using CompositeView here... 

} else if(other) { // ...

Оба шаблона работают, как и ожидалось, но я заметил странное поведение через Firebug (то же самое происходит с инструментом Chrome). В частности, при использовании второго файл CompositeView уже загружен, даже если я не следую ветке, которая управляет конкретным действием в ответ на условие something. Наоборот, при первом решении файл загружается по запросу.

Я что-то упускаю? Это из-за переменного подъема?


person Lorenzo B    schedule 18.11.2013    source источник
comment
Это не из-за переменного подъема. Я бы проверил, чтобы убедиться, что вы явно не импортируете этот скрипт каким-либо другим способом, потому что то, что вы описываете, на самом деле не должно происходить.   -  person Pointy    schedule 18.11.2013
comment
@Pointy Спасибо за ваш комментарий. Я проверил дважды, но не могу понять проблему. Да, поднять не проблема, но я просил только подтверждение...   -  person Lorenzo B    schedule 18.11.2013
comment
Дополнение Tamper Data для Firefox или собственные инструменты разработчика браузера, как правило, могут показать вам все происходящие HTTP-запросы. Вы должны очистить свой кеш и убедиться, что в версии с обратным вызовом (что в любом случае является правильным способом сделать что-то) вы определенно не импортируете скрипт, когда ваш код принимает ветвь else.   -  person Pointy    schedule 18.11.2013


Ответы (1)


Это ограничение поддержки стиля CommonJS require. В документации объясняется примерно следующее:

define(function (require) {
    var dependency1 = require('dependency1'),
        dependency2 = require('dependency2');

    return function () {};
});

переводится RequireJS в:

define(['require', 'dependency1', 'dependency2'], function (require) {
    var dependency1 = require('dependency1'),
        dependency2 = require('dependency2');

    return function () {};
});

Обратите внимание, как аргументы двух вызовов require становятся частью массива, передаваемого в define.

То, что, как вы говорите, вы наблюдали, согласуется с тем, что RequireJS проникает внутрь if и вытягивает требуемый модуль до define, так что он всегда загружается, даже если ветвь не используется. Единственный способ предотвратить постоянную загрузку модуля RequireJS — это то, что вы уже обнаружили: вам нужно использовать require с обратным вызовом.

person Louis    schedule 18.11.2013
comment
Спасибо. Ты прав. Основываясь на исходном коде, RequireJS найдет этот шаблон на любом уровне и добавит дополнительные зависимости, как вы описали (см. функцию define в строке 1984). - person Lorenzo B; 18.11.2013