Pull to refresh

JavaScript loader без define

Reading time2 min
Views9.8K
Привет Хабр!

Всем известно решение задачи загрузки скриптов.
Например Curl.JS, Require.JS, + популярные frameworks умеют это тоже.

MAIN UPDATE: В комментариях всё обсудили. Спасибо azproduction и nuit за идейные комментарии, а ainu за моральную поддержку.

Из комментариев ясно, что 100% лучше использовать LMD, т.к. там всё то же что здесь рассказано, только есть учет зависимостей, кеша и т.п. И, да, оно изобретено гораздо раньше, т.е. было первей!

Что такое LMD: читаем уважаемого azproduction.

Под катом остался код, который можно использовать в ознакомительных целях для ответа на вопрос почему написан MAIN UPDATE, то есть почему нужно использовать LMD вместо того что под катом.
Так же важно что оператор 'with' в настоящий момент Deprecated.



Все это написано с учетом ссылки.

Приводится исключительно код загрузчика, никаких дополнительных аспектов, которые учтены в LMD — нет.

UPD: сделано в попытке реализовать в browser то как работает mozIJSSubScriptLoader и/или Components.utils.import для расширений Firefox.

Т.е., загрузить скрипт, при этом переопределив его scope.

Пример.

Пара ссылок на начальные исходники: Раз и Два

Финальный код для загрузчика скриптов в виде метода для jQuery:

(function( jQuery, undefined ){
jQuery.loadSubScript = function( url, scope, thisName, returnCallback ){
    // если не передан scope сделаем его глобальным
    var scope = scope || window;
    // аналогично
    var thisName = thisName || window;
    
    $.ajax( {
          url: url
        , type: 'GET'
        , dataType: 'text'
        , success: function( data ){
            try{
                
                // создаем полученный код, не забываем про with
                var fns = new Function( 

                         'with( this ){ return ' 
                                + Function.apply( null, [ data ] )
                                + '; }' 

                );

                // инициализируем замыкание с with
                fns = fns.call( scope );
                // инициализируем замыкание с this
                var turn = fns.call( thisName );
                // возвращаем результат в callback, если он есть
                returnCallback && returnCallback( turn );
                
            }catch(e){ alert(e); }
        }
        , error: function( jqXHR, textStatus, errorThrown ){ 
                alert('Loader Error:\n' + errorThrown ); 
        }
    } );        
};
})( jQuery );


Так же есть НЕ Плагин, в котором реализуется метод noConflict, позволяющий убрать код загрузчика из window ( jQuery по прежнему используется для $.ajax ).

Что можно получить с помощью данного кода:

  • Просто загрузить скрипт в глобальный объект: window.
  • Загрузить скрипт с «подменой» scope: window + YourOwnScopObject.
  • Загрузить скрипт с подменой ему this.
  • Вернуть что-нибудь в callback, например, просто написав в вашем загружаемом скрипте return.
  • Избавиться от define().


Конечно, если что нибудь будет нести var, то оно будет внутри созданного замыкания. Без var, как и должно быть — попадет в window. То, что является методами переданного в scope объекта будет доступно без точки. С this — всё как обычно, в случае его подмены.

Ограничения: локальные файлы в Google Chrome и Opera.
Для Chrome лечится запуском с ключом: --allow-file-access-from-files.

Но лучше, всё же использовать LMD.

Пользуйтесь на здоровье!

Ссылка на GIT

Best Regards!

PS: Не знаю какую лицензию выбрать, наверное MIT + GPLv3.
Tags:
Hubs:
Total votes 12: ↑8 and ↓4+4
Comments18

Articles