Я создаю небольшое приложение с клиентом JavaScript (запускается в браузере) и сервером Node.js, общение с помощью WebSocket.
Я хотел бы поделиться кодом между клиентом и сервером. Я только начал с Node.js, и мои знания современного JavaScript немного устарели, если не сказать больше. Так что я до сих пор разбираюсь с функцией CommonJS require (). Если я создаю свои пакеты, используя объект «export», я не вижу, как я могу использовать те же файлы JavaScript в браузере.
Я хочу создать набор методов и классов, которые используются на обоих концах для облегчения кодирования и декодирования сообщений и других зеркальных задач. Тем не менее, системы упаковки Node.js / CommonJS, похоже, не позволяют мне создавать файлы JavaScript, которые можно использовать с обеих сторон.
Я также попытался использовать JS.Class для получения более узкой модели ОО, но я сдался, потому что не мог понять, как заставить предоставленные файлы JavaScript работать с require (). Есть ли что-то, что я здесь упускаю?
источник
Ответы:
Если вы хотите написать модуль, который можно использовать как на стороне клиента, так и на стороне сервера, у меня есть короткое сообщение в блоге о быстром и простом методе: написание для Node.js и браузера , по сути, следующее (где
this
то же самое, что иwindow
) :В качестве альтернативы есть несколько проектов, направленных на реализацию API Node.js на стороне клиента, например, Gemini Марака .
Возможно, вас также заинтересует DNode , который позволяет вам предоставлять функцию JavaScript, чтобы ее можно было вызывать с другого компьютера, используя простой сетевой протокол на основе JSON.
источник
У Epeli есть хорошее решение здесь http://epeli.github.com/piler/, которое работает даже без библиотеки, просто поместите это в файл с именем share.js
На стороне сервера просто используйте:
А на стороне клиента просто загрузите файл js, а затем используйте
источник
Извлеките исходный код jQuery, который делает это в шаблоне модуля Node.js, шаблоне модуля AMD и глобальном в браузере:
источник
Не забывайте, что строковое представление функции JavaScript представляет исходный код этой функции. Вы можете просто написать свои функции и конструкторы инкапсулированным образом, чтобы они могли быть toString () 'd и отправлены клиенту.
Другой способ сделать это - использовать систему сборки, поместить общий код в отдельные файлы, а затем включить их в сценарии сервера и клиента. Я использую этот подход для простой клиент-серверной игры через WebSockets, где сервер и клиент выполняют по существу один и тот же игровой цикл, а клиент синхронизируется с сервером каждый тик, чтобы никто не обманывал.
Моя система сборки для игры - это простой Bash- скрипт, который запускает файлы через препроцессор C, а затем через sed, чтобы очистить некоторые ненужные cpp-остатки, так что я могу использовать все обычные препроцессоры, такие как #include, #define, #ifdef , и т.д.
источник
Я бы рекомендовал смотреть в адаптер RequireJS для Node.js . Проблема состоит в том, что шаблон модуля CommonJS, используемый по умолчанию Node.js, не является асинхронным, что блокирует загрузку в веб-браузере. RequireJS использует шаблон AMD, который является асинхронным и совместимым как с сервером, так и с клиентом, если вы используете
r.js
адаптер.источник
Возможно, это не совсем соответствует вопросу, но я подумал, что поделюсь этим.
Я хотел сделать пару простых строковых утилит, объявленных в String.prototype, доступными как для узла, так и для браузера. Я просто храню эти функции в файле с именем utilities.js (во вложенной папке) и могу легко ссылаться на него как из тега script в моем коде браузера, так и с помощью require (без расширения .js) в моем скрипте Node.js :
my_node_script.js
my_browser_code.html
Я надеюсь, что это полезная информация для кого-то, кроме меня.
источник
utilites.js
в одной строкеmodule.exports = require('./static/js/utilities');
. Таким образом, вам нужно обновить только один путь, если вы перемешиваете вещи вокруг.utilities.js
находится вshared
папке под проектом. Использованиеrequire('/shared/utilities')
дало мне ошибкуCannot find module '/shared/utilities'
. Я должен использовать что-то подобное,require('./../../shared/utilities')
чтобы это работало. Таким образом, он всегда идет из текущей папки и перемещается вверх, а затем вниз.Если вы используете упаковщики модулей, такие как веб- пакет, для объединения файлов JavaScript для использования в браузере, вы можете просто повторно использовать свой модуль Node.js для внешнего интерфейса, запущенного в браузере. Другими словами, ваш модуль Node.js может использоваться совместно с Node.js и браузером.
Например, у вас есть следующий код sum.js:
Обычный модуль Node.js: sum.js
Используйте модуль в Node.js
Повторно использовать его в интерфейсе
источник
Сервер может просто отправлять исходные файлы JavaScript клиенту (браузеру), но хитрость заключается в том, что клиенту необходимо предоставить мини-среду «экспорта», прежде чем он сможет выполнить
exec
код и сохранить его как модуль.Простой способ создать такую среду - использовать замыкание. Например, скажем, ваш сервер предоставляет исходные файлы через HTTP, как
http://example.com/js/foo.js
. Браузер может загрузить необходимые файлы через XMLHttpRequest и загрузить код следующим образом:Ключевым моментом является то, что клиент может обернуть внешний код в анонимную функцию для немедленного запуска (замыкание), которая создает объект «export» и возвращает его, чтобы вы могли назначить его там, где хотите, а не загрязнять глобальное пространство имен. В этом примере он назначен атрибуту окна,
fooModule
который будет содержать код, экспортированный файломfoo.js
.источник
window.fooModule = {}; (new Function('exports', xhr.responseText))(window.fooModule)
.Ни одно из предыдущих решений не выводит модульную систему CommonJS в браузер.
Как уже упоминались в других ответах, есть управляющие активы / упаковочные решения , такие как Browserify или штабелер и есть RPC решение , такая как dnode или nowjs .
Но я не смог найти реализацию CommonJS для браузера (включая
require()
функцию иexports
/module.exports
objects и т. Д.). Поэтому я написал свою собственную, но потом обнаружил, что кто-то другой написал ее лучше, чем я: https://github.com/weepy/brequire . Это называется Brequire (сокращение от Browser требуется).Судя по популярности, управляющие активами соответствуют потребностям большинства разработчиков. Однако, если вам нужна браузерная реализация CommonJS, Brequire , вероятно, подойдет.
Обновление 2015: я больше не использую Brequire (он не обновлялся в течение нескольких лет). Если я просто пишу небольшой модуль с открытым исходным кодом и хочу, чтобы кто-нибудь мог его легко использовать, то я буду следовать схеме, аналогичной ответу Каолана (см. Выше) - я написал в блоге об этом пару лет тому назад.
Однако, если я пишу модули для частного использования или для сообщества, которое стандартизировано в CommonJS (например, сообщество Ampersand ), тогда я просто напишу их в формате CommonJS и использую Browserify .
источник
now.js также стоит посмотреть. Это позволяет вам вызывать серверную часть со стороны клиента, а клиентские функции - со стороны сервера.
источник
Если вы хотите написать свой браузер в стиле, похожем на Node.js, вы можете попробовать удвоить .
Нет компиляции кода браузера, поэтому вы можете написать свое приложение без ограничений.
источник
Напишите ваш код в виде модулей RequireJS, а ваши тесты - в качестве тестов Jasmine .
Таким образом, код может быть загружен везде с помощью RequireJS, и тесты можно запускать в браузере с помощью jasmine-html и с помощью jasmine-node в Node.js без необходимости изменять код или тесты.
Вот рабочий пример для этого.
источник
Вариант использования: поделитесь конфигурацией вашего приложения между Node.js и браузером (это всего лишь иллюстрация, вероятно, не лучший подход в зависимости от вашего приложения).
Проблема: вы не можете использовать
window
(не существует в Node.js) иglobal
(не существует в браузере).Решение:
Файл config.js:
В браузере (index.html):
Теперь вы можете открыть инструменты разработчика и получить доступ к глобальной переменной
config
В Node.js (app.js):
С Babel или TypeScript:
источник
shared.js
иhelpers.js
-shared.js
использует функции изhelpers.js
, поэтому он должен бытьconst { helperFunc } = require('./helpers')
вверху, чтобы он работал на стороне сервера. Проблема на клиенте, он жалуется на то, что онrequire
не является функцией, но если я обертываю строку requireif (typeof module === 'object') { ... }
, сервер говорит, что helperFunc () не определен (вне оператора if). Любые идеи, чтобы заставить это работать на обоих?shared.js
:helperFunc = (typeof exports === 'undefined') ? helperFunc : require('./helpers').helperFunc;
- К сожалению, понадобится строка для каждой экспортируемой функции, но, надеюсь, это хорошее решение?Я написал простой модуль , который можно импортировать (используя require в Node или теги script в браузере), который можно использовать для загрузки модулей как с клиента, так и с сервера.
Пример использования
1. Определение модуля
Поместите следующее в файл
log2.js
внутри вашей папки статических веб-файлов:Просто как тот!
2. Использование модуля
Поскольку это двусторонний загрузчик модулей, мы можем загрузить его с обеих сторон (клиента и сервера). Таким образом, вы можете сделать следующее, но вам не нужно делать оба сразу (не говоря уже в определенном порядке):
В Node все просто:
Это должно вернуться
2
.Если ваш файл не находится в текущем каталоге Node, обязательно позвоните
loader.setRoot
по пути к вашей статической папке веб-файлов (или где бы ни находился ваш модуль).Сначала определите веб-страницу:
Убедитесь, что вы не открываете файл прямо в вашем браузере; так как он использует AJAX, я предлагаю вам взглянуть на
http.server
модуль Python 3 (или каково ваше решение для развертывания суперскоростного сервера, командной строки, веб-сервера папок).Если все пойдет хорошо, появится следующее:
источник
Я написал это, это просто использовать, если вы хотите установить все переменные в глобальную область:
источник