Image for post
Image for post

From the Asset Pipeline to Webpack

POST UPDATES

This post content was updated to fix typos and reflect the changes for Webpack support on Rails 6.0 or better. Please visit the updated version at “From the Asset Pipeline to Webpack”

Image for post
Image for post

Starting with Webpack.

If you are creating a new Rails application starting with Webpack is easy.

$ rails new sample_app --webpack
$ rails new sample_app --webpack=react
$ rails new sample_app --webpack --skip-sprockets
config/webpacker.yml
config/webpack
├── development.js
├── environment.js
├── production.js
└── test.js
app/javascript
├── application
│ ├── images
│ ├── javascripts
│ └── stylesheets
└── packs
<%= javascript_pack_tag "application" %>
<%= stylesheet_pack_tag "application" %>
$ WEBPACKER_DEV_SERVER_HOST=0.0.0.0 ./bin/webpack-dev-server
policy.connect_src :self, :https, 'http://localhost:3035', 'ws://localhost:3035' if Rails.env.development?

Moving from the Asset Pipeline to Webpack

Everything described in the previous section applies to new Rails applications but what about an existing application? The same applies but you need to install Webpack manually, sort of.

$ bin/rails g webpacker:install
$ rails webpacker:install:erb
ERROR in ./app/javascript/packs/application.js.erb
Module build failed: Error: rails-erb-loader failed with code: 1
// To reference this file, add <%= javascript_pack_tag 'application' %> to the appropriate
// layout file, like app/views/layouts/application.html.erb
<%%= javascript_pack_tag 'application' %>
import 'image1.png';
import 'image2.png';
...
import 'imageN.png';
<% images_glob = Rails.application.root.join('app', 'javascript', 'application', 'images', '**', '*.{png,svg}') %>
<% Dir.glob(images_glob).each do |image| %>
import '<%= image %>';
<% end %>
<%= image_tag asset_pack_path("application/images/image1.png") %>
import 'application.css';
import 'layout.css';
...
import 'buttons.css';
<% css_glob = Rails.application.root.join('app', 'javascript', 'application', 'stylesheets', '**', '*.{css}') %>
<% Dir.glob(css_glob).each do |file| %>
import '<%= file %>';
<% end %>
import "<%= File.join(Gem.loaded_specs['mygem'].full_gem_path, 'app', 'assets', 'stylesheets', 'myfile.css') %>";
import 'application.scss';
$ bin/yarn add bulma
$ bin/yarn add  jquery turbolinks rails-ujs activestorage
import Rails from 'rails-ujs';
import Turbolinks from 'turbolinks';
import * as ActiveStorage from 'activestorage';
Rails.start();
Turbolinks.start();
ActiveStorage.start();
const webpack = require('webpack');
environment.plugins.append('Provide', new webpack.ProvidePlugin({
$: 'jquery',
jQuery: 'jquery'
}))
import "<%= File.join(Gem.loaded_specs['mygem'].full_gem_path, 'app', 'assets', 'javascripts', 'myfile') %>";
<% ['file1', 'file2'].each do |file| %>
import "<%= File.join(Gem.loaded_specs['mygem'].full_gem_path, 'app', 'assets', 'javascripts', file) %>";
<% end %>
<% files_glob = Rails.application.root.join('app', 'javascript', 'application', 'javascripts', '**', '*.js') %>
<% Dir.glob(files_glob).each do |file| %>
import '<%= file %>';
<% end %>
import '../application/images/index.js.erb';
import '../application/stylesheets/index.js.erb';
import '../application/javascripts/index.js.erb';
require "rails"
# Pick the frameworks you want:
require "active_model/railtie"
require "active_job/railtie"
require "active_record/railtie"
require "active_storage/engine"
require "action_controller/railtie"
require "action_mailer/railtie"
require "action_view/railtie"
# require "action_cable/engine"
# require "sprockets/railtie"
require "rails/test_unit/railtie"

Conclusion

If you get to this part of the blog and your application is running with Webpack for your assets: congratulations! Your team now has modern tools to work on your frontend.

web: bin/rails s -p $PORT
webpack: bin/webpack-dev-server

michelada.io

We plan, code and launch awesome web and mobile products.

Mario Alberto Chávez

Written by

Rubyist and software engineer. @micheladaio co-founder. Author of Aprendiendo Ruby on Rails @railsenespanol. Photography http://mario_chavez.500px.com

michelada.io

We plan, code and launch awesome web and mobile products.

Mario Alberto Chávez

Written by

Rubyist and software engineer. @micheladaio co-founder. Author of Aprendiendo Ruby on Rails @railsenespanol. Photography http://mario_chavez.500px.com

michelada.io

We plan, code and launch awesome web and mobile products.

Medium is an open platform where 170 million readers come to find insightful and dynamic thinking. Here, expert and undiscovered voices alike dive into the heart of any topic and bring new ideas to the surface. Learn more

Follow the writers, publications, and topics that matter to you, and you’ll see them on your homepage and in your inbox. Explore

If you have a story to tell, knowledge to share, or a perspective to offer — welcome home. It’s easy and free to post your thinking on any topic. Write on Medium

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store