сценарий requirejs, не относящийся к amd, требует глобальной зависимости от модуля amd

#javascript #requirejs #amd

#javascript #requirejs #amd

Вопрос:

Я пытаюсь создать конфигурацию прокладки в RequireJS, которая сводится к этому примеру:

 requirejs.config({
    paths:{
        'non-amd-script' : 'path-to/non-amd-script', 
        'amd-module' : 'path-to/amd-module'
    },
    shim: {
        'non-amd-script' : { deps: ['amd-module'] }
    }
});
 

Эти сценарии (по крайней мере, один из модулей, отличных от amd) были «разработаны» для включения как:

 <script src="amd-module'></script>
<script src="non-amd-script'></script>
 

Но я хочу загружать их асинхронно, с зависимостями и еще много чего, используя RequireJS.

Важное замечание:

  1. (это то, что движет моим вопросом) оба non-amd-script и amd-module являются неизменяемыми сценариями (т. Е. Они Предоставляются, и я не могу изменить их источник, поскольку изменения теряются при обновлении этих сценариев).
  2. Я генерирую свои конфигурации shim с помощью PHP (не спрашивайте …), И я не могу «понюхать» эти крайние случаи.

Чего я хочу

Если требуется для страницы, я инициирую загрузку non-amd-script с помощью require-call:

 require(['non-amd-script'], function(loadedModule) { //do stuff if the module returns stuff });
 

Проблема

Хотя это работает ( amd-module сначала загружается, затем non-amd-script ), оказывается, что non-amd-script требуется возврат amd-module в глобальную переменную.

Речь amd-module идет о микромодале, который, если он загружен на странице, будет зарегистрирован в window.MicroModal , но поскольку он поддерживает модуль, он не будет этого делать при загрузке через requirejs.

Тот факт, что он поддерживает модуль, сделает любую дополнительную конфигурацию прокладки неэффективной (например exports , или init ), поскольку они будут игнорироваться для модулей AMD (AFAIK).

Что я пробовал

Одно «решение», которое я пробовал и которое работает, заключается в следующем:

     shim: {
        'non-amd-script' : {
            deps: ['amd-module'],
            init: function(MicroModal) { window.MicroModal = MicroModal; return this; } 
        }
    }
 

Но я действительно не чувствую себя комфортно, используя это, потому что, как уже было сказано, я генерирую свои конфигурации shim с помощью PHP и должен сделать это для некоторых / множества других сценариев (возможно, с теми же проблемами).

Мой вопрос

Как я могу сделать non-amd-script игру приятной с amd-module тем, от чего это зависит, если последний не регистрирует ни один из глобалов, используемых в non-amd-script ?

Спасибо!

Ответ №1:

Вы можете создать прокси-модуль, который потребует amd-module и сделает его глобальным. Мы можем вызвать это amd-module-proxy . Затем вы можете использовать его в оболочке в качестве зависимости для non-amd-script .

Вот пример кода:

 // amd-module-proxy.js
define(['amd-module'], function (MicroModal) {
  window.MicroModal = MicroModal;
});
 
 requirejs.config({
    paths:{
        'non-amd-script' : 'path-to/non-amd-script', 
        'amd-module' : 'path-to/amd-module',
        'amd-module-proxy': 'path-to/amd-module-proxy'
    },
    shim: {
        'non-amd-script' : { deps: ['amd-module-proxy'] }
    }
});
 

Комментарии:

1. Спасибо за ваш ответ, Дамиан! Это элегантное решение, которое я также рассмотрел. Но это очень специфично для сценария; Я ищу способ заставить его работать без необходимости устанавливать какие-либо конкретные глобальные переменные. В этом случае я в основном хочу перевести оба встроенных <script> в requirejs, и поскольку я автоматизирую включение всех JS для страницы (для обработки с помощью requirejs), я генерирую пути и конфигурации прокладки, и я не могу оценить каждый скрипт, чтобы увидеть, какой (если есть) требуются глобальные переменные. Если бы я только мог поместить amd-модуль в область действия, отличную от amd-script, или наоборот…

2. @c_kick Я не знаю ни о каком общем решении, извините:(

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