Здравствуйте, друзья!
Простейший, казалось бы, вопрос, но через поиск ответ найти не могу.
Нашлась только эта http://clubs.ya.ru/bem/4080/ тема в клубах, я задал там вопрос, но не уверен в том, что тот сервис все еще работает, поэтому дублирую тут:
запускаю БЭМ-сервер и хотелось бы им аякс-запросы проксировать на бекенд (надоело использовать хром с опцией disable-web-security и костыль в коде), подскажите пожалуйста, можно ли это как-то настроить.
@KulakovSerg т.е. у нас есть отдельно машина разработчика, отдельно бекенд (?), и вам надо часть запросов отправить в bem-server (enb-server), а остальное на бекенд?
Классический вариант ответа — nginx ;-)
Но я бы попробовал и express+express-bem, https://github.com/zxqfox/express-bem у меня работало ;-)
upd: Кстати, еще есть вариант поднять bem-server через API на другом порту, и использовать что-то вроде http-proxy. см. https://github.com/nodejitsu/node-http-proxy + https://github.com/bem/bem-tools#api
У нас там здоровенный проект типа соцсети, поэтому клиентские и серверные разработчики отдельно, куча виртуалок под разные ветки разработки и т.д. и т.п.
Классически вариант не проксирует куки хоть застрелись (пересланные без изменений на локальный домен куки отвергаются браузером по причине несовпадения домена), а без кук бекенд не дает авторизацию и все аякс-запросы идут в лес. Я не силен в знании lua, поэтому китайские решения этой проблемы для проксирования кук в nginx раскочегарить не смог. Опять же, как-то странно уже имея в обязательном порядке nodejs ставить еще один веб-сервер каждому разработчику.
Да, можно наставить каждому в каждый браузер прокси-плагинов или поднять отдельные прокси-сервера, знаю, но в идеале хотелось бы обойтись минимумом стороннего софта, да еще и если какие-то пути в проекте сменятся, все эти настройки пойдут далеко и быстро, потому и спрашиваю, кто как решал проблему.
К тому же БЭМ-сервер в консоли пишет на соответсвующие запросы error 404, что и заронило в душу надежду на то, что его можно настроить =)
Упомянутый костыль с disable-web-security, обходящий политики безопасности для кроссдоменных запросов напрямую к серверу, рабочий только для хрома, поэтому у всех распрекрасно работал без всяких прочих извращений с проксированием, пока не понадобилось к релизу все досконально проверить в других браузерах.
По вашей ссылке вижу:
возможно, я Вас не так понял, но это совсем про другое - мне не нужна оптимизация рендеринга. Я мало знаком с nodejs и express, не могли бы вы мне словами пояснить что именно оттуда и для чего у Вас работало?
Не понял, к чему это? Порт и домен должны совпадать, чтобы аякс-запросы пришли куда нужно, иначе опять же проксирование и это ничем не отличается от того что я выше написал.
На момент написания вопроса я искал только гугле, но в яндексе, нашлось такое: http://ru.bem.info/tools/optimizers/borschik/borschik-server/ Кто разбирался, может знает, поможет ли оно для решения этой проблемы?
@KulakovSerg мне кажется, или вы правда используете bem-server как полноценный сервер для view, а не только для генерирования статики? Вы же понимаете, что bem-server'ом в продакшене пользоваться нельзя, он только для облегчения разработки предназначен?
nginx написал русский ;-) При чем тут китайцы? Куки передаются в заголовках — т.е. достаточно пробрасывать заголовок с куками. http://nginx.org/ru/docs/http/ngx_http_proxy_module.html#proxy_pass_header
На дев площадке у нас node.js работает на одном хосте, пхп на другом, на каждом стоит по nginx, и есть еще фронтовый на третьем хосте. В итоге рулится все сложно, но если упрощать, то получится примерно так:
На девелоперской машине останется только поднять ваш хост и проксировать нужные запросы к бекенду (например, /api, как в примере).
@apsavin:
отчего же Вы так плохо обо мне думаете? Или плохо читаете заголовок?
Именно поэтому я и предложил использовать node-http-proxy, вместо nginx.
Определитесь с тем, что вам нужно, потому что решений огромное кол-во.
китайцы пишут плагины на языке lua, который не является частью nginx, но может быть туда добавлен кастомной сборкой. По крайней мере я не специализируюсь в администрировании и после спрашивания у гугла такие плагины показались мне единственным решением)
@zxqfox, да, спасибо, так как Вы предлагаете скорее всего заработает...
Но БЭМ-сервер уже слушает этот порт, если включить и nginx то он перехватит запросы до ноды и туда просто ничего не попадет и не вернется назад соотвтетственно, а если я запущу еще что-то с node-http-proxy и попытаюсь слушать тот же порт что и БЭМ-сервер, то мне от БЭМ-сервера статика не отдастся.
В общем, мне кажется, что нужно как-то БЭМ-сервер настраивать чтобы он как-то запросамы к /api/ либо проксировал, либо куда-то по-другому обрабатывал, иначе никакой сторонний софт не поможет, хотя с node-http-proxy могу и ошибаться, не так глубоко разбираюсь в настройке веб-серверов как хотелось бы.
@KulakovSerg Само собой она слушает, можно либо на другой порт её перенести, либо на другом порту прокси поднять (и не важно, какой именно он будет).
Настраивать bem server в качестве прокси — вариант в корне неверный. Бэм сервер это софт, который занимается сборкой страниц, а не проксированием. У него есть конкретная задача. Правильнее всего в этом случае поставить прокси на основном порту, поднять бэм сервер на соседнем порту, и апи на третьем. И проблем нет, даже если у вас 10 бекендов, и все на разных серверах.
Запустить бэм сервер на соседнем порту —
bem server -p 65500
@zxqfox, извините если занимаю слишком много вашего времени, но хотелось бы уточнить.
Вот я запустил бэмсервер, он в консоль выдал ссылку для просмотра контента http://localhost:8080/ С самой страницы аякс-запросы выполнятются к http://localhost:8080/api/ соответственно, опять же в консоль бэмсервер ругается, что "HTTP error: 404, /home/user/project/api". Я так полагаю, что нужно запросы /home/user/project/api проксировать на путь истинный, куда-то в http://test.server.com/api/, каким-то образом сохраняя куки от игнорирования браузером.
Подскажите пожалуйста, как в nodejs написать что-либо, работающее (в том числе и с куками) аналогично тому конфигу nginx, что Вы привели выше?
@KulakovSerg ничего страшного ;-)
Запросы к /api выполняются из браузера. Bem server сам по себе собирает вам несколько разных файлов (обычно, html, js, css), и иногда еще фризит статику. Т.е. если вы с порта 8080 будете отдавать и статику, и ответы от бекенда — браузер ничего не заметит и куки будут приниматься нормально безо всяких хаков. Для этого и нужно поднять прокси на 8080 порту, который на стороне сервера сам будет делать запросы и к бекенду (если /api), и к bem serverу (если /*.bundles). Естественно, сохраняя куки в процессе проброса запросов.
Грубо говоря, нужно поднять bem server на порту 8081:
Нужно поднять некое прокси (например, это https://github.com/nodejitsu/node-http-proxy):
создаем index.js (на базе http и http-proxy):
И запускаем наш прокси веб сервер:
Ну вот примерно так ;-) Не тестировал
Upd: req.path заменил на req.url
@zxqfox, cпасибо, поcле обеда затестирую) Выглядит как самое простое решение
Если заработает, то будет на проекте еще один велосипед в дополнение к Jade-шаблонизатору (так уж исторически сложилось), Perl-бекенду (и это тоже, но кластер пашет шустро), трансллятору jade-шаблонов в perl-шаблонизатор на сервере (для отдачи статики поисковикам, perl совсем не понимать jade) и куче кастомных БЭМ-блоков под jade...
Добавлю, что на самом деле
bem server
— это достаточно простая штука, которая просто мапит урл из запроса в цель дляbem make
, ждет, пока цель соберется и отдает в браузер результат.Поэтому предлагаю рассмотреть схему с полным отказом от
bem server
в пользу вызоваbem make
через JS API из своего кастомного node-сервера в dev-окружении.Это может выглядеть как мидлварь (код не тестировал, на правах иллюстрации к идее):
@tadatuda благодарю, идея рабочая. Только вопрос, какое должен быть значение targets, если страницы лежат просто в desctop.bundles? Документации по .build не нашел, только по .make
@tadatuta А это уже очень близко с express-bem и express-bem-tools-make.
P.s. но тут возникает вопрос, как перенаправлять запросы к бекенду ;-)
@KulakovSerg Если
desctop
— это не опечатка, тоdesctop/page-name
(зачастую для серверных приложений используется общий бандл для всей статики, но если нужны разные, нужно будет получать текущую страницу из запроса).Если в консоль не сыпется никаких ошибок, то предположу, что виснет потому, что
make()
не отрабатывает и, соответственно,then()
не дергается в принципе.@zxqfox профит варианта с мидлварью для сборки как раз в том, что хоть воруй-убивай: пиши любые роуты и дергай любое апи
@KulakovSerg подумал предложить совсем альтернативный вариант. если отдельных бандлов на проекте не много (в идеале — один общий бандл), то вместо использования сервера, можно просто дергать bem make с помощью любого вотчера за изменениями исходников на файловой системе.
@tadatuta так мой вариант это и предлагает, но роуты до бекенда все равно руками... В общем, как-то так:
Вся вот эта логика, которую ты описал, и рулится внутри этих модулей.
@tadatuta
простите за ложную тревогу, это мой первый скрипт nodejs - не учел что он на каждый файл содержимого уже загруженной страницы страницы полез все мейкать, оттого и висло.
Опечатку поправил, с target разобрался, спасибо большое! Видимо, ваш первый вариант был с Express, попробую свое тоже переписать под него.
@zxqfox, подскажите пожалуйста,express-bem принимает targets?
Без него, наверное, как-то так:
@tadatuta, подскажите пожалуйста, как отследить ошибки в BEM.api.make?
Например, у меня сейчас при опечатке в шаблонизаторе просто повисает http://localhost:8080
Что странно, сам make тоже ничего в консоль не пишет об ошибках.
make()
возвращает q-промис. Отлавливать ошибки можно так:@tadatuta, благодарю. А есть какой-то флаг к make(), чтобы он принудительно очищал имеющиеся файлы? У меня через раз их перезапись происходить стала
да. все те же флаги (в данном случае
force
), которые есть у консольной командыbem make
, можно использовать и через JS API, т.к. ядром является COA@tadatuta, спасибо большое. Полезная библиотека, раньше не вникал в её работу.
Как Вы думаете, понадобится ли этот скрипт кому-нибудь еще? Стоит ли тратить время, чтобы допилить его до ума (в том числе реализацию вашей идеи с листнерами файловой системы) и выкладывать на гитхаб? Очень уж как-то узкоспецефично под конкретный проект все это на выходе выглядит
@tadatuta, кажется, по предыдущему вопросу я недопроверил, не работает так:
В make.js он объявлен как .flag(), но на значения true и 1 при вызове из api не откликается... Подскажите пожалуйста, в чем может быть трабл?
@KulakovSerg
Действительно, решение получится либо совсем примитивное (как текущий
project-stub
, который почти ничего не умеет, зато подходит всем), либо слишком специфичное. Поэтому ответ такой: если удастся найти разумный баланс, когда и полезное что-то и при этом по-прежнему универсальное, то да :)В
targets
должны быть пути до запрашиваемых файлов (я как раз в https://github.com/bem/bem-forum-content-ru/issues/117#issuecomment-63812214 приводил пример, как это может выглядеть дляexpress
).@tadatuta, спасибо за развернутый ответ, ваш пример мне очень помог. Простите что неверно выразился - на гитхабе не работали комменты почему-то и это сообщение пришлось 3 раза отправлять, недовоспроизвел текст...
Но не работает force: true, так же как и force: 1 - видимо потому, что у force в COA-декларации стоит .flag(). Какое должно быть значение в api-вызовах у параметров с таким типом?
@KulakovSerg а, его нужно писать в первом параметре:
@tadatuta, а если написать мидлварь, методы которой будут содержать код из .get() которые я написал выше и принимать параметрами локации?
В случае если никто ничего не кастомизировал, то внешне будет еще один бэм-сервер