Vue CLI: меняем индекс-файл при сборке
Те, кто уже работал с Vue.js при помощи Vue CLI, знают, что эта надстройка над вебпаком берёт очень многие вещи на себя, упрощая процесс сборки проекта и развития его экосистемы.
Можно, к примеру, добавить плагин для PWA и без лишних телодвижений превратить своё приложение в PWA. Также Vue CLI контролирует сборку приложения, создавая файловую структуру и заполняя файл index.html
Поворотный момент
Буквально неделю назад передо мной встала задача в результате сборки проекта при помощи Vue CLI получать не html-файл, а php, в котором реализуется некая серверная логика.
Поверхностное гугление показало, что можно использовать webpack-php-loader для сборки проекта. Однако это не решало мою проблему: насколько я понял, этот лоадер запускает php на машине, на которой происходит сборка, рендерит его и на выходе всё равно выдаёт html. Мне это не подходило, так как в php я работал с юзерагентом, передаваемым конкретным пользователем.
Решение - vue.config.js
В итоге мне удалось найти инструкцию, как указать файл, который при сборке будет считаться за “шаблон”, а также как переименовать выходной файл после сборки проекта. Делается это в файле vue.config.js.
Давайте определим себе задачу: закрыть доступ пользователям Internet Explorer 9.
Вкратце, этот файл позволяет (очень сложным путём, по-моему мнению) переопределить некоторые настройки вебпака для сборки проекта. Именно здесь мы и будем работать.
Если у вас ещё нет этого файла, создайте его в корне вашего проекта (на одном уровне с package.json) и поместите туда экспортный объект в синтаксисе Node.js:
// ./vue.config.js module.exports = { }
Далее, в папке src вашего проекта, создайте файл-шаблон, который будет использоваться при сборке. ВАЖНО: не удаляйте оригинальный файл index.html из папки public! Он нужен нам, чтобы работать в development-режиме и сохранить всякие прелести вроде хот-релоад.
Допустим, он называется index_template.php Скопируйте в него содержимое файла ./public/index.html, добавив где нужно логику на php.
// ./src/index_template.php <?php $isIE9 = strpos($_SERVER['HTTP_USER_AGENT'], 'MSIE 9.') !== false; if ($isIE9) { die('Браузер не поддердживается!'); } ?> <!DOCTYPE html> <html lang="ru"> <head> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta charset="utf-8"> <meta name="viewport" content="width=device-width,initial-scale=1.0"> <link rel="icon" href="<%= BASE_URL %>favicon.png"> <title>Site title</title> </head> <body> <noscript> <strong>We're sorry but website doesn't work properly without JavaScript enabled. Please enable it to continue.</strong> </noscript> <div id="app"></div> <!-- built files will be auto injected --> </body> </html>
Здесь мы просто для примера определяем, точно ли IE9 перед нами, и если да, прекращаем выполнение скрипта.
Осталось прописать настройки в vue.config.js
Первым делом сообщим, что после наполнения файла содержимым сохранять его нужно не как index.html, а как index.php:
// ./vue.config.js module.exports = { indexPath: 'index.php' }
Эта настройка создаст в папке dist файл с нужным расширением.
Далее напишем настройку для изменения файла-шаблона. Делается это, на первый вгляд, весьма нетривиально, но сейчас я не хотел бы углубляться в устройство конфиг-файла Vue. Так что рассмотрим лишь те моменты, которые важны для темы публикации.
// ./vue.config.js module.exports ={ indexPath: 'index.php', // Добавляем это: chainWebpack: config => { if (process.env.NODE_ENV === 'production') { config .plugin('html') .tap(args => { args[0].template = './src/index_template.php' args[0].minify.removeAttributeQuotes = false return args }) } } }
Здесь мы обращаемся к html-загрузчику вебпака, и сообщаем, что при сборке в production шаблон теперь находится по адресу ./src/index_template.php. Также мы говорим, что при минификации кода не нужно удалять кавычки атрибутов, так как иногда это может нарушить работу php-скрипта.
На этом всё! Попробуйте запустить npm run build
и вы увидите в папке dist файл index.php, полностью готовый к работе на продакшн-сервере!
Таким образом вы можете перенаправить вывод сборки в любой другой файл: TWIG, EJS и так далее.
Если у вас есть другое решение этого вопроса - я буду только рад с ним ознакомиться.