# Shakapacker _Official, actively maintained successor to [rails/webpacker](https://github.com/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](./docs/v6_upgrade.md) for upgrading from v5 or prior v6 releases. [![Ruby specs](https://github.com/shakacode/shakapacker/workflows/Ruby%20specs/badge.svg)](https://github.com/shakacode/shakapacker/actions) [![Jest specs](https://github.com/shakacode/shakapacker/workflows/Jest%20specs/badge.svg)](https://github.com/shakacode/shakapacker/actions) [![Rubocop](https://github.com/shakacode/shakapacker/workflows/Rubocop/badge.svg)](https://github.com/shakacode/shakapacker/actions) [![JS lint](https://github.com/shakacode/shakapacker/workflows/JS%20lint/badge.svg)](https://github.com/shakacode/shakapacker/actions) [![node.js](https://img.shields.io/badge/node-%3E%3D%2012.0.0-brightgreen.svg)](https://www.npmjs.com/package/shakapacker) [![Gem](https://img.shields.io/gem/v/shakapacker.svg)](https://rubygems.org/gems/shakapacker) [![npm version](https://badge.fury.io/js/shakapacker.svg)](https://badge.fury.io/js/shakapacker) Webpacker makes it easy to use the JavaScript pre-processor and bundler [Webpack v5+](https://webpack.js.org/) 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](https://swc.rs/) and [esbuild-loader](https://github.com/privatenumber/esbuild-loader) support! They are faster than Babel! See a comparison of [webpacker with jsbundling-rails](https://github.com/rails/jsbundling-rails/blob/main/docs/comparison_with_webpacker.md). Discussion forum and Slack to discuss debugging and troubleshooting tips. Please open issues for bugs and feature requests: 1. [Discussions tab](https://github.com/shakacode/shakapacker/discussions) 2. [Slack discussion channel](https://reactrails.slack.com/join/shared_invite/enQtNjY3NTczMjczNzYxLTlmYjdiZmY3MTVlMzU2YWE0OWM0MzNiZDI0MzdkZGFiZTFkYTFkOGVjODBmOWEyYWQ3MzA2NGE1YWJjNmVlMGE) --- - [Prerequisites](#prerequisites) - [Features](#features) - [Optional support](#optional-support) - [Installation](#installation) - [Rails v6+](#rails-v6) - [Note for Sprockets usage](#note-for-sprockets-usage) - [Note for Yarn v2 usage](#note-for-yarn-v2-usage) - [Usage](#usage) - [View Helpers](#view-helpers) - [Defer for `javascript_pack_tag`](#defer-for-javascript_pack_tag) - [Server-Side Rendering (SSR)](#server-side-rendering-ssr) - [Development](#development) - [Webpack Configuration](#webpack-configuration) - [Babel configuration](#babel-configuration) - [SWC configuration](#swc-configuration) - [esbuild loader configuration](#esbuild-loader-configuration) - [Integrations](#integrations) - [React](#react) - [Typescript](#typescript) - [CoffeeScript](#coffeescript) - [TypeScript](#typescript) - [CSS](#css) - [Postcss](#postcss) - [Sass](#sass) - [Less](#less) - [Stylus](#stylus) - [Other frameworks](#other-frameworks) - [Custom Rails environments](#custom-rails-environments) - [Upgrading](#upgrading) - [Paths](#paths) - [Additional paths](#additional-paths) - [Deployment](#deployment) - [Example Apps](#example-apps) - [Troubleshooting](#troubleshooting) - [Contributing](#contributing) - [License](#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+](https://webpack.js.org/) - ES6 with [babel](https://babeljs.io/), [SWC](https://swc.rs/), or [Esbuild](https://github.com/privatenumber/esbuild-loader) - 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. ```bash 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`: ```bash bundle add shakapacker --strict ``` Then running the following to install Webpacker: ```bash ./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: ```bash yarn ``` Note, in v6, most JS packages are peer dependencies. Thus, the installer will add the packages: ```bash 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`) ```ruby 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](https://yarnpkg.com/getting-started/migration#step-by-step) to opt out of Plug'n'Play behaviour. ## Usage ### View Helpers Once installed, you can start writing modern ES6-flavored JavaScript apps right away: ```yml 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`: ```erb <%= 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: ```erb <%= javascript_pack_tag 'calendar', 'map', 'data-turbolinks-track': 'reload' %> ``` **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. ```erb <%# 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