Webpack — это не таскраннер, это упаковщик. Под «упаковщиком» мы подразумеваем специализированный инструмент, способный производить высокооптимизированный пакет. Но легко ли получить этот пакет?

No.

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

Забудьте все, что вы знали о Gulp или Grunt. Это будет бесполезно.

Здесь я попытаюсь освободить ваш разум, но я могу только показать вам дверь...

Начиная с этого места, вы хорошо знаете Node и Npm. Иначе что здесь делают?

Я предполагаю, что нам нужна очень простая установка, мы хотим использовать ES6 и SASS. И мы хотим, чтобы они были соответственно преобразованы в Javascript и CSS.

У нас есть такой проект:

.
├── package.json
├── src
│   ├── img
│   │   ├── diamond.png
│   │   └── nyan.gif
│   ├── index.ejs
│   ├── main.js
│   └── styles
└── webpack.config.js

Первое, что нужно сделать, это установить Webpack локально.

npm install webpack --save-dev

И создайте файл конфигурации веб-пакета webpack.config.js:

var path = require('path');
module.exports = {
  entry: “./src/main.js”,
  output: {
    path: path.resolve(__dirname, 'build'),
    filename: “bundle.js”
  }
};

main.js — это точка входа. bundle.js — это выходной файл. Это самый простой файл конфигурации Webpack.

Давайте добавим его как скрипт NPM. Обновите файл package.json:

“scripts”: {
  “build”: “rm -rf build && webpack”
},

И запустите:

$ npm run build

Результат находится в папке build.

Хорошо, а ES6?

На стороне клиента последние браузеры спокойно совместимы с ES6 (95%+). Это относится к Chrome 52+ и Edge 14+. Однако старые браузеры совершенно не смогут выполнять чистый ES6.
Со стороны сервера Node 6 на данный момент совместим на 92%.
Итак, нам нужно транспилировать ES6 в Javascript, и мы выбираем Babel. сделать это… потому что он кажется более совместимым с ES6, чем другие. Но с Babel у нас будет соответствие только 71%. Наконец, даже если у вас новейший браузер, сегодня невозможно использовать самые продвинутые функции ES6.
Вы можете увидеть все это дерьмо на этом листе: https://kangax.github.io/compat -таблица/es6/

Поехали.
Нам нужно установить (локально) загрузчик для webpack для транспиляции ES6:

$ npm i --save-dev babel-loader babel-core

Я доверяю вам делать это в одиночку с этого момента ;)

Это минимум для использования Babel с Webpack.
Теперь нам нужно выбрать «пресет». Выбираем пресет ES6 (ранее ES2015). Но мы могли бы выбрать ES2016 или ES2017… Поэтому вам нужно установить babel-preset-es2015.

Ок, устанавливай :D

Теперь мы должны указать Webpack для использования Babel:

var path = require(‘path’);
module.exports = {
  entry: “./src/main.js”,
  output: {
    path: path.resolve(__dirname, ‘build’),
    filename: “bundle.js”
  },
  module: {
    loaders: [
      { 
        test: /\.js$/,
        exclude: /node_modules/,
        loader: “babel”
      }
    ]
  }
 
};

Теперь мы можем написать код ES6 и транспилировать его в ES5.

Это круто, но я хочу веб-приложение!

Правильно. Возможно, вам нужен сервер. Сервер для развития! webpack-dev-server предоставьте это… Установите его!

И обновите файл package.json:

“scripts”: {
  “dev”: “webpack-dev-server --hot --inline --content-base build”
},

--hot --inline включить автоперезагрузку. Не волнуйтесь, прохладно (или жарко?). Возможно, мы рассмотрим это в следующем посте.

Бегать:

$ npm run dev

И просмотрите http://localhost:8080/.

Ага. Файл index.html… где-то?

Webpack изначально не дает возможности генерировать index.html… На самом деле, Webpack бесполезен без своих плагинов! Как Gulp, вы знаете…

Установите плагин html-webpack.

И настройте подключаемый модуль в файле webpack.config.js:

var HtmlWebpackPlugin = require(‘html-webpack-plugin’);
var path = require(‘path’);
module.exports = {
  entry: ‘./src/main.js’,
  output: {
    path: path.resolve(__dirname, ‘build’),
    filename: ‘bundle.js’
  },
  module: {
    loaders: [
      { 
        test: /\.js$/,
        exclude: /node_modules/,
        loader: ‘babel’
      }
    ]
  },
  plugins: [new HtmlWebpackPlugin()]
 
};

Теперь откройте браузер и перейдите по адресу http://localhost:8080. Tada.
Обратите внимание, что он больше не создает папку build, а обслуживает bundle.js напрямую через память.

Хороший! Мне нужен пользовательский индексный файл сейчас.

Легкомысленный человек. Может шаблонить?

plugins: [
  new HtmlWebpackPlugin({
    title: ‘ES6 Web Page’,
    template: ‘src/index.ejs’,
    filename: ‘index.html’
  })
]

Бим.

Вполне нормально. Но как скомпилировать SCSS?

Хорошо. Вся эта часть более сложная.

Во-первых, давайте попробуем интегрировать простые таблицы стилей CSS. Нам нужно установить style-loader и css-loader.

{
  test: /\.css$/,
  loader: ‘style!css’
}

В Webpack есть загрузчики для многих типов контента. Здесь мы загружаем все файлы CSS в загрузчик CSS, а затем в загрузчик style.

А теперь просто добавьте новую запись:

entry: [
  ‘./src/main.js’,
  ‘./src/style.css’
],

Если вы запустите npm run dev и измените CSS, он динамически изменит стиль в браузере.

Попробуйте запустить просто webpack, чтобы скомпилировать его в папке браузера и заглянуть внутрь. Нет файла style.css.

Верните мне мой файл style.css, пожалуйста.

Верно. Обычно здесь мы предпочитаем иметь отдельный файл для CSS. Для этого нам нужно использовать другой плагин. Установите extract-text-webpack-plugin.

Добавьте плагин в раздел plugin с небольшой настройкой:

plugins: [
  new HtmlWebpackPlugin({
    title: ‘ES6 Web Page’,
    template: ‘src/index.ejs’
  }),
  new ExtractTextPlugin(‘style.css’)
]

И обновите конфигурацию загрузчика, чтобы указать плагину, что делать:

var ExtractTextPlugin = require('extract-text-webpack-plugin');
// ...
{
  test: /\.css$/,
  loader: ExtractTextPlugin.extract(‘css’)
}

Теперь у нас есть выходной файл CSS, который волшебным образом внедряется в index.html.

Если вы хотите использовать препроцессор, такой как SASS (рекомендую!), вы должны установить sass-loader.

Переименуйте style.css в style.scss и обновите конфигурацию загрузчика:

{
  test: /\.scss$/,
  loader: ExtractTextPlugin.extract(‘css!sass’)
},

Теперь я хочу знать, как управлять изображениями с помощью моей настройки SASS.

В порядке. В вашем CSS (или SASS) вы можете ссылаться на изображение с помощью url(…). Без специального загрузчика эти URL-адреса не изменяются.

Давайте попробуем умный загрузчик. Установите resolve-url-loader и добавьте цепочку загрузчиков:

loader: ExtractTextPlugin.extract(‘css!resolve-url!sass’)

И обратитесь к локальному файлу в вашем коде. Какие? Это не работает?

да. На самом деле Webpack теперь нужен загрузчик для изображений… чтобы знать, что преобразовывать и копировать и… В любом случае. Установите загрузчик файлов.

{
  test: /\.(png|jpg|gif)$/,
  loader: ‘file?name=img/[name].[ext]’
}

Вот. Конфигурация загрузчика для изображений :) Все изображения png/jpg/gif требуютd (в javascript) или @imported (в SASS) будет обрабатываться этим загрузчиком.

Теперь все, что вы вводите в url(path/to/foo.jpg), преобразуется в url(img/foo.jpg) (и изображение копируется сюда!) .

В порядке. Теперь я хочу использовать data-URI. Вы не можете? Ты?

Да, я могу.

Замените свой file-loader на url-loader:

{
  test: /\.(png|jpg|gif)$/,
  loader: ‘url?limit=10000&name=img/[name].[ext]’
}

С этой конфигурацией все изображения размером менее 10000 байт будут встроены как URL-адрес данных в ваш CSS. С другой стороны, это то же самое поведение, что и раньше, потому что url-loader использует file-loader в качестве запасного варианта.

Webpack может предоставить множество других функций, и одной статьи недостаточно, чтобы показать их все. Надеюсь, что скоро найду время написать еще одну статью!