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 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 е безполезен без своите добавки! Подобно на Гълп, знаете ли…

Инсталирайте html-webpack-plugin.

И конфигурирайте приставката във вашия файл 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 и след това в програмата за зареждане на стил.

А сега просто добавете нов запис:

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]’
}

С тази конфигурация всички изображения, по-малки от 10 000 байта, ще бъдат вградени като data-url във вашия CSS. За другия това е същото поведение като преди, защото url-loader използва file-loader като резервен вариант.

Много други функции могат да бъдат предоставени от Webpack и една статия не е достатъчна, за да ги покаже всички. Надявам се скоро да намеря време да напиша друга статия!