require как в ноде
Когда-то давно не имел представления, как сделать включение скриптов в браузере как в ноде. Сегодня опыта немного больше. Посидев пару десятков минут, сделал. Есть более функциональные импортеры модулей, этот мини скрипт создан чисто из спортивного интереса. Может быть кому-то это покажется полезным.
Функция require принимает на себя два параметра: адрес скрипта и опциональный колбек. Если колбек не указан, то запрос на сервер будет идти синхронно, а возвращаться будет модуль. Если не указан, то возвращается null, а аргументом коллбека будет модуль. Пример: var module = require('module.js'); // module теперь извлекаемый модуль //... или var module; require('module.js', function( m ){ module = m; //... }); Пример файла модуля: var local = 'local'; exports.method1 = function(){ alert('method 1, local=' + local) }; this.method2 = function(){ alert('method 2') }; Собственно, функция require: window.require = function require(path, callback) { var req = new XMLHttpRequest(), module = null, async = !! callback, createModule = function (text) { return (new Function('var exports = this;' + text + '; return this;')).call({}); }; req.open('GET', path, async); req.onreadystatechange = function () { if (req.readyState === 4) { if (req.status === 200) { module = createModule(req.responseText); callback && callback(module); } else { throw new Error('Module ' + path + ' not found'); } } }; req.send(null); return module; }; |
Цитата:
|
|
Цитата:
Цитата:
|
Кеширования загруженного не хватает, чтоб одно и тоже по 5 раз не грузилось.
|
а если скрипт на другом домене ?
|
<script src="anotherDomain.js"></script> |
tadjik1,
Тогда вся концепция экспортов разлетается. В общем загрузка модулей это актуально, но таким подходом написанном на коленке ничего не добиться. |
Цитата:
Цитата:
Цитата:
|
Nekromancer, а какой подход по-твоему был бы хорош?
|
Цитата:
Цитата:
Во первых конечно система модулей должна быть от части уникальной, для той или иной архитектуры сервера. Во вторых должна быть какая то система, а не как например попытки вконтакт сделать нечто подобное. Хороший пример в Яндексе, во внутреннем коде не копался, но это наверно единственные кто для синхронной загрузки модуля используют document.write. Это именно тут случай, когда нужен это инструмент. Ещё просматривал всякие реализации, даже посмотрел видео презентацию от "ведущего" разработчика в мейл.ру. Меня вот например не могло не "порадовать" исполнение кода через onclick и называя это всё "возможностью из коробки". |
Цитата:
Цитата:
|
Цитата:
Да, вот ещё. Почему должно? Кеширование заголовками это один способ, но не единственный. Например часто можно на вопрос - Почему сервер не присылает Etag? - услышать, - А зачем? Last-Modified достаточно. А ещё аргументируют это лишней нагрузкой на сервер :) |
Цитата:
|
Цитата:
FINoM, и вообще ты так споришь против кеширования, как будто это что-то сложное, там же 2 строчки дописать и готово. |
Цитата:
Как кажется правильным так и пишу. |
Цитата:
Цитата:
|
Riim, мне тупо было интересно как зареквайрить скрипт подобно ноде. Я сделал то что хотел.
А здесь можно добавить очень много полезных вещей, как вызов сразу нескольких модулей (как в requirejs), совмещение нескольких модулей в одном, пресловутое кеширование... Но делать это просто лень. Я не для использования писал этот код, а для того, чтоб показать забавную вещицу (по крайней мере, для меня забавную). Если хотите большего, не проблема, пишите, я не накладываю никаких ограничений на свой код :D |
Цитата:
|
Kolyaj,
Это в Яндекс картах, флаг useDocumentWrite. |
Цитата:
|
Цитата:
|
Kolyaj,
тут разве есть что то плохое? |
Цитата:
|
FINoM,
Я не понимаю по каким данным ты судишь, что крайне редко. Для обычных сайтов - да, вообще не надо. Но для них и модули не нужны. Помнится ты сам просил уроки о том, как создавать правильные веб приложения. |
Цитата:
В случае API карт, очевидно, подключаются не модули, а сам API. |
Kolyaj,
Этим же document.write можно запросить сразу все модули которые в зависимости, то есть будет на один запрос больше. |
А почему сразу все не запросить? Без document.write?
|
Kolyaj,
потому, что формируется один статический файл в котором основное управление. Я думаю можно конечно вставить в тело документа все нужные скрипты для данной страницы. Но я решил попробовать систему хранения скриптов в storage. Если пользователь активный посетитель ресурса, то у него должна быть уже большая часть скриптов. П.С. Это конечно сомнительное преимущество, но всё же. |
Цитата:
Цитата:
|
Цитата:
Цитата:
|
Думать, как её решать. В спешке писал.
Цитата:
|
Цитата:
|
Цитата:
|
Развил сабж: http://pastebin.com/zWUcBare
Теперь можно запрашивать модули кучей: require(['m1', 'm2']);Если не использовать коллбек, то объекты просто конкатенируются. Например: // m1 this.method1 = function(){}; this.method2 = function(){}; // m2 this.method3 = function(){}; this.method4 = function(){}; require(['m1', 'm2']);Возвращает объект с этими четырьмя методами. Если использовать коллбек, то в него передаются модули в том же порядке, что и массив скриптов: require(['m1', 'm2'], function( m1, m2 ){ ... }); Добавил пару настроек: require.PATH = '/'; // папка, в которой лежат модули, например, /js/modules require.POSTFIX = ''; // постфикс (ко) адреса скрипта, например, '.js' или '.module.js' require.CONCAT_ALL = false; // в коллбек передаётся один аргумент: объект со всеми модулями сразу // например require(['m1', 'm2'], function( all ){ // all == {method1: ...,method2: ...,method3: ...,method4: ... } });В будущем все-таки добавлю кеширование и запросы к модулям на другом домене (cors) |
Модульность это хорошо. Но все почему-то забывают, что скрипту могут понадобиться и другие данные, например HTML-разметка (шаблоны) или стили.
Поэтому нужно грузить XML-файл, в котором будут все эти данные. Что бы это было на уровне API функции require. Это ИМХО) |
Цитата:
Цитата:
|
Цитата:
|
Цитата:
Да и вообще, к черту XML, если есть JSON. По крайней мере 99% задач, которые решаются XML можно решить JSON. Он компактнее, читабельнее, дружит с JS. |
Цитата:
Цитата:
Цитата:
|
Часовой пояс GMT +3, время: 19:45. |