Vue.js + Brunch: Альтернатива Webpack по которой вы изголодались

28.09.2017

Представьте, что если бы был инструмент сборки проектов Vue.js, который компилировал быстрее, чем Webpack, выдавал меньший размер пакета и требовал всего несколько строк конфигурации…

Brunch(англ.-поздний завтрак) — это тот инструмент. В этой статье я покажу вам, как невероятно просто настроить проект Vue.js + Brunch и расскажу о плюсах и минусах Brunch.

Чтобы подогреть ваш интерес, взгляните на это сравнение конфигураций Webpack и Brunch для одного простого проекта Vue.js:

Устали от Webpack?

Webpack — это важный инструмент для создания сложных, высоко оптимизированных веб-приложений и поощряется многими влиятельными веб-разработчиками.

Однако, для новеньких или тех, кто работает над менее амбициозными проектами, Webpack в основном является препятствием. Пользователи чувствуют, для проектов Vue.js они должны выбирать либо разработку в среде lo-fi ES5 без клёвых фишек, как однофазные компоненты, либо в очень сложной среде с таким же количеством времени, затрачиваемого на конфигурацию сборки, как и на разработку приложения.

Освобождаем место для Brunch!

Brunch существует с 2012 года, и, хотя он является инструментом построения по умолчанию для платформы Phoenix Elixir, он все еще удивительно непопулярен. Тем не менее, у него есть преданая группа пользователей, любящих его за свою основную философию «простоты и скорости», которую поддерживают и пользователи Vue.js .

Несмотря на свою непопулярность, почти 80 плагинов, созданных сообществом, предназначены для самых востребованных автоматизированных систем, таких как транспилинг, linting, оптимизация и т. д. Brunch может выполнять большую часть того, что вам понадобится в проекте Vue: обернуть файлы как модули, объединить их в сборку, компилировать Vue-файлы, транспилировать JS и SASS и так далее.

Чтобы быть ясно, Brunch не так полнофункционален, как Webpack, и имеет определенные ограничения. Например, Brunch пока не поддерживает динамический импорт и не обрабатывает изображения и шрифты.

Условия конфигурации

Определяющей особенностью Brunch является то, что он упрям ​​и предпочитает условия конфигурации. Если вы хотите структурировать свой проект «Brunch way», и вы довольны стандартными настройками большинства плагинов, вам может потребоваться лишь несколько строк конфигурации для довольно сложной сборки.

Возьмем пример предварительной компиляции SASS. В Webpack каждый проект должен объявлять загрузчики для типа файла, который будет обработан. Типичная конфигурация SASS:

webpack.config.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
module.exports = {
...
module: {
rules: [{
test: /\.scss$/,
use: [{
loader: "style-loader"
}, {
loader: "css-loader"
}, {
loader: "sass-loader"
}]
}]
}
};

Однако с Brunch всё что вам нужно сделать, это установить плагин Brunch SASS. Brunch сканирует ваш пакет package.json при запуске сборки и, увидев, что вы установили плагин, обо всём позаботится.

Пробуем на вкус

Чтобы узнать, что может делать Brunch, я установил проект Vue.js с использованием шаблона проекта Vue CLI webpack-simple. После создания шаблона с помощью Webpack я получаю следующее:

Теперь я переношу этот проект в Brunch и пытаюсь воссоздать те же функции сборки и процессы, что и Webpack, чтобы подчеркнуть любые сходства и различия.

Не стесняйтесь загружать полный код из этого репо и следовать ему.

Установка

Как и Webpack, Brunch лучше всего установить глобально, тогда CLI Brunch можно запускать из любого места.

$ npm i -g brunch

А также установите его локально:

$ npm i --save-dev brunch

Конфигурация

Brunch аналогичную Webpack декларативную конфигурацию. Ниже приведена минимальная конфигурация для запуска Brunch. Все, что он выполнит, — это модуляция и объединение любых файлов JavaScript в каталоге watch в выходной файл app.js.

brunch-config.js

1
2
3
4
5
6
7
module.exports = {
files: {
javascripts: {
joinTo: 'app.js'
}
}
};

В отличие от Webpack, Brunch не требует входного файла. Вместо этого у вас есть каталог watch и Brunch просто обрабатывает каждый файл там, если это возможно.

Каталог watch по умолчанию в Brunch — это app, а не src. App в этом проекте будет использовать минимальную конфигурацию Brunch, поэтому я буду перемещать туда все файлы проекта:

$ mv src app

Сборка

Теперь можешь запустить первую сборку:

$ brunch build

В результате приятное сообщение:

14:32:19 - info: compiled main.js into app.js, copied logo.png in 466 ms

И создается новый общедоступный каталог, содержащий следующие файлы сборки:

public
— app.js
— app.js.map
— logo.png

JavaScript файл сборки

При проверке основного файла сборки JavaScript public/app.js первые 149 строк представляют собой код начальной загрузки Brunch, который будет в каждой сборке. После этого код из main.js — единственный файл JavaScript в папке watch:

1
2
3
4
5
6
7
8
9
require.register("main.js", function(exports, require, module) {
import Vue from 'vue'
import App from './App.vue'
 
new Vue({
el: '#app',
render: h => h(App)
})
});

Brunch завернул main.js в качестве модуля CommonJS. Однако он не импортировал vue или App.vue и не перешел на ES5. Нам понадобятся дополнительные плагины для этих задач.

Assets

Другим условием Brunch является то, что любой каталог, называемый assets, будет рекурсивно скопирован в public папку без какой-либо обработки, поэтому вы увидите logo.png в результатах.

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

Плагины

Чтобы обработать файлы проекта, мне нужно добавить некоторые плагины в Brunch. Есть код ES6, а также файл Vue, который включает SASS, поэтому я буду устанавливать соответствующие плагины для этих типов файлов:

$ npm i - save-dev babel-brunch babel-preset-es2015 vue-brunch sass-brunch

Я также установил babel-preset-es2015, чтобы получить JavaScript совместимый с браузером. Мне нужно будет обновить файл .babelrc, чтобы указать на это, поскольку Webpack имеет более сложные средства для определения того, для какой среды следует строить:

.babelrc

1
2
3
4
5
{
"presets": [
[ "es2015" ]
]
}

Удивительно, но это все, что требуется! Когда я снова запускаю сборку, то получаю этот вывод:

15:05:57 - info: compiled 4 files into app.js, copied logo.png in 1.5 sec

Еще раз проверьте файл сборки public/app.js, есть еще много кода. Это связано с тем, что Brunch перекодировал ES6 в main.js, нашел зависимость Vue и добавил, а также обработал и импортировал App.vue.

Как Brunch может делать это без какой-либо конфигурации? Он видит эти плагины в зависимостях в package.json и просто регистрирует их с настройками по умолчанию.

Обслуживание Brunch

Я создал весь код проекта, поэтому пришло время пойти в браузер и посмотреть, что же там получилось.

Как и у Webpack, у Brunch есть встроенный сервер разработки, который я могу использовать для обслуживания проекта. Он также будет следить за любыми изменениями файлов и автоматически менять (очень быстро).

Однако, прежде чем я запустил сервер, я переместил index.html в каталог assets, чтобы он был скопирован в public папку и так же выполнен:

$ mv index.html ./app/assets

Теперь я могу запустить сервер:

$ brunch watch --server

Получаем вот такой вывод:

15:16:40 - info: application started on https://localhost:3333/
15:16:40 - info: compiled 4 files into app.js, copied 2 in 1.7 sec

Вызов main.js

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

Помните, что Brunch обертывает все файлы в модули CommonJS на выходе следующим образом:

1
2
3
require.register("main.js", function(exports, require, module) {
// Содержание main.js
}

Суть в том, что модуль назван по имени своего файла минус расширение, поэтому main.js является основным. Теперь мне нужно вызвать этот модуль в index.html после загрузки сценария:

app/assets/index.html

1
2
3
4
5
<body>
<div id="app"></div>
<script type="text/javascript" src="/app.js"></script>
<script type="text/javascript">require('main');</script>
</body>

vue-brunch

Ок, почти готово. Обновляя браузер снова, я получаю ошибку:

Uncaught Error: Cannot find module 'vueify/lib/insert-css' from 'App.vue'

Это связано с тем, что API-интерфейс Brunch не такой мощный, как Webpack, и для возможности встроить CSS во время выполнения, vue-brunch требует, чтобы модуль vueify-insert-css был доступен.

Это должно быть импортировано вверху main.js:

import 'vueify/lib/insert-css';

Приложение Vue снова работает:

Разница в работе

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

У Webpack есть опция конфигурации, отключающая раздражающее сообщение о режиме разработки. Насколько я знаю, это невозможно сделать с помощью Brunch, поэтому мне придется добавить эту строку в main.js после импорта Vue:

main.js

1
2
import Vue from 'vue';
Vue.config.productionTip = false;

Я также хочу сократить файл сборки JavaScript, чтобы он был приятным и компактным. Для этого я установлю brunch-uglify-js:

$ npm i --save-dev brunch-uglify-js

Как вы могли догадаться, дальнейшая настройка не требуется. Все, что мне нужно сделать, это добавить параметр -p (production) в Brunch при сборке, и на выходе код будет сжат.

$ brunch build -p

Все очень просто!

Сравнение

Я успешно заменил функциональность сборки webpack-simple с помощью Brunch. Давайте теперь сравним разницу в файлах конфигурации.

Сначала Webpack:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
var path = require('path')
var webpack = require('webpack')
 
module.exports = {
  entry: './src/main.js',
  output: {
    path: path.resolve(__dirname, './dist'),
    publicPath: '/dist/',
    filename: 'build.js'
  },
  module: {
    rules: [
      {
        test: /\.vue$/,
        loader: 'vue-loader',
        options: {
          loaders: {
            // Since sass-loader (weirdly) has SCSS as its default parse mode, we map
            // the "scss" and "sass" values for the lang attribute to the right configs here.
            // other preprocessors should work out of the box, no loader config like this necessary.
            'scss': 'vue-style-loader!css-loader!sass-loader',
            'sass': 'vue-style-loader!css-loader!sass-loader?indentedSyntax'
          }
          // other vue-loader options go here
        }
      },
      {
        test: /\.js$/,
        loader: 'babel-loader',
        exclude: /node_modules/
      }
    ]
  },
  resolve: {
    alias: {
      'vue$': 'vue/dist/vue.esm.js'
    }
  },
  devServer: {
    historyApiFallback: true,
    noInfo: true
  },
  performance: {
    hints: false
  },
  devtool: '#eval-source-map'
}
 
if (process.env.NODE_ENV === 'production') {
  module.exports.devtool = '#source-map'
  // https://vue-loader.vuejs.org/en/workflow/production.html
  module.exports.plugins = (module.exports.plugins || []).concat([
    new webpack.DefinePlugin({
      'process.env': {
        NODE_ENV: '"production"'
      }
    }),
    new webpack.optimize.UglifyJsPlugin({
      sourceMap: true,
      compress: {
        warnings: false
      }
    }),
    new webpack.LoaderOptionsPlugin({
      minimize: true
    })
  ])
}

(Обратите внимание, что приведенное выше не имеет конфигурации файлового загрузчика, поскольку это невозможно в Brunch).

И теперь, Brunch:

brunch-config.js

1
2
3
4
5
6
7
module.exports = {
files: {
javascripts: {
joinTo: 'app.js'
}
}
};

Как видите, Brunch требует значительно меньшую конфигурацию, если вы следуете его условиям. Однако, в Brunch мне пришлось добавить две дополнительные строки кода в main.js и одну дополнительную строку в index.html, чтобы получить эквивалентную функциональность.

Тесты

А как насчет размера и производительности? Сравнение производственной сборки из обоих инструментов:

Tool   Bundle size Compilation speed
Webpack     87K            4.1sec
Brunch      64K            1.3sec    

Удивительно, но Brunch имеет меньший размер пакета и скомпилирован более чем в 3 раза быстрее, чем Webpack.

Вывод

Я думаю, что Brunch — отличный выбор для простых Vue проектов. Его не только просто настроить, но и очень быстро, плюс меньший размер файла на выходе.

Однако это не означает, что Brunch универсально лучше, чем Webpack. Есть много вещей, которые Brunch не умеет делать, например динамический импорт, который необходим для создания PWA.

Дело в том, что, хотя Webpack определенно имеет свое место в работе, Brunch тоже хорошо справляется с этим.

Приготовь свой Brunch сам

Как и в Vue CLI, вы можете создавать скелеты проекта. Я рекомендую сначала попробовать brunch-vue-barebones, который очень похож на то, что я настроил.

Так же загляните в документацию Brunch или это классное руководство от сообщества для лучшего ознакомления и, конечно же, забавных каламбуров с названием этого чудесного сборщика.

Приятного аппетита!

Оригинальная статья: https://vuejsdevelopers.com/2017/08/20/vue-js-brunch/

Комментарии

  • Оставьте первый комментарий - автор старался!

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

Сообщить об опечатке

Текст, который будет отправлен нашим редакторам: