Shakapacker
Official, actively maintained successor to rails/webpacker. Internal naming for shakapacker
will continue to use webpacker
where possible for v6. ShakaCode stands behind the long-term maintainence and development of this project for the Rails community.
- See V6 Upgrade for upgrading from v5 or prior v6 releases.
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:
ShakaCode offers support for upgrading from webpacker or using Shakapacker. If interested, contact justin@shakacode.com. ShakaCode is hiring passionate engineers that love open source.
- Prerequisites
- Features
- Installation
- Usage
- View Helpers
- Defer for
javascript_pack_tag
- Server-Side Rendering (SSR)
- Development
- Webpack Configuration
- Babel configuration
- SWC configuration
- esbuild loader configuration
- Integrations
- React
- Typescript
- CoffeeScript
- TypeScript
- CSS
- Postcss
- Sass
- Less
- Stylus
- Other frameworks
- Custom Rails environments
- Upgrading
- Paths
- Additional paths
- Deployment
- Example Apps
- Troubleshooting
- Contributing
- License
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