Вот это да. Теперь мы здесь! В предыдущей статье этой серии мы познакомились с Webpack и рассказали, какие проблемы он решает. Если вы его пропустили, то отметьте его здесь.

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

mkdir learning_webpack
cd learning_webpack

Хороший. Затем давайте добавим webpack в качестве зависимости разработчика в наш package.json при создании файлов index.html и index.js.

// Execute these in learning_webpack directory
npm init -y 
npm install [email protected] --save-dev
touch index.html
touch index.js
// index.html
<!doctype html>
<html>
  <head>
    <meta charset="utf-8" />
    <title>Learning Webpack</title>
  </head>
  <body>
    <div id="app"></div>
    <script src="index.js"></script>
  </body>
</html>

Мы только что создали базовый HTML-код и указали в нем index.js файл. Пока это отличная работа. Молодцы!

В предыдущей статье мы сказали, что webpack представляет так называемый График зависимостей. Это достигается за счет использования ключевого слова magic require при извлечении зависимостей. Это можно объяснить на простом примере, показанном ниже:

// index.js
function HelloComponent(message) {
  this.message = message;
}
HelloComponent.prototype.appendMessage = function() {
  var p = document.createElement('p');
  p.innerText = this.message;
  var main = document.getElementById('app');
  main.appendChild(p);
}
var component = new HelloComponent('Hello world!');
component.appendMessage();

Это довольно просто. Здесь нет особой проблемы с зависимостью. Но давайте предположим, что все сообщения у нас были в другом файле, и мы хотели создать другие компоненты, которые зависели от этого файла сообщений. См. Код ниже:

cd [/path/to/learning/webpack]
$touch messages.js
// messages.js
const messages = {
  hello: 'Hello world!',
  hi: 'Hi everyone!'
}
module.exports = messages;

Мы только что создали файл сообщений в том же каталоге, что и index.js, и экспортировали объект message, используя синтаксис commonJS (это учитывает наличие module.exports). Без module.exports мы получили бы 2 сценария в index.html, т.е. index.js и messages.js. Это довольно просто. Ура!!

Затем давайте немного изменим HelloComponent, чтобы теперь он зависел от messages:

// index.js
var messages = require('./messages');
function HelloComponent() {
  this.message = message;
}
HelloComponent.prototype.appendMessage = function() {
  var p = document.createElement('p');
  p.innerText = this.message;
  var main = document.getElementById('app');
  main.appendChild(p);
}
var component = new HelloComponent(messages.hello);
component.appendMessage();

Обратите внимание на использование require:

var messages = require('./messages');

Webpack распознает наличие require и может получить необходимую зависимость, например, messages от messages.js.

Каким образом здесь Webpack играет? Чтобы лучше убедиться, давайте теперь выполним следующие команды.

./node_modules/.bin/webpack index.js dist/index.js

Если вы последуете по тексту, вы увидите куски, генерируемые Webpack, и то, как прошла обработка. Таким образом, webpack как исполняемая команда принимает 2 аргумента, то есть входной файл и выходной файл (не беспокойтесь, если он не существует). Что ж, если вы установили Webpack глобально, вы также можете выполнить указанную выше команду как: webpack index.js dis/index.js. После выполнения команды создается новая папка с именем dist с файлом index.js. Попробуйте проверить этот файл. Это весело. Что ж, для подсказки, Webpack вставляет некоторый шаблонный код, прежде чем помещать ваш код под ним.

На этом этапе нам нужно немного подправить наш скрипт в index.html. Теперь это выглядит так:

<script src="dist/index.js"></script>

На этом этапе можно сделать вывод, что независимо от зависимых сценариев Webpack преобразует их в простой единый сценарий, и все будет управляться за вас. Только после этого вы сосредотачиваетесь на управлении своим кодом, а Webpack обрабатывает все зависимости. Разве это не круто?

А что насчет других изображений? В сегодняшних быстро развивающихся вычислениях одностраничные приложения действительно бушуют. Раааааррр !! HTML теперь кажется помещенным в JavaScript. И это тоже включает CSS. Так что насчет изображений, которые становятся зависимостями в этих файлах? Хм… интересно.

Хорошо, теперь поговорим о загрузчиках. Но как насчет вопроса об изображениях? Я знаю. Понимание загрузчиков поможет ответить на этот вопрос. Все, что не является JavaScript, но становится зависимостью в файле JavaScript, может быть обработано Webpack при наличии загрузчика. Так что просто найдите style-loader или css-loader, если вам нужен какой-то CSS. С изображениями, возможно, найду file-loader. Так что все, что не является JavaScript, но является зависимостью в вашем модуле, найдите его loader и снимите его! Но как нам использовать loader в Webpack?

Наша работа становится все более беспорядочной. Давайте поместим все, что нужно Webpack, в файл конфигурации - webpack.config.js (ну, это имя по умолчанию для файла конфигурации).

// webpack.config.js
var path = require('path');
module.exports = {
  entry: 'index.js',
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: 'index.js'
  }
}

Все еще используя модуль commonJS, мы экспортируем объект конфигурации. Что ж, какой-то компонент сбивает с толку? Думаю, вам интересно, откуда взялся модуль path? Это путь модулей по умолчанию, поставляемых с Node.js. Я просто require (осваиваю) это и хорошо этим пользуюсь. Теперь мы можем просто запустить одну команду:

webpack

Только то? да. Webpack прочитает инструкции из webpack.config.js файла и построит выходной файл. Прохладный! А теперь давайте добавим загрузчик изображения. Но сначала давайте добавим img в index.js файл.

// index.js (a portion of it gets updated)
var image = require('./img.png') // Make sure that file exists
HelloComponent.prototype.appendImage = function() {
  var div = document.createElement('div');
  div.innerHTML = '<img src="' + image + '" />';
  var app = document.getElementById('app')
  app.appendChild(div);
}

Затем мы добавляем loader в webpack.config.js файл следующим образом:

// Execute the following commands
npm install file-loader -D
// webpack.config.js
var path = require('path');
module.exports = {
  entry: 'index.js',
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: 'index.js'
  },
  module: {
    rules: [{
      test: /\.png/,
      use: 'file-loader'
    }]
  }
}

modules принимает одно правило или набор правил. Каждое правило принимает один или несколько loaders. Перейдите сюда, чтобы узнать больше о погрузчиках.

Итак, мы заканчиваем вторую часть этой серии. Мы обсудили, как настроить Webpack. Мы также обсудили, как обрабатывать зависимости JavaScript и зависимости, отличные от JavaScript. Webpack может делать и другие удивительные вещи. Следите за новостями в следующих статьях.