Мы в Trengo решили разделить архитектуру Monolith на Backend и Frontend, и я имел честь сделать это. Конечно, это зависит от потенциала проекта, я считаю, что полезно знать, как мы обнаружили кроличьи норы и как вы можете их решить.
Меня зовут Нима, и добро пожаловать в мой блог.

Проблема

Вы и структура вашей команды должны работать над архитектурой Monolith, Backend Frontend или Microfrontend и т. д. Я не буду объяснять плюсы и минусы, но если вы решили разделить свой Laravel + Vuejs Monolith на backend и frontend , это была бы хорошая статья для вас.
Если у вас архитектура Monolith, возможно, у вас есть Monorepo, которое вызовет хаос в больших командах. Наличие отдельного репозитория было бы очень полезно с точки зрения CI/CD и с технической точки зрения.

Решения

Первая фраза, которую вы будете искать, будет Могу ли я полностью отделить Vue.js Front-end от Laravel Back-end? Ответ Да, но как?
Мы нашли четыре решения:
Разделение с помощью Webpack5 — Разделение с помощью Vite — Разделение с помощью Webpack4 — Разделение с самим Laravel-mix.
Есть плюсы и минусы здесь я объясню, почему мы выбираем Webpack5, но это полностью зависит от вас.

Laravel-микс

Бесполезно отделять архитектуру Monolith от Laravel-mix, когда мы не собираемся использовать в ней большую часть фич. Laravel-Mix очень мощный, только если вы собираетесь использовать приложение Monolith с Laravel. Много настроек Webpack, настройка которых занимает очень много времени, также вы не можете самостоятельно обновить версию Webpack с 4 до 5 или с 5 до 6, пока Laravel-Mix не даст обновлений, что означает, что вы не можете обновляться. с новейшими технологиями.

Веб-пакет4

Webpack — хорошее решение для замены его на Laravel-Mix, но какая версия? как сказал Webpack, всегда старайтесь использовать последнюю версию, если вы хотите иметь работающее приложение. Webpack 4 слишком сильно мешает новым технологиям, таким как федерация модулей, конфликт между [email protected] и [email protected], который вызовет this.getOptions() ошибку, которая обрабатывается в Webpack 5, и т. д. Если вы заботитесь об обновлениях приложений, я настоятельно рекомендую выбрать другие варианты.

Вите

Может быть, вы слышали о Vite,

Vite — это инструмент для сборки, цель которого — обеспечить более быструю и экономичную разработку современных веб-проектов.

У меня был хороший опыт работы с Vite, это очень помогло мне настроить приложение с меньшими усилиями. но почему мы не выбрали его для нашего проекта Vue?

Внимание: если у вас есть список маршрутов в .js, он попытается построить все маршруты в режиме разработки, в зависимости от вашего проекта это может занять много минут.

Vite еще не созрел, и вы не можете рассчитывать на него в режиме производства (2022 г.). вам не может быть отказано в производительности Vite, но и для устаревших кодов и структур вы столкнетесь с некоторыми более серьезными проблемами. Если вы хотите насладиться его мощью, было бы неплохо использовать динамический импорт, чтобы помочь в разделении кода и больше SplitChunk. Я хочу начать новый проект с нуля, обязательно буду использовать Vite.

Веб-пакет 5

Очень приятно, что есть большой выбор библиотек. Webpack 5 — лучшая библиотека, основанная на нашем проекте, большом проекте с большим количеством настроек на Laravel-Mix, который необходимо перенести на новый сборщик.
У нас не будет проблем с PostCss или сборкой router.js. , конечно, Webpack HMR (горячая перезагрузка модуля) не очень быстр, так как использует socket.js для работы в реальном времени, но я покажу вам, что он в два раза быстрее, чем Laravel-Mix 5.

Шаг за шагом

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

Я использую маршруты Laravel вместо REST

Я настоятельно рекомендую сначала перейти на REST, это самая важная часть миграции. Например. У нас есть маршрут «/authenticate/login», который обрабатывает процесс входа пользователя в систему, в этом случае лучший подход — перенести его в «/api/authenticate/login», который будет принимать параметры JSON и также будет отвечать на JSON. если все ваше приложение не в REST, то давайте создадим карточку рефакторинга в вашей системе управления задачами со значком «критическое».

У меня есть index.blade.php вместо index.html

Мы справимся с этим позже с помощью Webpack, единственное, что нужно — это скопировать/вставить весь файл в новый index.html, вот и все, пусть Webpack справится с этим.

Как обращаться с окружением?

Все переменные «env» изменятся с «import.meta.EnvName» на «process.env.EnvName», что означает, что мы должны заменить их все, а также создать файл «.env» в корне проекта с желаемым переменные.

Как насчет метода «импорт»?

Замените только «import(…).default» на «require(…).default».

Изменится ли наша кодовая база?

Конечно нет, если у вас есть стандартная кодовая база, у вас не будет проблем.

Как настроить Webpack5 на Vuejs 2?

Это довольно просто, я настоятельно рекомендую разделить конфигурации «разработка» и «производство», так вы будете лучше контролировать каждую конфигурацию среды. Очень часто возникает конфликт между этими двумя окружениями.
Давайте начнем с создания нового каталога с именем вашего приложения (например, myapp ) и создадим структуру каталогов, как показано ниже:

.
|-- README.md
|-- package.json
|-- public
|-- src
-- webpack
    |-- paths.js
    |-- webpack.common.js
    |-- webpack.config.dev.js
    `-- webpack.config.prod.js

Пришло время установить зависимости.

npm i -D @webpack-cli/serve clean-webpack-plugin compression-webpack-plugin copy-webpack-plugin css-minimizer-webpack-plugin dotenv-webpack html-webpack-plugin optimize-css-assets-webpack-plugin speed-measure-webpack-plugin terser-webpack-plugin webpack webpack-bundle-analyzer webpack-cli webpack-dev-server webpack-hot-middleware webpack-merge css-loader vue-loader esbuild-loader 

Попробовал установить все devDependencies, если какие-то из них не установились, будем делать дальше.
Теперь давайте посмотрим, как выглядит «webpack.common.js».

Это слишком долго, да, я знаю, я не буду объяснять загрузчики, так как вы можете найти их в Medium или в их репозиториях Git, по этой причине я попытался оставить комментарии, если это необходимо, но давайте сделаем быстрый обзор.

SpeedMeasurePlugin: этот плагин поможет нам измерить производительность Webpack. Так полезно узнать, у какого загрузчика нехватка производительности. мы должны обернуть его вокруг нашей конфигурации.

Запись: запись должна относиться к основному файлу javascript, в котором запущено приложение Vuejs.

Предоставить подключаемый модуль:

Автоматически загружайте модули вместо того, чтобы import или require их везде.

Если вы работаете с библиотекой подчеркивания, такой как «lodash» или «Jquery», которая имеет специальный синтаксис, необычный для Webpack и не импортируется внутри файлов, вы должны предоставить их внутри этого плагина.

CopyWebpackPlugin: этот плагин очень полезен для нас, потому что у нас есть «общедоступная» папка из «Laravel», и она понадобится нам после разделения. Как вы знаете, Laravel-mix был подключен «публично» к приложению «Vuejs». Из-за этого после миграции ни одно из изображений или каких-либо ресурсов не будет загружаться правильно, поскольку Webpack не имеет доступа к «общедоступной» папке (вне области папки), этот плагин попытается установить это соединение.

ESBuild: пришло время заменить babel-loader на ES-build, чтобы ускорить сборку Webpack. больше никаких объяснений, читаем документацию: https://github.com/privatenumber/esbuild-loader

Сейчас у нас все хорошо, давайте наращивать развитие. это так просто.

Поскольку это так просто, я просто хочу объяснить HotModuleReplacementPlugin и исходную карту.

HotModuleReplacementPlugin: или HMR — это подключаемый модуль, который будет перезагружать страницу каждый раз, когда мы сохраняем наши изменения в IDE, преимущество, связанное с другими наблюдателями, заключается в сохранении состояния, что означает, что ваши состояния будут сохраняться после каждой перезагрузки по мере перезагрузки подключаемого модуля. только конкретный и связанный DOM.

devtool: Возможно, сначала это не так ясно. Давайте посмотрим, что такое Devtool в документации Webpack.

source-map-loader извлекает существующие исходные карты из всех записей JavaScript. Сюда входят как встроенные исходные карты, так и карты, связанные через URL. Все данные исходной карты передаются в веб-пакет для обработки в соответствии с выбранным стилем исходной карты, указанным параметром devtool в webpack.config.js.

Чаще всего используется отладка кода в браузере, исходные карты еще не транспилированы, и вы можете увидеть в них свои коды Vuejs, чтобы найти, в какой части есть ошибка. поскольку это снизит производительность, лучше всего оставить его только в режиме разработки. вы можете найти список различных исходных карт здесь: https://webpack.js.org/configuration/devtool/

Я предпочитаю использовать «inline-source-map», который даст мне достаточно деталей и увеличит время сборки и перестроения в режиме разработки.

Так интересно для производства? Итак, начнем.

Сначала вы увидите, что devtool ложный, имеет смысл не предоставлять отлаживаемую версию в продакшене, так как это увеличит размер пакета, время сборки, а также клиенту это не понадобится.

splitChunks: на этапе оптимизации мы используем splitChunks, который слишком сильно увеличивает производительность за счет разделения пакета на отдельные модули, https://webpack.js.org/plugins/split-chunks- плагин/

TerserPlugin: кто-нибудь знает, что подключаемый модуль Terser влияет на производительность. Terser использует множество алгоритмов для максимально возможной минимизации кода javascript. https://webpack.js.org/plugins/terser-webpack-plugin/

Единственное, что осталось, это paths.js

const paths = require('path')

module.exports = {
// Source files
src: paths.resolve(__dirname, '../src'),

// Production build files
build: paths.resolve(__dirname, '../dist'),

// Static files that get copied to build folder
public: paths.resolve(__dirname, '../public'),
}

Это слишком просто и не требует пояснений. 😄

В основном готово, давайте изменим наш package.json

"scripts": {
  "dev": "webpack server --mode=development --config ./webpack/webpack.config.dev.js",
  "build": "webpack --mode=production --config ./webpack/webpack.config.prod.js",
  "serve:dev": "pm2 start ecosystem.config.js --env development",
  "serve:prod": "pm2 start ecosystem.config.js --env production"
},

Это и так понятно, только я хочу объяснить serve:dev и prod. В качестве менеджера процессов я предпочитаю использовать PM2, если вы с ним не знакомы, очень рекомендую ознакомиться с его документацией: https://pm2.keymetrics.io/. ecosystem.config.js — это основной файл конфигурации или PM2 для определения различных вариантов поведения при производстве или разработке, вы можете проверить построенный проект на своем локальном компьютере, запустив serve: dev, и он фактически такой же, как и производственный , очень важно попытаться сделать среду разработки и производства одинаковой, чтобы уменьшить количество ошибок.

ecosystem.config.js

module.exports = {
    script: 'serve',
env_development: {
    NODE_ENV: 'development',
    PM2_SERVE_PATH: './dist',
    PM2_SERVE_PORT: 3000,
    PM2_SERVE_SPA: 'true',
},
env_production: {
    NODE_ENV: 'production',
    PM2_SERVE_PATH: './dist',
    PM2_SERVE_PORT: 8080,
    PM2_SERVE_SPA: 'true',
},
deploy: {
        development: {
          host: ['localhost', '127.0.0.1'],
        },
        production: {
          host: ['production.domain', 'production IPAddress'],
        },
    },
};

Время разобраться с цифрами

Теперь пришло время просмотреть тест новой конфигурации Webpack с текущим проектом Laravel-mix. Конечно, это связано с вашим проектом. Эти тесты относятся к большому проекту с большим количеством файлов.

Время сборки Laravel Mix — 3,30 минуты

Время сборки Webpack5 — 1,9461 минуты

Вы можете видеть, что это почти в два раза быстрее. но это не единственный бенчмарк, у меня есть еще один интересный бенчмарк по запуску тестов

Laravel-mix — 6,44 секунды

Веб-пакет 5–3,318 секунд

Результат такой же, как указано выше. мы испытали лучшую производительность в Trengo, который изменил эти изменения.

Заключение

Выбор лучшего сборщика модулей зависит от вашего проекта, нет конкретного рецепта для повышения производительности вашего проекта, для некоторых проектов лучше всего подходит Laravel-mix или, может быть, Vite. Самое главное — знать свои проекты и кроличьи норы внутри них. Для например. в проекте Laravel Monolith, если вы используете прямые маршрутизаторы, такие как «authenticate/forget-password», вы должны изменить его на REST API и обрабатывать все с помощью JWT или другого шифрования.

Одна важная вещь — скопировать целиком master.blade.php в «public/index.html» внутри новой структуры, которая является основным HTML-шаблоном.
Больше ничего не нужно делать. упомяните, наслаждайтесь кодированием 😉