Why Webpack?
JavaScript applications are getting more complex every day and developers are taking advantage of new versions of the language, new ways of coding are becoming more popular as well, that means lots of modules with dependencies, 3rd party libraries and more and more assets each day.
Webpack is a static module bundler for modern JavaScript applications, it processes your application and builds a dependency graph that includes every module, then it packages all modules into one or more bundles.
By using webpack we can take advantage of JavaScript new features included on ES6, and for React/Angular developers, things like TypeScript and JSX, it’s also possible to use webpack for CSS, images and font assets.
Webpacker
Webpacker is a ruby gem which allows us to use JavaScript pre-processor and webpack as a bundler to manage applications like JavaScript in Rails, in some cases you may not even need the Rails asset pipeline.
You can refer to the Github repo and check for updated requirements:
https://github.com/rails/webpacker
Adding webpacker to Rails
New application
# Available Rails 5.1+
$ rails new myapp --webpack
Existing Rails application
Add webpacker gem to the Gemfile:
# Gemfile
gem 'webpacker', '~> 3.2'
# OR if you prefer to use master
gem 'webpacker', git: 'https://github.com/rails/webpacker.git'
Then run:
$ bundle install
$ bundle exec rake webpacker:install
This will add some new files to your project:
app/javascript:
├── packs:
│ # only webpack entry files here
│ └── application.js
└── src:
│ └── application.css
└── images:
└── logo.svg
React joins the game
As you may know by now, React has been very popular over the last few years since its first version, and many changes and architectures have been getting popular too using it as the nuclear pieces of a puzzle, so let’s invite it to join this game:
Install react
We are using a gem called react-rails
which wraps everything we need to get started with react inside our rails views, simply add the gem to the Gemfile.
gem ‘react-rails’
Then, as usual run:
$ bundle install
$ bundle exec rake webpacker:install:react
$ rails generate react:install
That will install the ReactRailsUJS setup, a directory for your components and a script for server rendering.
Use processed JavaScript
You can link the javaScript processed by webpack using the javascript_pack_tag, also if you have styles imported into your pack file, you can use stylesheet_pack_tag, in my case I just added javaScript inside app/views/layouts/application.html.erb
<!DOCTYPE html>
<html>
<head>
<title>Rails 5 + Webpack</title>
<%= csrf_meta_tags %>
<%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %>
<%= javascript_include_tag 'application', 'data-turbolinks-track': 'reload' %>
<%= javascript_pack_tag 'application' %>
</head>
<body>
<%= yield %>
</body>
</html>
Generate new components
Just run this command:
$ rails g react:component HelloWorld greeting:string
It is added to app/javascript/components/
To render this component into a Rails view:
<%= react_component("HelloWorld", { greeting: "Hello" }) %>
Write some CSS
Eventually you may want to write your own CSS using a preprocessor like SASS inside your application, it’s easy to get webpack bundling all our stylesheets.
Adding CSS generated by webpack
This is a simple step, add the “ helper to your view:
app/views/layouts/application.html.erb
<!DOCTYPE html>
<html>
<head>
<title>UppyUploader</title>
<%= csrf_meta_tags %>
<%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %>
<%= javascript_include_tag 'application', 'data-turbolinks-track': 'reload' %>
<%= javascript_pack_tag 'application' %>
<%= stylesheet_pack_tag 'application' %>
</head>
<body>
<%= yield %>
</body>
</html>
Also, rename your application.css
to application.scss
if needed.
In this step you can add third party libraries css as well if needed it, this could be done using npm packages.
app/javascript/stylesheets/application.scss
@import 'uppy/dist/uppy.min.css';
Now, if you also want to bundle your scss using webpack, you must include the styles inside your application.js
app/javascript/packs/application.js
var componentRequireContext = require.context("components", true);
var ReactRailsUJS = require("react_ujs");
ReactRailsUJS.useContext(componentRequireContext);
import 'styles/application.scss';
Once you’ve done this, you can use the application.scss
as the application entry point for all your SCSS imports and partials.
app/javascript/stylesheets/application.scss
@import 'uppy/dist/uppy.min.css';
@import 'colors';
@import 'global';
@import 'example-selector';
Conclusion
Now you can start building react components and give them nice and cool styling if you want. I wrote this post because even if you have everything you need to get these two things working, it can be hard to figure out how to wrap up everything the way you want. Personally, I don’t like to have css files spread across different folders. I want to keep everything well organized in an entry file and importing everything as partials; how about you? It’s your call how you do it at the end, but it’s important to know that there are other ways to build an application. I learnt this while I was coding a working example for Transloadit’s Uppy File Uploader.
I hope you’ve enjoyed this quick intro and I also hope this helps you coding.
See you!