Речь об удобной организации работы с Javascript иCSS.
Я хочу иметь возможность для разработки разносить логические модули по отдельным файлам, использовать возможности ES6 и LESS, но при этом, чтобы на продакшен подключать только один суммарный файл (js, css), его имя менялось при внесении изменений (чтобы обновлять кеш), при этом, чтобы мне не приходилось вручную менять название файла в шаблоне. Для полноты ощущений еще добавим Autiprefixer.
К сожалению, очень много сайтов все еще живет на виртуальном хостинге, поэтому будем пытаться все это сделать в его условиях. Обязательный минимум - это доступ по SSH.
1 Установка node
Для решения поставленной задачи сперва потребуется локально установить NodeJS.
Заходим на официальный сайт https://nodejs.org/dist/latest/ и ищем там похожий файл, подходящий к нашей версии операционной системы.
Узнать версию можно выполнив команду:
cat /etc/*-release
//ответ
CentOS release 6.9 (Final)
Узнать разрядность:
uname -m
//ответ
x86_64
Видно, что подходит файл node-v10.4.1-linux-x64.tar.gz. Загружаем его в корень домашней директории:
wget https://nodejs.org/dist/latest/node-v10.4.1-linux-x64.tar.gz
Распаковываем:
tar -xvzf node-v10.4.1-linux-x64.tar.gz
Архив больше не понадобится, его можно удалить.
Добавляем путь к бинарникам NodeJS в переменную $PATH. Для этого создаем файл .bashrc:
nano .bashrc
и пишем в него:
export PATH=~/node-v10.4.1-linux-x64/bin:$PATH
Теперь нужно, чтобы этот файл читался при логине в системе. Для этого создаем файл
nano .bash_profile
и пишем в него
if [ -f ~/.bashrc ]; then
. ~/.bashrc
fi
ОК. Теперь нужно закрыть сессию и снова войти. Проверяем, что NodeJS виден:
node -v
npm -v
Если в ответ выводятся версии программ, то все установилось.
2 Создание проекта
Теперь нужно инициализироваь проект с NodeJS (здесь -y нужно, чтобы не отвечать на излишние вопросы):
npm init -y
После этого в корневой директории появится файл package.json
3 Устанока модулей
Далее ставим нужные модули:
npm install @babel/cli @babel/core @babel/plugin-transform-classes @babel/polyfill @babel/preset-env autoprefixer babel-loader babel-plugin-transform-builtin-classes core-js css-loader html-webpack-plugin less less-loader mini-css-extract-plugin node-less postcss-loader script-ext-html-webpack-plugin style-loader webpack webpack-cli --save-dev
4 Режимы работы webpack
В package.json добавить в секцию scripts два режима работы webpack: dev - для разработки и build для продакшен
"dev": "webpack --mode development",
"build": "webpack --mode production"
5 Конфигурирование babel
Создаем файл .babelrc и пишем в него строку:
"plugins": [ "@babel/plugin-transform-classes" ]
Файл в формате json.
6 Список поддерживаемых браузеров
Также модуль Autoprefixer перешел на использование файла .browserslistrc. Теперь указывать перечень совместимых браузеров там. Формат - простой текст, например:
# Browsers that we support
ie >= 10
last 2 version
7 Конфигурирование webpack
Для простоты всю конфигурацию мы будем делать в файле webpack.config.js
Я возьму некий сферический сайт в вакууме и предположу, что исходники у нас лежат в директории src в корне домашней папки, домашняя папка - директория www, а результат сборки - в папке шабонов с именем sk-temp. Пути к шаблонам типичные для ЮМИ.
const path = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const autoprefixer = require('autoprefixer');
module.exports = {
entry: ["./src/js/main.js", "./src/styles/main.less"],
output: {
publicPath: '/',
path: path.join(__dirname, "/www"),
filename: "templates/sk-temp/assets/js/[name].[chunkhash].js"
},
devtool: "source-map",
//watch: true,
module: {
rules: [
{
test: /\.js$/,
use: {
loader: 'babel-loader',
options: {
presets: ["@babel/preset-env"]
}
}
},
{
test: /\.less$/,
use: [
'style-loader',
MiniCssExtractPlugin.loader,
'css-loader',
{
loader: 'postcss-loader',
options: {
plugins: [
autoprefixer({
grid: true//,
//browsers:['ie >= 10', 'last 2 version']
})
],
sourceMap: true
}
},
'less-loader'
]
}
]
},
plugins: [
new HtmlWebpackPlugin({
inject: false,
hash: true,
template: './src/webpack-gen.xml',
filename: 'templates/sk-temp/xslt/layouts/webpack-gen.xml'
}),
new MiniCssExtractPlugin({
filename: "templates/sk-temp/assets/css/[name].[chunkhash].css",
chunkFilename: "[name].css"
})
]
};
Здесь закомментирована инструкция watch, потому что на REG.RU, где я проверял конфигурацию, при включенном мониторинге перестает отвечать web-сервер. Почему - не разбирался, думаю, на более вменяемом хостинге такой проблемы не будет. Напомню, что по моему опыту наилучшим выбором в России являются два хостера: Timeweb - хорошее качество услуг, доступ по SSH всегда (а не по требованию, как на Spaceweb), вход в phpmyadmin без необходимости вводить пароль на каждый чих, плюс низкие цены на VDS (по российским меркам низкие, конечно); второй хостер - beget, он дает NodeJS из коробки.
8 Шаблон для вывода сгенерированных бандлов и подключение его к ЮМИ
В шаблоне src/webpack-gen.xml подключаем файлы скриптов и стилей, так, как они будут видны в ЮМИ:
<?xml version="1.0" encoding="utf-8"?>
<assets>
<link rel="stylesheet" href="<%=htmlWebpackPlugin.files.chunks.main.css %>" />
<script src="<%= htmlWebpackPlugin.files.chunks.main.entry %>"></script>
</assets>
Обработанный файл будет помещен в templates/sk-temp/xslt/layouts/webpack-gen.xml. При каждом изменении исходников ссылка на скрипты будет меняться, примрно так:
<link rel="stylesheet" href="/templates/sk-temp/assets/css/main.bfd478388b2c73ebee96.css?99d07b1b2c5853a3c8cc">
<script src="/templates/sk-temp/assets/js/main.bfd478388b2c73ebee96.js?99d07b1b2c5853a3c8cc"></script>
Теперь надо подключить его к шаблону ЮМИ. Поскольку мы предусмотрительно поместили webpack-gen.xml в одну папку с xslt-шаблонами, то в нужном месте вставляем команду:
<xsl:copy-of select="document('webpack-gen.xml')/assets/node()"/>
9 Использование
Теперь можно запускать сборку:
npm run dev
Здесь dev - это имя девелоперской сборки (dev и build), которые мы добавляли в package.json