Как повторно использовать модули commonjs в браузере и на сервере с помощью modulr?

Я использую modulr для использования модулей commonjs в браузере. Цель состоит в том, чтобы иметь возможность повторно использовать некоторые из этих модулей также в серверной среде.

Эти «общие» модули должны делать что-то вроде этого:

var _ = _ || require("underscore");

имея в виду:

  • если _ существует как глобальная переменная (среда браузера), используйте ее
  • иначе загрузите модуль подчеркивания (сервер) и используйте его вместо

Теперь, поскольку modulr выполняет статический анализ всего кода, ища вызовы require для генерации окончательного файла js, сборка завершится ошибкой.

Есть ли способ обойти эту проблему?

(Например, если modulr поддерживает что-то вроде параметра --ignore=<module_list>, все будет работать нормально.)


person ivo    schedule 08.08.2011    source источник


Ответы (1)


По-видимому, в модуле нет способа исправить это, поэтому мне пришлось создать модуль обходного пути с именем Env, который выглядит так:

// Env.js

var my = {
    modules: undefined,
    require: require
};

exports.override = function(modules) {
    my.modules = modules;
};

exports.require = function(path) {
    if (my.modules && my.modules[path]) {
        return my.modules[path];
    } else {
        // my.require(...) is needed instead of simply require(...)
        // because simply require(...) will cause a modulr parsing failure
        return my.require(path);
    }
}; 

А на стороне клиента есть специальный инициализатор, который:

// ClientInitializer.js
Env = require('shared/Env');
Env.override({ underscore: _ });

Итак, «общие» модули могут:

// SharedModule.js
var _ = require('shared/Env').require('underscore');  

Если на сервере работает «общий» модуль, вызывается обычная функция require. Если он запущен в браузере, модуль Env ответит глобальной переменной _.

person ivo    schedule 09.08.2011