Как вы управляете репозиториями для производства / развертывания приложения Node-React? - PullRequest
2 голосов
/ 02 марта 2020

Недолго go, у нас были серверные страницы рендеринга, а затем появился React для рендеринга на стороне клиента и одностраничного приложения. Он представил виртуальные DOM и изменил способ написания нашего кода.

Нам нужны все эти реагирующие библиотеки и устанавливаем их как зависимости перед написанием наших кодов. Теперь мы можем разбить на множество компонентов, иметь много файлов css и s css, включая изображения. Но в конце мы соберем файлы, сделаем компактный пакет и подадим из папки сборки.

Express get route

app.get('*', (req,res) =>{
    res.sendFile(path.join(__dirname+'/client/build/index.html'));
});

Вот что я понял:

Папка сборки - это место, где веб-пакет объединяет все файлы и создает минимизированный пакет, готовый к развертыванию. Этот файл в основном представляет собой простые HTML и JS файлы, которые может понять каждый браузер. Поскольку все браузеры не понимают ES6 и многое другое, мы должны преобразовать все эти файлы в простой язык, понятный каждому браузеру.

Кроме того, сервер webpack-dev предназначен только для целей разработки, и мы выиграли ' не запускать его в производство.

  1. Является ли виртуальный DOM / Real DOM только для целей разработки? или эти библиотеки реагируют также при сборке минимизированных файлов? Если позже это так, то реакция запускается в фоновом режиме в браузере клиента? Я хочу знать, как реагирует на сборку на стороне клиента после сборки приложения.
  2. Как вы управляете репозиториями github для приложения Node-React? У вас есть два разных хранилища: одно для внешнего интерфейса, другое для внутреннего? Какой отраслевой стандарт?
  3. Если у вас есть два репозитория, как вы развертываете интерфейсный код? Так как вы не можете запустить webpack-dev-server в производство. Также вы не можете указать publi c stati c (папка сборки) на своем внутреннем сервере (express сервер), так как они разделены в двух репозиториях. Как происходит интеграция этих двух репозиториев (скажем, у нас есть два экземпляра AWS EC2, по одному для каждого), или фронт-энд обслуживается из репозитория переднего плана ??). Можете ли вы на самом деле использовать что-то вроде npm serve в производстве ??

что я пытаюсь сделать?

Я хочу развернуть свое приложение, реагирующее на узлы на AWS. У меня есть только один репозиторий на GitHub. У меня есть одна папка «клиент» внутри моего репо, где весь код реагирования находится вместе с пакетом. json файл. Все остальные файлы для сервера находятся в папке root (на сервере нет собственной папки, а файлы разбросаны внутри папки root). Итак, есть два пакета. json файлов, один внутри root папки для сервера и один внутри клиентской папки. Я планирую запустить приложение my-node в docker контейнере.

Пожалуйста, помогите мне понимать основные концепции и стандартные методы размещения и развертывания кода, поддерживая крупномасштабное корпоративное приложение в картине.

Ответы [ 5 ]

1 голос
/ 11 марта 2020

Я полагаю, что другие проделали довольно хорошую работу, объясняя React Virtual DOM. Простым и практичным способом я попытаюсь объяснить, как я (буду) управлять развертыванием динамического c веб-сайта (включая корпоративные системы среднего размера) с использованием NodeJS и React. Я также постараюсь не утомлять вас.

Представьте на этот раз, что React никогда не существовало и что вы создавали традиционное приложение для рендеринга на стороне сервера. Каждый раз, когда пользователь выбирает маршрут, контроллер работает с моделью для выполнения бизнес-логики c и возвращает представление. В NodeJS это представление обычно компилируется с использованием механизма шаблонов, такого как рули. Если вы задумаетесь на секунду, станет очевидно, что представлением может быть любой html контент, который затем отправляется обратно в браузер в качестве ответа.

Это типичный ответ, который можно отправить обратно:

<html>

<head>
    <title>Our Website</title>
    <style></style>
    <script src="/link/to/any/JS/script"></script>
</head>

<body>
    <h1>Hello World </h1>
</body>

</html>

Если этот ответ попадает в браузер, очевидно, «Hello World» отображается на экране. Теперь, с помощью этого простого подхода, мы можем делать мощные вещи!

ВАРИАНТ 1: Мы можем назначить один контроллер для обработки всех входящих маршрутов app.get("*", controllerFunc) и отобразить одно представление для всего нашего сервера.

ВАРИАНТ 2: Мы могли бы попросить несколько контроллеров обрабатывать различные маршруты и отображать специфичные для маршрута c представления с нашего сервера.

ВАРИАНТ 3: Мы могли бы попросить несколько контроллеров обрабатывать различные маршруты и генерировать страницы на лету (т.е. динамически) с нашего сервера.

Если бы мы строили традиционное веб-приложение, вариант 3 будет единственным разумным стандартом. Здесь страницы генерируются динамически для разных маршрутов. Однако с помощью опции 1 мы можем создать качественное одностраничное приложение, в котором ответ, отправляемый на сервер, представляет собой пустую страницу html, но со встроенным сценарием JS, который имеет возможность манипулировать DOM - Да, Реагировать ! Вот как может выглядеть такой ответ:

<html>

<head>
    <title>Our Website</title>
    <style></style>
    <script src="/link/to/any/JS/script"></script>
</head>

<body>
    <h1>Hello World </h1>
    <div id="root"> </div>
    <script async type=”text/javascript” src="/link/to/our/transpiled/ReactSPA.js"></script>
    <!--async attribute is important to ensure that the script has access to the DOM whenever it loads. This also makes the script non-blocking -->
</body>

</html>

Очевидно, что мы возлагаем всю ответственность на сгенерированный SPA, и все журналы маршрутизации c обрабатываются на стороне клиента (см. * 1028). * реагируют-маршрутизатор-дом ). На стороне сервера мы можем представить концепцию в варианте 2 и настроить обработчики маршрутов NodeJS, чтобы прослушивать другой конкретный маршрут c для любого взаимодействия REST API. Если вы знакомы с NodeJS, порядок регистрации маршрутов по app.get() или app.post() имеет значение.

Однако, используя опцию 1, мы можем быстро ограничиться и можем обслуживать только одно одностраничное приложение с этого сервера. Почему? Потому что мы попросили один контроллер обработать все входящие маршруты, не относящиеся к API, и отобразить одно представление. Мы также рискуем обслуживать ненужный раздутый файл JS. Пользователям предоставляется полный веб-сайт, когда все, что им, вероятно, нужно, - это только целевая страница.

Если мы обратимся к варианту 2, то мы можем гораздо больше настраивать и обслуживать несколько одностраничных приложений для разных маршрутов, все с нашего сервера. Такой подход помогает уменьшить размеры сборки JS, отправляемой в браузер. Типичным примером может служить веб-сайт, на котором есть страница приветствия (или каталог введения), страница входа в систему и панель мониторинга.

Назначая контроллеры для разных маршрутов, мы можем создавать SPA специально для этих маршрутов. SPA для начальной страницы, другой для страницы входа в систему, а затем другой для панели инструментов. Да, браузер должен был бы загружаться при переходе между тремя, но, по крайней мере, мы сильно увеличиваем начальное время рендеринга для нашего сайта. Мы также можем использовать более безопасную опцию cook ie для авторизации, а не менее безопасную опцию хранения токенов сессий на localStorage.

В более продвинутых настройках у нас могут быть динамические c веб-сайты с различными компонентами React, отображаемыми как виджеты на динамически генерируемой странице. На самом деле, это то, что делает Facebook.

Способ создания таких SPA или компонентов довольно прост. Запустите реактивный проект и настройте веб-пакет для рендеринга готового к производству файла JS в предпочитаемый каталог publi c stati c в репозитории на стороне сервера. <script>, указанный в представлении, может затем легко загрузить эти встроенные реагирующие компоненты, поскольку они существуют в области действия каталога publi c на стороне сервера.

По сути, это означает один репозиторий с несколькими клиентскими каталогами и один каталог сервера, в котором место назначения файлов рабочей сборки, которые будут сгенерированы веб-пакетом для каждого клиентского проекта, установлено в общедоступный каталог сервера c stati c сервера. Итак, каждый каталог на стороне клиента - это проект (либо полный SPA, либо простой React Component в качестве виджета) со своим собственным файлом webpack.config и package. json. Фактически у вас может быть два отдельных конфигурационных файла - производство и разработка. Затем для сборки вы используете npm ~relevant command~ либо для производственной, либо для разрабатываемой сборки.

Затем вы можете go опередить хост, как и любое приложение NodeJS. Потому что основным приложением является NodeJS - вот где находится сервер. Замените NodeJS на PHP и Apache / NGINX, концепция остается прежней.

1 голос
/ 11 марта 2020

Я бы не стал go объяснять все пункты вашего вопроса здесь, потому что @Arnav Yagnik и @PrivateOmega оба отлично справились с объяснением большинства из них. Я определенно рекомендую вам внимательно прочитать их ответы и прочитать ссылки, предоставленные для получения дополнительной информации , прежде чем читать этот ответ .

Я хотел бы ответить на ваш вопрос о развертывании приложения Node-React. В производстве, как правило, у нас есть разные развертывания (или «репозитории», как вы упомянули в своем вопросе) для внешнего интерфейса (React) и внутреннего (Node). Это позволяет вашему бэкэнду сидеть в экземпляре EC2, например, с автоматическим масштабированием, чтобы убедиться, что он может справиться со всеми поступающими запросами.

Как упоминалось в предыдущих ответах, и в Ваш вопрос также, Webpack компилирует и преобразует файлы React в простые HTML и JS файлы, которые могут запускаться большинством браузеров (я не собираюсь объяснять VirtualDOM здесь, потому что это уже было прекрасно объяснено в других ответах). Затем вы бы взяли эти минимизированные файлы и подали их, например, из корзины S3, потому что опять-таки это одностраничное приложение (также обсуждаемое в других ответах), а бизнес-логика c уже находится в минимизированных JS файлах. и это просто отправка всех запросов на ваш внутренний сервер.

Теперь для внешнего интерфейса вы можете использовать TravisCI, например, для развертывания папки build ( тот, о котором вы говорите в своем вопросе) к экземпляру EC2 и обслуживайте свои файлы, используя NGINX или, если вы можете правильно настроить развертывание CDN, вы можете подавать файлы из корзины S3 для наиболее оптимальной производительности.

Вы можете думать о , обслуживающем приложение React, как об отправке криптоблокового c блока кода в браузер вашего пользователя. Теперь вы можете развернуть этот блок кода crypti c в общедоступном сегменте S3 и обслуживать его оттуда. Опять же, из-за webpack и минификации / uglification, никто не сможет понять, каким был ваш исходный код, помните, что вы все равно можете получить доступ ко всему коду, например, на вкладках Sources Chrome.

1 голос
/ 10 марта 2020

Я хотел бы начать с прояснения терминологии настолько, насколько смогу.

Как вы сказали серверные страницы был более выдающимся стандартом в прошлом, но он не С появлением React ничего не изменилось, потому что даже React поддерживает Рендеринг сервера или SSR , что означает, что HTML страницы генерируются на стороне сервера и затем передаются клиентам с помощью браузера.

И рендеринг на стороне клиента означает, что в браузер загружается страница HTML, а затем код javascript отображает объекты поверх этих HTML страниц и делает их интерактивными.

И одностраничное приложение концепция заключается в том, что у нас есть только один HTML файл или базовая HTML страница, поверх которой, основываясь на взаимодействиях пользователей и данных с сервера, она непрерывно переписывается.

Virtual Dom - это удивительная концепция, представленная React. Код библиотеки React воссоздает структуру всех элементов (называемых элементами DOM) страницы HTML в памяти в виде дерева. Это позволяет алгоритму React, называемому Fiber , согласовать соответствующие изменения в соответствии с обновлением маршрута или любыми другими изменениями сначала в этой древовидной структуре, прежде чем преобразовывать их в реальные элементы на странице HTML.

Babel - это транспортер для передачи новейших функций, которые движки браузеров еще не начали поддерживать, в код, который они могут понять, обычно код ES6 + в pre-ES6, потому что все браузеры поддерживают это. В приложении React, если вы написали приложение с использованием синтаксиса JSX, babel также поддерживает преобразование JSX в обычный javascript.

Да, разбиение страниц на множество компонентов возможно из-за композиционного характера компонентов в React, который означает, что мы можем создавать сложные вещи, комбинируя маленькие и более сфокусированные вещи.

В конце, перед тем как обслуживать его конечным пользователям, у нас не может быть задержки в веб-приложении из-за огромного размера кода, поэтому во время сборки В процессе выполняются такие вещи, как минимизация (удаление пробелов и т. д. c) и другая оптимизация, например объединение нескольких файлов javascript в один и т. д. c, а затем компактный пакет подается из папки сборки, как вы сказали. * Да, папка сборки - это то, где webpack выполняет мини-фукцию и комбинацию, чтобы создать как можно меньший пакет. Это базовые файлы c HTML и JS, которые понятны каждому браузеру, и если код содержит что-то, что не поддерживается конкретным браузером, в него также входит соответствующий код поддержки или что-то, называемое polyfill. Технически нельзя сказать, что браузеры понимают только код до ES6, потому что многие движки браузеров уже реализовали множество функций ES6.

Сервер разработки Webpack просто используется для обслуживания приложения веб-пакета через порт, такой как node.js и предоставляет нам такие функции, как оперативная перезагрузка, которые необходимы, когда вы постоянно вносите изменения в базу кода своего приложения, и не нужны на производстве, потому что, как мы уже говорили ранее, на этапе производства это всего лишь HTML и JS и никто никогда не вносит никаких изменений в эти файлы.

  1. Виртуальный DOM представляет собой представление памяти или концепцию, используемую React Code, точно так же, как у нас есть стеки и очереди, а не только используемые во время разработки. Да и нет. Потому что я думаю, что соответствующие части исходного кода реагирования, которые требуются для запуска приложения, также будут объединены перед созданием производственного комплекта.

  2. Я бы сказал, что нет заранее заданный способ, потому что это полностью зависит от разработчика и команды, потому что я видел людей, использующих 2 отдельных репо, потому что внешние люди работают над внешними, тогда как внутренние работают над внутренними. Но есть также случай, когда каждый является разработчиком полного стека, и технически вы можете иметь его в одном репо с одним пакетом. json и использовать бэкэнд для обслуживания файлов внешнего интерфейса, и вам придется вручную устанавливать каждую зависимость реакции и не может напрямую использовать CRA или создать-реагировать-приложение, как генератор.

  3. Какое отношение имеют 2 репозитория к развертыванию внешнего интерфейса в рабочей среде? Вам не нужно запускать webpack-dev-server для файлов сервера в производстве. Вы можете создать производственный пакет, а затем настроить любой http-сервер для обслуживания созданного пакета.

Что касается вашего текущего сценария, я бы сказал, что вместо 2 пакетов. json, вы можете go с одним пакетом. json и установите все зависимости вместе или go с использованием подхода monorepo, используя что-то вроде lerna или рабочих областей пряжи .

Но для начинающих я бы предложил 2 отдельных репозитория, чтобы столкнуться с меньшими проблемами.

И бонусный балл, если вы не в курсе, вы можете написать React в коде до ES6, а также без JSX.

1 голос
/ 11 марта 2020

1) виртуальный DOM в основном означает, что вы вызываете функцию реагирования, а не фактическую функцию, которая выполняет манипуляции с реальным DOM

, как этот

document.getElementById("demo").innerHTML ="Helloworld"

изменяет фактическую dom

, но

ReactDOM.render(
  <HelloMessage name="Taylor" />,
  document.getElementById('demo')
);

, если вы видите это правильно, вы ничего не делаете напрямую с dom, который вы просто предоставляете для управления функцией реакции. вещи, внутренне реагирующие, заботятся о модификации демо-элемента that dom всякий раз, когда реактив хочет перерисовать его, основываясь на своей собственной логике c, которая, как они утверждают, оптимизирована, и именно поэтому люди используют ее в первую очередь. Да, когда вы создаете свой код с помощью веб-пакета, он включает в себя реагирование, являющееся частью этого уменьшенного кода, поэтому, если вы видите какую-либо из трассировок стека ошибок в разработке, вы видите, что реакция является отправной точкой для этого

2 ) Я думаю, что выбор будет сделан, так как на этом

3 нет ограничений. 3) Переход к развертыванию. В общем, если вы хотите использовать nodejs, вы можете выбрать expressjs тип сервера: развертывание, но, как правило, лучше использовать высокопроизводительный сервер, такой как Nginx или Apache, либо, если вы просто не хотите разбираться во всей этой драме вещей, обычно люди используют развертывание на основе heroku или люди используют специальные платформы как netlify, скачок. sh в наши дни (его очень легко развернуть на этих платформах).

1 голос
/ 06 марта 2020

Я хотел бы обратиться к этому с другим подходом.

Страницы, отображаемые сервером: концепция не изменилась, сервер, когда сталкивается с запросом DO C, должен ответить html. Теперь HTML может содержать или не содержать скрипты (может быть как встроенным, так и адресом внешнего сервера). В случае контекста вопроса вы все равно можете отправить HTML, где он будет загружать написанные вами сценарии (может включать реакцию или нет). в большинстве случаев вы можете отправлять пустые html с тегами сценариев, которые будут загружать сценарии по сети и выполнять их, которые будут содержать все логи рендеринга c.

Чтобы ответить на ваши вопросы: 1-й: нет фоновый режим в однопоточном режиме JS (если мы не хотим говорить о рабочих, но мы можем оставить их для этого обсуждения). При написании кода вы не взаимодействуете ни с каким DOM. Вы инструктируете свои компоненты (расширенные React), когда менять их состояние и когда выполнять повторную визуализацию (setState). React внутренне вычисляет виртуальный DOM и сравнивает его с Real DOM, чтобы вычислить фактические изменения, которые должны быть внесены в Real DOM (это очень абстрактный ответ, для более глубокого понимания, пожалуйста, прочитайте реагирующую документацию. Базовая линия здесь: вы не взаимодействуете ни с каким DOM, просто указание библиотеке React core когда обновляться и какое состояние обновлено)

2-й: Если вы хотите поддерживать SSR (страницы, отображаемые сервером). Я бы предложил сделать 2 папки: client (это будет включать в себя все клиентские компоненты и логи c) и server (будет включать все серверные логи c) с разными пакет. json, поскольку пакеты отличаются для обоих приложений. Здесь нет такого отраслевого стандарта, что должно работать на вашей лодке, но обычно создание каталогов на основе логических объектов должно удовлетворять разделению и удобству обслуживания, если в будущем вы думаете Если вы хотите разделить сервер и клиента на отдельные репозитории, это определенно облегчит процесс.

3-й: Вы избегаете запуска webpack-dev-server в производстве. Файлы, как правило, не запутываются, поэтому полезная нагрузка велика (не забывайте, что ваш написанный код там). Даже если вы хотите создавать разные репозитории, сервер может выплевывать html и html запрашивать сценарии на вашем клиентском сервере.

Как развернуть: разверните код и запустите:

узел сервер / приложение. js

и в приложении. js вы можете написать блок местоположения, что вы упомянули.

PS: Если вам просто нужен сервер с этим блоком местоположения. вам действительно нужен сервер express? Вы можете загрузить клиентскую сборку в CDN и направить свой домен для обслуживания индекса. html из CDN (здесь также можно использовать корзину s3)

...