Shakapacker

Official, actively maintained successor to rails/webpacker. Internal naming for shakapacker will continue to use webpacker where possible for v6. ShakaCode stands behind long-term maintainence and development of this project for the Rails community.

  • See V6 Upgrade for upgrading from v5 or prior v6 releases.

Ruby specs Jest specs Rubocop JS lint

node.js Gem npm version

Webpacker makes it easy to use the JavaScript pre-processor and bundler Webpack v5+ to manage application-like JavaScript in Rails. It can coexist with the asset pipeline, leaving Webpack responsible solely for app-like JavaScript, or it can be used exclusively, making it also responsible for images, fonts, and CSS.

Check out 6.1.1+ for SWC and esbuild-loader support! They are faster than Babel!

See a comparison of webpacker with jsbundling-rails.

Discussion forum and Slack to discuss debugging and troubleshooting tips. Please open issues for bugs and feature requests:

  1. Discussions tab
  2. Slack discussion channel
  3. Tweets with tag #shakapacker

ShakaCode offers suppport for upgrading from webpacker or using Shakapacker. If interested, contact justin@shakacode.com. ShakaCode is hiring passionate engineers that love open source.


Prerequisites

  • Ruby 2.6+
  • Rails 5.2+
  • Node.js 12.13.0+ || 14+
  • Yarn

Features

  • Rails view helpers that fully support Webpack output, including HMR and code splitting.
  • Convenient but not required webpack configuration. The only requirement is that your webpack configuration create a manifest.
  • HMR with the webpack-dev-server, such as for hot-reloading for React!
  • Automatic code splitting using multiple entry points to optimize JavaScript downloads
  • Webpack v5+
  • ES6 with babel, SWC, or Esbuild
  • Asset compression, source-maps, and minification
  • CDN support
  • Extensible and configurable. For example, all major dependencies are specified as peers, so you can upgrade easily.

Optional support

Requires extra packages to be installed.

  • React
  • TypeScript
  • Stylesheets - Sass, Less, Stylus and Css, PostCSS
  • CoffeeScript

Installation

Rails v6+

With Rails v6+, skip JavaScript for a new app and follow below Manual Installation Steps to manually add the shakapacker gem to your Gemfile.

rails new myapp --skip-javascript

Note, Rails 6 installs the older v5 version of webpacker unless you specify --skip-javascript.

Add shakapacker gem to your Gemfile:

bundle add shakapacker --strict

Then running the following to install Webpacker:

./bin/bundle install
./bin/rails webpacker:install

When package.json and/or yarn.lock changes, such as when pulling down changes to your local environment in a team settings, be sure to keep your NPM packages up-to-date:

yarn

Note, in v6, most JS packages are peer dependencies. Thus, the installer will add the packages:

yarn add @babel/core @babel/plugin-transform-runtime @babel/preset-env @babel/runtime babel-loader \
  compression-webpack-plugin terser-webpack-plugin \
  webpack webpack-assets-manifest webpack-cli webpack-merge webpack-sources webpack-dev-server

Previously, these "webpack" and "babel" packages were direct dependencies for webpacker. By making these peer dependencies, you have control over the versions used in your webpack and babel configs.

Note for Sprockets usage

If you are still using Sprockets for some of your assets, you might want to include files from node_modules directory in your asset pipeline. This is useful, for example, if you want to reference a stylesheet from a node package in your .scss stylesheet.

In order to enable this, make sure you add node_modules to the asset load path by adding the following in an initializer (for example config/initializers/assets.rb)

Rails.application.config.assets.paths << Rails.root.join('node_modules')

Note for Yarn v2 usage

If you are using Yarn v2 (berry), please note that PnP modules are not supported.

In order to use Shakapacker with Yarn v2, make sure you set nodeLinker: node-modules in your .yarnrc.yml file as per the Yarn docs to opt out of Plug'n'Play behaviour.

Usage

View Helpers

Once installed, you can start writing modern ES6-flavored JavaScript apps right away:

app/javascript:
  # Only Webpack entry files here
  └── application.js
  └── application.css
  └── src:
  │   └── my_component.js
  └── stylesheets:
  │   └── my_styles.css
  └── images:
      └── logo.svg

You can then link the JavaScript pack in Rails views using the javascript_pack_tag helper. If you have styles imported in your pack file, you can link them by using stylesheet_pack_tag:

<%= javascript_pack_tag 'application' %>
<%= stylesheet_pack_tag 'application' %>

The javascript_pack_tag and stylesheet_pack_tag helpers will include all the transpiled packs with the chunks in your view, which creates html tags for all the chunks.

The result looks like this:

<%= javascript_pack_tag 'calendar', 'map', 'data-turbolinks-track': 'reload' %>

<script src="/packs/vendor-16838bab065ae1e314.js" data-turbolinks-track="reload" defer></script>
<script src="/packs/calendar~runtime-16838bab065ae1e314.js" data-turbolinks-track="reload" defer></script>
<script src="/packs/calendar-1016838bab065ae1e314.js" data-turbolinks-track="reload" defer"></script>
<script src="/packs/map~runtime-16838bab065ae1e314.js" data-turbolinks-track="reload" defer></script>
<script src="/packs/map-16838bab065ae1e314.js" data-turbolinks-track="reload" defer></script>

Important: Pass all your pack names as multiple arguments, not multiple calls, when using javascript_pack_tag and the stylesheet_pack_tag. Otherwise, you will get duplicated chunks on the page. Be especially careful if you might be calling these view helpers from your view, partials, and the layout for a page. You will need some logic to ensure you call the helpers only once with multiple arguments.

<%# DO %>
<%= javascript_pack_tag 'calendar', 'map' %>
<%= stylesheet_pack_tag 'calendar', 'map' %>

<%# DON'T %>
<%= javascript_pack_tag 'calendar' %>
<%= javascript_pack_tag 'map' %>
<%= stylesheet_pack_tag 'calendar' %>
<%= stylesheet_pack_tag 'map' %>

However, you may use multiple calls to stylesheet_pack_tag if, say, you require multiple