Node-style требуется для javascript в браузере?



существуют ли какие-либо библиотеки для javascript в браузере, которые обеспечивают такую же гибкость/модульность/простоту использования, как и Node's require?



чтобы предоставить более подробную информацию: причина require так хорошо, что это:




  1. позволяет динамически загружать код из других мест (что стилистически лучше, на мой взгляд, чем связывать весь ваш код в HTML)

  2. это обеспечивает последовательный интерфейс для построения модулей

  3. это легко для модулей зависеть от других модулей (поэтому я мог бы написать, например, API, который требует jQuery, чтобы я мог использовать jQuery.ajax()

  4. загруженный javascript - это scoped, то есть, я мог бы загрузить с var dsp = require("dsp.js"); и я смогу получить доступ dsp.FFT, что не помешало бы моему местному var FFT


я пока не нашел библиотеку, которая делает это эффективно. Обходные пути, которые я обычно использую являются:




  • coffeescript-concat -- достаточно легко требовать другие js, но вы должны скомпилировать его, что означает, что он менее подходит для быстрой разработки (например, создание API в тесте)


  • RequireJS -- это популярно, просто и решает 1-3, но отсутствие области видимости-это настоящий нарушитель сделки (я считаю головы.js похоже на то, что ему не хватает объема, хотя у меня никогда не было повода использовать его. Точно так же,LABjs загрузить и .wait() смягчает проблемы зависимости, но он все еще не делает область видимости)



насколько я могу судить, существует множество решений для динамической и/или асинхронной загрузки javascript, но они, как правило, имеют те же проблемы с областью действия, что и просто загрузка js из HTML. Больше всего мне хотелось бы загрузить javascript, который вообще не загрязняет глобальное пространство имен, но все же позволяет мне загружать и используйте библиотеки (так же, как требует узел).



EDIT (МОЙ ОТВЕТ): С момента написания этого, я широко используется RequireJS (который теперь имеет гораздо более четкую документацию). RequireJS действительно был правильным выбором, на мой взгляд. Я хотел бы пояснить, как система работает для людей, которые так же смущены, как и я:



можно использовать require в повседневной разработке. Модуль может быть чем угодно возвращенным функцией (обычно объектом или объектом). функция) и определяется как параметр. Вы также можете скомпилировать проект в один файл для развертывания с помощью r.js (на практике это почти всегда быстрее, даже если require можно загружать скрипты параллельно).



основное различие между RequireJS и node-style require like browserify (классный проект, предложенный tjameson) использует то, как модули разработаны и требуются:




  • RequireJS использует AMD (определение асинхронного модуля). В AMD,require принимает список модулей (файлов javascript) для загрузки и функции обратного вызова. Когда он загрузил каждый из модулей, он вызывает обратный вызов с каждым модулем в качестве параметра обратного вызова. Таким образом, он действительно асинхронный и поэтому хорошо подходит для интернета.

  • узел использует CommonJS. В CommonJS,require - Это блокирующий вызов, который загружает модуль и возвращает ее как объект. Это отлично работает для узла, потому что файлы считываются с файловой системы, что достаточно быстро, но плохо работает на web, потому что загрузка файлов синхронно может занять гораздо больше времени.


на практике многие разработчики использовали Node (и, следовательно, CommonJS), прежде чем они когда-либо видели AMD. Кроме того, многие библиотеки/модули написаны для CommonJS (путем добавления вещей в exports "объект"), а не для AMD (возвращая модуль от

632   7  

7 ответов:

проверить Эндер. Он делает многое из этого.

и browserify - это очень хорошо. Я использовал требуются-поцелуй и это работает. Возможно, есть и другие.

Я не уверен в RequireJS. Это просто не совпадает узла. Вы можете столкнуться с проблемами с загрузкой из других мест, но это может сработать. Пока есть метод provide или что-то, что можно вызвать.

TL; DR- я бы рекомендовал browserify или require-kiss.

обновление:

require-kiss теперь мертв, и автор удалил его. С тех пор я использую RequireJS с тех пор без проблем. Автор require-kiss написал pakmanager и Пакман. Полное раскрытие информации, я работаю с разработчиком.

лично мне нравится RequireJS лучше. Это намного проще отлаживать (вы можете иметь отдельные файлы в разработке и один развернутый файл в производство) и строится на твердом "стандарте".

Я написал небольшой скрипт, который позволяет асинхронную и синхронную загрузку JavaScript-файлов, которые могут быть полезны здесь. Он не имеет зависимостей и совместим с узлом.js & CommonJS. Вы даже можете объединить несколько модулей в один файл, чтобы уменьшить количество HTTP-запросов на рабочих серверах. Использование довольно легко:

<script type="text/javascript" src="require.js"></script>
<script type="text/javascript">
    var ModuleA = require('modulea') // Sync loading of a script in the module directory
    ModuleA.funcA();

    require('./path/moduleb.js', callbackB); // Async loading of a script anywhere else
    function callbackB(ModuleB) {
        ModuleB.funcB();
    }
</script>

более подробную информацию и код можно найти в моем блоге: http://pixelsvsbytes.com/2013/02/js-require-for-browsers-better-faster-stronger/ Код также находится на GitHub:https://github.com/letorbi/smoothie/blob/master/standalone/require.js

вариация Илья Харламов отличный ответ, С некоторым кодом, чтобы он играл хорошо с инструментами разработчика chrome.

//
///- REQUIRE FN
// equivalent to require from node.js
function require(url){
    if (url.toLowerCase().substr(-3)!=='.js') url+='.js'; // to allow loading without js suffix;
    if (!require.cache) require.cache=[]; //init cache
    var exports=require.cache[url]; //get from cache
    if (!exports) { //not cached
            try {
                exports={};
                var X=new XMLHttpRequest();
                X.open("GET", url, 0); // sync
                X.send();
                if (X.status && X.status !== 200)  throw new Error(X.statusText);
                var source = X.responseText;
                // fix (if saved form for Chrome Dev Tools)
                if (source.substr(0,10)==="(function("){ 
                    var moduleStart = source.indexOf('{');
                    var moduleEnd = source.lastIndexOf('})');
                    var CDTcomment = source.indexOf('//@ ');
                    if (CDTcomment>-1 && CDTcomment<moduleStart+6) moduleStart = source.indexOf('\n',CDTcomment);
                    source = source.slice(moduleStart+1,moduleEnd-1); 
                } 
                // fix, add comment to show source on Chrome Dev Tools
                source="//@ sourceURL="+window.location.origin+url+"\n" + source;
                //------
                var module = { id: url, uri: url, exports:exports }; //according to node.js modules 
                var anonFn = new Function("require", "exports", "module", source); //create a Fn with module code, and 3 params: require, exports & module
                anonFn(require, exports, module); // call the Fn, Execute the module
                require.cache[url]  = exports = module.exports; //cache obj exported by module
            } catch (err) {
                throw new Error("Error loading module "+url+": "+err);
            }
    }
    return exports; //require returns object exported by module
}
///- END REQUIRE FN
(function () {
    // c is cache, the rest are the constants
    var c = {},s="status",t="Text",e="exports",E="Error",r="require",m="module",S=" ",w=window;
    w[r]=function R(url) {
        url+=/.js$/i.test(url) ? "" : ".js";// to allow loading without js suffix;
        var X=new XMLHttpRequest(),module = { id: url, uri: url }; //according to the modules 1.1 standard
        if (!c[url])
            try {
                X.open("GET", url, 0); // sync
                X.send();
                if (X[s] && X[s] != 200) 
                    throw X[s+t];
                Function(r, e, m, X['response'+t])(R, c[url]={}, module); // Execute the module
                module[e] && (c[url]=module[e]);
            } catch (x) {
                throw w[E](E+" in "+r+": Can't load "+m+S+url+":"+S+x);
            }
        return c[url];
    }
})();

лучше не использовать в производстве из-за блокировки. (В узлах.js, require () - это блокирующий вызов хорошо).

Webmake связывает модули в стиле узла в браузер,попробуйте.

Require-stub - обеспечивает узел-уступчивый require в браузере разрешает как модули, так и относительные пути. Использует технику, аналогичную TKRequire (XMLHttpRequest). Результирующий код полностью browserifyable, в том, что require-stub может служить заменой для watchify.

вот расширение фантастического ответа Лусио М. Тато, которое позволяет рекурсивно загружать модули с относительными путями.

здесь проект github для размещения решения и пример того, как его использовать:

https://github.com/trausti/TKRequire.js

для использования TKRequire.js, включите следующую строку в свой заголовок

затем загрузить модули так же, как в узле.js:

var MyModule = require("./ relative / path/to / MyModule.js");

Comments

    Ничего не найдено.