Простое руководство по переходу со Sprockets на Webpacker

Обновлено 1 мая 2020 г. для Webpacker 5.

Обновлено 30 августа 2019 г. для Webpacker 4 и Rails 6.0 и добавлены пользовательские шрифты.

Это руководство познакомит вас с процессом миграции вашего Rails-приложения со Sprockets на Webpacker. Несмотря на то, что Webpacker предлагает продолжать использовать Sprockets для CSS и изображений, я действительно не понимаю, почему мы должны держать два сборщика одновременно, когда мы можем просто использовать Webpacker для всего.
Затем мы сначала переместим только Javascript часть вашего кода, а затем мы также увидим, как перемещать CSS, изображения, шрифты и т. д.

Требования

Мы начнем это руководство с приложения Rails, которое использует Sprockets. Вы, вероятно, переходите на Rails 6.0 или уже сделали это, и вам интересно, как вы можете легко перенести также свой Javascript в Webpacker и никогда не вернуться.

Я предлагаю вам перенести ваше приложение на Rails 6.0, а затем продолжить работу с этим руководством, но это не обязательно: при разработке программного обеспечения есть много вещей, которые не нужны, но время от времени вы должны рискнуть. сделать их 😉 .

Добавление драгоценных камней

Первое, что нужно сделать, это добавить webpacker gem в Gemfile нашего проекта:

gem 'webpacker', '~> 5.0'

и установите его, следуя README проекта:

bundle
bundle exec rails webpacker:install

ПРИМЕЧАНИЕ. Чтобы использовать Webpacker, у вас должен быть установлен node.js.
Установка и настройка node.js не является частью этого руководства, но я предлагаю вам использовать последнюю стабильную версию и записать ее в .nvmrc файл в корне проекта, который сможет прочитать nvm.

Теперь у нас есть готовый Webpacker, и мы уже можем его использовать! 🎉

Я не буду объяснять вам, что делает Webpacker и какие файлы он генерирует: вам не нужно знать это сейчас. Теперь вам нужно сбросить звездочки. Это наша цель на сегодня.

Попробуй это

Это действительно работает? Давайте сначала проверим это.

Давайте познакомимся с нашей первой созданной папкой: app/javascript. Это эквивалент нашей старой, дорогой, app/assets/javascript папки, и, как и в старой, вы создадите packs/application.js файл, с которого можно начать.

app/javascript:
 └── packs:
   └── application.js

# application.js
console.log('Hello World from Webpacker');

Этот файл является точным эквивалентом app/assets/javascript/application.js: это отправная точка, в которую мы будем включать все наши ресурсы JS.

Давайте добавим его в наш шаблон, как мы это делали для старого, используя

= javascript_pack_tag 'application'

(вы можете добавить опцию 'data-turbolinks-track': 'reload', если используете Turbolinks.)

и мы должны увидеть сообщение «Hello World» в инструментах разработчика Chrome, подтверждающее, что все работает нормально:

Перенести Javascript

Теперь, когда у нас установлен Webpacker и все работает нормально, мы можем продолжить, переместив наши старые файлы Javascript. Наша application.js имеет очень простую структуру:

//= require jquery
//= require jquery_ujs
//= require turbolinks
//= require bootstrap-sprockets
//= require formvalidation/formValidation
//= require formvalidation/bootstrap4.min
//= require_tree .

для этого в основном требуются некоторые библиотеки (jquery, turbolinks и т. д.), а затем включаются наши пользовательские файлы Javascript.
Давайте начнем с последних: шаги просты:

  1. Удалите //= require_tree . из старого app/assets/application.js
  2. Переместить все файлы и папки из app/assets/javascript в /app/javascript/src (кроме application.js)
  3. Импортируйте все свои файлы в новый packs/application.js
import '../src/filename.js';

Перенести библиотеки

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

//= require jquery
//= require rails-ujs
//= require turbolinks
//= require bootstrap-sprockets

Нам нужно загрузить эквивалентный пакет npm и потребовать их.

Настроить jquery

Если вы используете JQuery в своем приложении, вы, вероятно, не хотите избавляться от него сейчас (также потому, что он все еще требуется для Bootstrap ...), чтобы мы могли его перенести. Добавьте пакет:

yarn add jquery

Теперь нам нужно настроить Webpacker для включения его во все наши среды. Для этого меняем файл environment.js.

# app/config/webpack/environment.js
const {environment} = require('@rails/webpacker');

const webpack = require('webpack');
environment.plugins.append('Provide', new webpack.ProvidePlugin({
  $: 'jquery',
  jQuery: 'jquery'
}));

module.exports = environment;

так что вы, наконец, можете использовать его в своем application.js файле.

# app/javascript/packs/application.js
$(function () {
  console.log('Hello World from Webpacker');
});

Настройка rails-ujs и турболыков

Устанавливаем модули:

yarn add @rails/ujs turbolinks

и запустите их:

# app/javascript/packs/application.js
require("@rails/ujs").start()
require("turbolinks").start()

если вы используете ActiveStorage и ActionCable, вы также можете установить и потребовать их:

yarn add @rails/actioncable @rails/activestorage
require("@rails/activestorage").start()
require("channels")

Настроить Bootstrap

Последним недостающим элементом является Bootstrap. JQuery существует, поэтому мы можем просто установить пакет и потребовать его.

yarn add bootstrap popper.js

добавить Popper в конфигурацию окружения:

# app/config/webpack/environment.js
...
environment.plugins.append('Provide', new webpack.ProvidePlugin({
  $: 'jquery',
  jQuery: 'jquery',
  Popper: ['popper.js', 'default']
}));

...

и импортируем плагины:

# app/javascript/packs/application.js
import 'bootstrap/dist/js/bootstrap';

С помощью Bootstrap мы успешно переместили все наши ресурсы Javascript в webpack. Мы можем удалить старый application.js файл и удалить его импорт из нашего шаблона.

Как видите, переместить javascript из Sprockets в Webpacker довольно просто. Как только вы поймете, как организованы файлы и модули, вы увидите, что это просто, как это было со Sprockets, и вы можете удалить некоторые драгоценные камни и импортировать соответствующий пакет npm. В нашем случае, например, мы уже могли удалить sprockets-es6, jquery-turbolinks и jquery-rails.

Webpacker предназначен для управления файлами javascript, поэтому мы можем остановиться на этом и продолжать использовать звездочки для изображений и CSS, но он также может управлять этими ресурсами, поэтому я думаю, что стоит также взглянуть на то, как их перенести.

Перенести CSS

Мы также можем управлять таблицами стилей с помощью Webpacker. Наше приложение содержит несколько настраиваемых файлов SCSS в папке с ресурсами, bootstrap и font-awesome из драгоценного камня и таблицу стилей в папке поставщика.

@import 'font-awesome';
@import 'shared/variables';
@import 'bootstrap';
@import 'transactions';
@import 'custom_buttons';
@import 'formValidation.min';

Мы начнем с переименования папки Webpacker, потому что кажется неправильным помещать таблицы стилей в папку javascript. Переименуйте app/javascript в app/webpacker и переместите все файлы javascript с app/javascript/src на app/webpacker/src/javascripts. Не забудьте изменить config/webpacker.yml:

source_path: app/webpacker

Создайте файл app/webpacker/packs/stylesheets.scss и переместите ресурсы CSS в папку app/webpacker/src/stylesheets.
Файл будет очень похож на исходный:

#app/webpacker/packs/stylesheets.scss
@import '../src/stylesheets/transactions';
@import '../src/stylesheets/custom_buttons';

включите извлечение CSS в webpacker.yml, установив extract_css: true и включив в свой шаблон следующий вызов:

= stylesheet_pack_tag 'stylesheets'

Бутстрап

Чтобы бутстрап работал и скомпилировался из SCSS, вы можете просто включить следующее в наш новый stylesheets.scss

@import '~bootstrap/scss/bootstrap';

Поскольку мы настроили наш начальный загрузчик, мы можем импортировать переменные, как делали раньше, через

@import '../src/stylesheets/shared/variables';

перед импортом bootstrap.

Если вы раньше использовали SCSS, в конце концов, это не сильно изменится.

В конце концов, нам нужно импортировать font-awesome из пакета npm вместо gem.

# fontawesome 4
yarn add font-awesome
# fontawesome 5 
yarn add @fortawesome/fontawesome-free

а также

# fontawesome 4
$fa-font-path: "~font-awesome/fonts";
@import '~font-awesome/scss/font-awesome';
# fontawesome 5
$fa-font-path: '~@fortawesome/fontawesome-free/webfonts';
@import '~@fortawesome/fontawesome-free/scss/fontawesome';
@import '~@fortawesome/fontawesome-free/scss/solid';

и можно удалить старую ссылку на файл звездочек

= stylesheet_link_tag 'application'

Изображений

Перенести ваши изображения довольно просто. Что мы собираемся сделать, так это создать пакет, содержащий все изображения, и импортировать их.

Создайте папку app/webpacker/images и переместите в нее все изображения.

Теперь импортируйте их в свой application.js файл с помощью

require.context('../images', true);

Теперь все ваши изображения доступны через Webpacker. Чтобы использовать их, вам нужно заменить старые изображения с помощью помощника asset_pack_path.

 - asset_path('icon.png')
 + image_pack_path('icon.png')

Поскольку помощник Sprockets больше не доступен, вам необходимо заменить их в своих файлах SCSS:

  .google-icon {
-   background-image: image-url('btn_google_dark.svg');
+   background-image: url('../images/btn_google_dark.svg');
  }

Шрифты

Поместите свои пользовательские шрифты в папку app/webpacker/fonts и импортируйте их в свой stylesheets.scss с помощью:

@font-face {
 font-family: YourFontFamily;
 src: url('../fonts/yourfile.ttf') format('truetype');
}

Заключение

Вы успешно заменили Sprockets на Webpacker и можете начать пользоваться всеми его преимуществами, такими как горячая перезагрузка модуля или анализ пакетов.

Означает ли это, что вы больше не будете использовать звездочки? С моей точки зрения да.
Просто нет смысла использовать более медленный инструмент с меньшим количеством функций, когда использовать Webpacker так просто.

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

Если я что-то пропустил или у вас есть вопросы, оставьте комментарий.
Если вы хотите узнать о некоторых интересных функциях, которые вы можете использовать теперь, когда у вас установлен Webpacker, прочтите мои статьи о Горячая перезагрузка модуля для CSS и Горячая перезагрузка модуля для React.