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 может предоставить множество других функций, и одной статьи недостаточно, чтобы показать их все. Надеюсь, что скоро найду время написать еще одну статью!