Установка Webpack, Babel, LESS на виртуальный хостинг

Речь об удобной организации работы с 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