This put pressure on Rails to offer up something similar. The solution was Webpacker. A gem that provides a wrapper to work with Webpack itself. This allowed Rails to stick to their motto of convention over configuration with providing some sensible defaults for Webpack while still offering developers who used Rails access to the vast npm repository.
With Rails 6 and above Webpack is now the default but could be integrated into Rails 5 by adding the gem to the Gemfile and then initialising it.
Look through these now and then use them to test yourself after doing the assignment
application.js file. That file was downloaded to a client when it first connected to your server.
Using packs instead, we can have different pack files that can be downloaded only when needed. You can create an unlimited number of packs and just reference that pack on the page it is needed. For example if you had some code to handle form validations on the client side it might not be needed for somebody who never went to the page with the form. With the Asset Pipeline that code would be downloaded at initial page load but using Webpack you can just reference that pack in the view where it is required and it will only download when somebody visits the form.
To see how this is done let’s look at how we reference packs, and touch on how it used to be done using the asset pipeline. Before the Webpacker gem, when there was only the Asset Pipeline, if you started a new Rails application it would create the following lines in the
These lines took the
application.js files in the
Using Webpack and “packs” in Rails 6 we instead get the following lines.
"application" which then loads the
application.js pack file.
As mentioned earlier, unlike the Asset Pipeline which requires everything to be referenced in the
application file, we can include one or several pack files into our app using Webpack. It only requires we place a pack file in the
As an example we may have some code we use to manage a contact form submission. We don’t want it loaded on every page. So in the
packs directory we create a
contact_form.js pack file. Then in our form view we can place the following line at the bottom of the page…
application.js pack file from the rails installation car project you can see it’s only job is to require files from elsewhere and initialise them if necessary.
Going back to our contact_form pack file we might create a directory such as
require a file such as
../contact_form/whatever_file_we_need. Note we use
../ because from our pack directory we will need to move one directory up to find our
With Rubygems we use a Gemfile and with Webpacker we use a
bundle but with Webpack we can use Yarn from the terminal to add a library. If we wanted to add bootstrap we could use
yarn add bootstrap
jest which we wouldn’t need in production code. To do this just add the
--dev option when installing the library
yarn add --dev jest
Packages are installed to the
node_modules folder. Open that at your own peril as it’s known for being a bit of a black hole for code. Due to the size it can take it’s by default excluded from being checked into by git and instead if you clone a project you just use the package.json and yarn to recreate the node_modules folder.
Once you have installed a library then you need to reference it in your pack file. Webpack references the
node_modules folder as a top level directory to search for anything referenced so you aren’t stuck trying to work your way backwards from the pack file when requiring a library with lines like
require ../../node_modules/etc and instead you can just reference the library starting with it’s own folder in node_modules.
stylesheet_pack_tag, such as…
In this case we can require any css into the
application.js file and Rails will load it as css and bundle it together using Webpack.
One key thing to note when you’re using Webpacker is how it works out what code to load. With the Asset Pipeline because all code was required to be loaded in the
application.js file, Rails could build just one dependency graph of all the code and make sure no code was included twice. A good example of this might be if you used jquery in your application and then used a third party library that also uses jquery and was listed as one of its dependencies, then the Asset Pipeline would ensure it was only loaded once so you didn’t bloat your code.
With Webpack it builds a dependency graph for each pack file so it’s possible, if different pack files both require the same library, to bundle the same code twice into the different packs which would then make the overall download size for the client to download everything it needs much larger. There are several ways to ensure you don’t do this but the easiest way, at least when starting out, is to only use the default
application.js pack file. If you only have one pack file where all the code you need is included then the dependency graph will be built from that one file and Webpack will ensure it optimises the code required.
There isn’t a huge amount of reading to do here. But a couple of links just to get you a better understanding of Webpack.