2013-07-30 2 views
4

Рассмотрим это:RequireJS - Загрузка модулей AMD как внутри требуют расхода и встроенного

<script src='global.js'></script> 
<script src='require.js'></script> 
<script> 
require(['modular_foo'], function() { 
    //do stuff 
}); 

... и в боковых global.js у нас есть, среди прочего:

//global.js 
$.getScript("modular_bar.js"); 

, где оба modular_foo и modular_bar - анонимно определенные модули AMD. Используя requireJS, загрузка чего-то вроде выше даст вам нашу любимую ошибку, mismatched anonymous define() modules.

Достаточно хорошо, почему эта ошибка возникает (прочитайте эту страницу, если хотите узнать), но проблема в том, что, если вы не можете выйти из этой ситуации?

Я работаю на установленной платформе, которая постепенно переходит на поток RJS, так как теперь нет возможности использовать как встроенные устаревшие скрипты (некоторые из которых имеют проверку AMD для запуска define()), и наш requireJS точка входа одновременно.

В некоторых случаях я могу просто разместить встроенные скрипты, совместимые с AMD, после загрузки библиотеки require.js, но это не работает, если вам нужно асинхронно загружать другие вещи (modular_bar.js) в зависимости от содержимого DOM. Я мог бы также просто прокомментировать все проверки AMD из файлов, загружаемых извне в RJS, но это мешает им несовместимо с тем, что они загружаются в модульный поток.

У кого-нибудь из нас было такое же впечатление? Как вы смешиваете свои потоки, чтобы преодолеть подобные конфликты?

ответ

0

У меня нет опыта использования этого решения в производственной среде, но я потратил пару дней на этот вопрос, выяснив наилучший способ приблизиться к нему.

Вы можете использовать модифицированную библиотеку RequireJS, которая не позволяет анонимному define выполнить, если он передается через eval. Кроме того, вы можете запретить любые вызовы define, удалив проверку типа для строки на name в фрагменте ниже.

Следующий фрагмент является модификацией RequireJS, который будет игнорировать анонимный, если он вызван eval. Вы можете найти fully modified require.js in this GitHub Gist.

Код основывается на parse-stack library. Если вы не можете включить библиотеку до RequireJS, я предлагаю просто конкатенировать ее в верхней части файла.

Demo

// This is a snippet of RequireJS 
// ... 
define = function (name, deps, callback) { 
    var node, context; 

    // We will allow named modules to be defined by `eval` 
    if (!(typeof name == 'string' || name instanceof String)) 
    { 
     var stack = parseStack(new Error()); 

     // If we find any eval in the stack, do not define the module 
     // This is to avoid the "Mismatched anonymous define() module" error 
     // Caused by executing an anonymous define without requireJS 
     for(var i = 0; i < stack.length; i++) 
     { 
      if(stack[i].name == "eval") 
      { 
       return; 
      } 
     } 
    } 

    // ...