README.md in shakapacker-7.3.0.beta.1 vs README.md in shakapacker-8.0.1
- old
+ new
@@ -1,10 +1,11 @@
-# Shakapacker (v7)
+# Shakapacker (v8)
_Official, actively maintained successor to [rails/webpacker](https://github.com/rails/webpacker).ShakaCode stands behind the long-term maintenance and development of this project for the Rails community._
* ⚠️ See the [6-stable](https://github.com/shakacode/shakapacker/tree/6-stable) branch for Shakapacker v6.x code and documentation. :warning:
+* See [V8 Upgrade](./docs/v8_upgrade.md) for upgrading from the v7 release.
* See [V7 Upgrade](./docs/v7_upgrade.md) for upgrading from the v6 release.
* 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)
@@ -24,24 +25,30 @@
See a comparison of [Shakapacker with jsbundling-rails](https://github.com/rails/jsbundling-rails/blob/main/docs/comparison_with_webpacker.md). For an in-depth discussion of choosing between `shakapacker` and `jsbundling-rails`, see the discussion [Webpacker alternatives - which path should we go to? #8783](https://github.com/decidim/decidim/discussions/8783) and the resulting PR [Switch away from Webpacker to Shakapacker #10389](https://github.com/decidim/decidim/pull/10389).
For discussions, see our [Slack Channel](https://reactrails.slack.com/join/shared_invite/enQtNjY3NTczMjczNzYxLTlmYjdiZmY3MTVlMzU2YWE0OWM0MzNiZDI0MzdkZGFiZTFkYTFkOGVjODBmOWEyYWQ3MzA2NGE1YWJjNmVlMGE).
---
-### ShakaCode Support
+## ShakaCode Support
-[ShakaCode](https://www.shakacode.com) offers support for upgrading from Webpacker and using Shakapacker. If interested, contact Justin Gordon, [justin@shakacode.com](mailto:justin@shakacode.com). We're also [hiring](https://jobs.lever.co/shakacode/3bdbfdb3-4495-4611-a279-01dddb351abe)!
+[ShakaCode](https://www.shakacode.com) focuses on helping Ruby on Rails teams use React and Webpack better. We can upgrade your project and improve your development and customer experiences, allowing you to focus on building new features or fixing bugs instead.
-Here's a testimonial of how ShakaCode can help, from [Florian Gößler](https://github.com/FGoessler) of [Blinkist](https://www.blinkist.com/), January 2, 2023:
+For an overview of working with us, see our [Client Engagement Model](https://www.shakacode.com/blog/client-engagement-model/) article and [how we bill for time](https://www.shakacode.com/blog/shortcut-jira-trello-github-toggl-time-and-task-tracking/).
+
+We also specialize in helping development teams lower infrastructure and CI costs. Check out our project [Control Plane Flow](https://github.com/shakacode/control-plane-flow/), which can allow you to get the ease of Heroku with the power of Kubernetes and big cost savings.
+
+If you think ShakaCode can help your project, [click here](https://meetings.hubspot.com/justingordon/30-minute-consultation) to book a call with [Justin Gordon](mailto:justin@shakacode.com), the creator of React on Rails and Shakapacker.
+
+Here's a testimonial of how ShakaCode can help from [Florian Gößler](https://github.com/FGoessler) of [Blinkist](https://www.blinkist.com/), January 2, 2023:
> Hey Justin 👋
>
> I just wanted to let you know that we today shipped the webpacker to shakapacker upgrades and it all seems to be running smoothly! Thanks again for all your support and your teams work! 😍
>
> On top of your work, it was now also very easy for me to upgrade Tailwind and include our external node_module based web component library which we were using for our other (more modern) apps already. That work is going to be shipped later this week though as we are polishing the last bits of it. 😉
>
> Have a great 2023 and maybe we get to work together again later in the year! 🙌
-Read the [full review here](https://clutch.co/profile/shakacode#reviews?sort_by=date_DESC#review-2118154). Here's [another review of a Shakapacker migration that led to more work](https://clutch.co/profile/shakacode#reviews?sort_by=date_DESC#review-2096078).
+Read the [full review here](https://clutch.co/profile/shakacode#reviews?sort_by=date_DESC#review-2118154).
---
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
@@ -49,12 +56,10 @@
- [Prerequisites](#prerequisites)
- [Features](#features)
- [Optional support](#optional-support)
- [Installation](#installation)
- [Rails v6+](#rails-v6)
- - [Using alternative package managers](#using-alternative-package-managers)
- - [Note for Yarn v2 usage](#note-for-yarn-v2-usage)
- [Concepts](#concepts)
- [Usage](#usage)
- [Configuration and Code](#configuration-and-code)
- [View Helpers](#view-helpers)
- [View Helpers `javascript_pack_tag` and `stylesheet_pack_tag`](#view-helpers-javascript_pack_tag-and-stylesheet_pack_tag)
@@ -96,20 +101,20 @@
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
## Prerequisites
-- Ruby 2.6+
+- Ruby 2.7+
- Rails 5.2+
-- Node.js 12.13.0+ || 14+
-- Yarn
+- Node.js 14+
## 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 creates a manifest.
- HMR with the `shakapacker-dev-server`, such as for hot-reloading React!
- Automatic code splitting using multiple entry points to optimize JavaScript downloads.
+- Support for [NPM](https://www.npmjs.com/package/npm), Yarn ([classic](https://classic.yarnpkg.com/lang/en/) and [berry](https://yarnpkg.com/getting-started)), [PNPM](https://pnpm.io/), and [Bun](https://bun.sh/)
- [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.
@@ -145,45 +150,52 @@
./bin/rails shakapacker:install
```
Before initiating the installation process, ensure you have committed all the changes. While installing Shakapacker, there might be some conflict between the existing file content and what Shakapacker tries to copy. You can either approve all the prompts for overriding these files or use the `FORCE=true` environment variable before the installation command to force the override without any prompt.
-When `package.json` and/or `yarn.lock` changes, such as when pulling down changes to your local environment in team settings, be sure to keep your NPM packages up-to-date:
+Shakapacker uses the [`package_json`](https://github.com/shakacode/package_json) gem to handle updating the `package.json` and interacting with the underlying package manager of choice for managing dependencies and running commands; the package manager is managed using the [`packageManager`](https://nodejs.org/api/packages.html#packagemanager) property in the `package.json`, otherwise falling back to the value of `PACKAGE_JSON_FALLBACK_MANAGER` if set or otherwise `npm`.
-```bash
-yarn
-```
+If `packageManager` is not set when running `shakapacker:install`, Shakapacker will set it based on the lockfile and the result of calling `--version` on the inferred manager; if no lockfile is present, then `npm` be used unless you choose to explicitly set the `PACKAGE_JSON_FALLBACK_MANAGER` to your preferred package manager.
-Note, in v6+, most JS packages are peer dependencies. Thus, the installer will add the packages:
+> [!NOTE]
+>
+> The `packageManager` property is only used to determine the package manager to use, based primarily on its name.
+> The version (if present) is only used to determine if Yarn Classic or Yarn Berry should be used, but is otherwise
+> _not_ checked, nor is [`corepack`](https://nodejs.org/api/corepack.html) used to ensure that the package manager is installed.
+>
+> It is up to the developer to ensure that the desired package manager is actually install at the right version, which can be done
+> using `corepack` or by other means.
-```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 `shakapacker`. By
-making these peer dependencies, you have control over the versions used in your webpack and babel configs.
-
-### Using alternative package managers
-
-There is experimental support for using package managers besides Yarn classic for managing JavaScript dependencies using the [`package_json`](https://github.com/G-Rath/package_json) gem.
-
-This can be enabled by setting the environment variable `SHAKAPACKER_USE_PACKAGE_JSON_GEM` to `true`; Shakapacker will then use the `package_json` gem which in turn will look for the [`packageManager`](https://nodejs.org/api/packages.html#packagemanager) property in the `package.json` or otherwise the `PACKAGE_JSON_FALLBACK_MANAGER` environment variable to determine which manager to use, defaulting to `npm` if neither are found.
-
See [here](https://github.com/G-Rath/package_json#specifying-a-package-manager) for a list of the supported package managers and more information; note that `package_json` does not handle ensuring the manager is installed.
-> **Note**
->
-> The rest of the documentation assumes that `package_json` is not being used, and so always references `yarn` - you should instead use the package manager of your choice for these commands.
+If you wish to use [Yarn PnP](https://yarnpkg.com/features/pnp) you will need to configure Babel using a `babel.config.js` file rather than via `package.json` - see [customizing Babel Config](./docs/customizing_babel_config.md) for examples on how to do this.
-### Note for Yarn v2 usage
+> [!NOTE]
+>
+> The rest of the documentation will only reference `npm` when providing commands such as to install optional packages except in cases where
+> a particular package manager requires a very different command; otherwise it should be safe to just replace `npm` with the name of your
+> preferred package manager when running the command
-If you are using Yarn v2 (berry), please note that PnP modules are not supported unless you're using `SHAKAPACKER_USE_PACKAGE_JSON_GEM`.
+Note, in v6+, most JS packages are peer dependencies. Thus, the installer will add the packages:
-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 behavior.
+- `@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 `shakapacker`. By
+making these peer dependencies, you have control over the versions used in your webpack and babel configs.
+
## Concepts
At its core, Shakapacker's essential function is to:
1. Provide configuration by a single file used by both Rails view helpers and JavaScript webpack compilation code.
@@ -432,20 +444,17 @@
In production or CI environments, the `digest` strategy is more suitable, unless you are using incremental builds or caching and can guarantee that the timestamps will not change after e.g. cache restore. However, many production or CI environments will explicitly compile assets, so `compile: false` is more appropriate. Otherwise, you'll waste time either checking file timestamps or computing digests.
You can control what strategy is used by the `compiler_strategy` option in `shakapacker.yml` config file. By default `mtime` strategy is used in development environment, `digest` is used elsewhere.
-**Note:**
-If you are not using the `shakapacker-dev-server`,
-your packs will be served by the Rails public file server.
-If you've enabled caching
-(Rails application `config.action_controller.perform_caching` setting),
-your changes will likely not be picked up due to `Cache-Control` header being set
-and
-assets being cached in the browser memory.
-For more details see
-[issue 88: Caching issues in Development since migrating to Shakapacker](https://github.com/shakacode/shakapacker/issues/88).
+> [!NOTE]
+>
+> If you are not using the `shakapacker-dev-server`, your packs will be served by the Rails public file server.
+> If you've enabled caching (Rails application `config.action_controller.perform_caching` setting),
+> your changes will likely not be picked up due to `Cache-Control` header being set and assets being cached in the browser memory.
+>
+> For more details see [issue 88: Caching issues in Development since migrating to Shakapacker](https://github.com/shakacode/shakapacker/issues/88).
If you want to use live code reloading, or you have enough JavaScript that on-demand compilation is too slow, you'll need to run `./bin/shakapacker-dev-server`. This process will watch for changes in the relevant files, defined by `shakapacker.yml` configuration settings for `source_path`, `source_entry_path`, and `additional_paths`, and it will then automatically reload the browser to match. This feature is also known as [Hot Module Replacement](https://webpack.js.org/concepts/hot-module-replacement/).
#### Common Development Commands
@@ -576,12 +585,15 @@
```
You may want to modify the rules in the default configuration. For instance, if you are using a custom svg loader, you may want to remove `.svg` from the default file loader rules. You can search and filter the default rules like so:
```js
-const svgRule = config.module.rules.find(rule => rule.test.test('.svg'));
-svgRule.test = svgRule.test.filter(t => !t.test('.svg'))
+const fileRule = config.module.rules.find(rule => rule.test.test('.svg'));
+// removing svg from asset file rule's test RegExp
+fileRule.test = /\.(bmp|gif|jpe?g|png|tiff|ico|avif|webp|eot|otf|ttf|woff|woff2)$/
+// changing the rule type from 'asset/resource' to 'asset'. See https://webpack.js.org/guides/asset-modules/
+fileRule.type = 'asset'
```
### Babel configuration
By default, you will find the Shakapacker preset in your `package.json`. Note, you need to use the new NPM package name, `shakapacker`.
@@ -619,17 +631,17 @@
See also [Customizing Babel Config](./docs/customizing_babel_config.md) for an example React configuration.
#### TypeScript
```bash
-yarn add typescript @babel/preset-typescript
+npm install typescript @babel/preset-typescript
```
Babel won’t perform any type-checking on TypeScript code. To optionally use type-checking run:
```bash
-yarn add fork-ts-checker-webpack-plugin
+npm install fork-ts-checker-webpack-plugin
```
Add tsconfig.json
```json
@@ -666,11 +678,11 @@
#### CSS
To enable CSS support in your application, add the following packages:
```bash
-yarn add css-loader style-loader mini-css-extract-plugin css-minimizer-webpack-plugin
+npm install css-loader style-loader mini-css-extract-plugin css-minimizer-webpack-plugin
```
Optionally, add the `CSS` extension to webpack config for easy resolution.
```js
@@ -690,40 +702,59 @@
then add the relevant pre-processors:
#### Postcss
```bash
-yarn add postcss postcss-loader
+npm install postcss postcss-loader
```
Optionally add these two plugins if they are required in your `postcss.config.js`:
```bash
-yarn add postcss-preset-env postcss-flexbugs-fixes
+npm install postcss-preset-env postcss-flexbugs-fixes
```
#### Sass
```bash
-yarn add sass sass-loader
+npm install sass-loader
```
+You will also need to install [Dart Sass](https://github.com/sass/dart-sass), [Node Sass](https://github.com/sass/node-sass) or [Sass Embedded](https://github.com/sass/embedded-host-node) to pick the implementation to use. sass-loader will automatically pick an implementation based on installed packages.
+
+Please refer to [sass-loader documentation](https://www.npmjs.com/package/sass-loader) and individual packages repos for more information on all the options.
+
+##### Dart Sass
+```bash
+npm install sass
+```
+
+##### Node Sass
+```bash
+npm install node-sass
+```
+
+##### Sass Embedded
+```bash
+npm install sass-embedded
+```
+
#### Less
```bash
-yarn add less less-loader
+npm install less less-loader
```
#### Stylus
```bash
-yarn add stylus stylus-loader
+npm install stylus stylus-loader
```
#### CoffeeScript
```bash
-yarn add coffeescript coffee-loader
+npm install coffeescript coffee-loader
```
#### Other frameworks
Please follow Webpack integration guide for the relevant framework or library,
@@ -819,20 +850,28 @@
bundle update shakapacker
# overwrite your changes to the default install files and revert any unwanted changes from the install
rails shakapacker:install
-# yarn 1 instructions
+# using npm
+npm install shakapacker@latest
+npm install webpack-dev-server@latest
+
+# using yarn classic
yarn upgrade shakapacker --latest
yarn upgrade webpack-dev-server --latest
-# yarn 2 instructions
+# using yarn berry
yarn up shakapacker@latest
yarn up webpack-dev-server@latest
+# using pnpm
+pnpm up shakapacker@latest
+pnpm up webpack-dev-server@latest
+
# Or to install the latest release (including pre-releases)
-yarn add shakapacker@next
+npm install shakapacker@next
```
Also, consult the [CHANGELOG](./CHANGELOG.md) for additional upgrade links.
### Paths
@@ -878,12 +917,14 @@
// Note it's relative to parent directory i.e. app/assets
import 'stylesheets/main'
import 'images/rails.png'
```
-Assets put in these folders will have their directory stripped just like with the `source_path`. For example:
+Assets put in these folders will also have their path stripped just like with the `source_path`.
+Example:
+
A file in `app/assets/images/image.svg` with `additional_paths: ['app/assets']` will result in `static/images/image.svg`
**Note:** Please be careful when adding paths here otherwise it will make the compilation slow, consider adding specific paths instead of the whole parent directory if you just need to reference one or two modules
**Also note:** While importing assets living outside your `source_path` defined in shakapacker.yml (like, for instance, assets under `app/assets`) from within your packs using _relative_ paths like `import '../../assets/javascripts/file.js'` will work in development, Shakapacker won't recompile the bundle in production unless a file that lives in one of it's watched paths has changed (check out `Shakapacker::MtimeStrategy#latest_modified_timestamp` or `Shakapacker::DigestStrategy#watched_files_digest` depending on strategy configured by `compiler_strategy` option in `shakapacker.yml`). That's why you'd need to add `app/assets` to the additional_paths as stated above and use `import 'javascripts/file.js'` instead.
@@ -893,12 +934,29 @@
Shakapacker hooks up a new `shakapacker:compile` task to `assets:precompile`, which gets run whenever you run `assets:precompile`. If you are not using Sprockets, `shakapacker:compile` is automatically aliased to `assets:precompile`. Similar to sprockets both rake tasks will compile packs in production mode but will use `RAILS_ENV` to load configuration from `config/shakapacker.yml` (if available).
This behavior is optional & can be disabled by either setting a `SHAKAPACKER_PRECOMPILE` environment variable to `false`, `no`, `n`, or `f`, or by setting a `shakapacker_precompile` key in your `shakapacker.yml` to `false`. ([source code](./lib/shakapacker/configuration.rb#L34))
-When compiling assets for production on a remote server, such as a continuous integration environment, it's recommended to use `yarn install --frozen-lockfile` to install NPM packages on the remote host to ensure that the installed packages match the `yarn.lock` file.
+When compiling assets for production on a remote server, such as a continuous integration environment, it's recommended to ensure the exact versions specified in your lockfile are installed:
+```
+# using npm
+npm ci
+
+# using yarn classic
+yarn install --frozen-lockfile
+
+# using yarn berry
+yarn install --immutable
+
+# using pnpm
+pnpm install --frozen-lockfile
+
+# using bun
+bun install --frozen-lockfile
+```
+
If you are using a CDN setup, Shakapacker does NOT use the `ASSET_HOST` environment variable to prefix URLs for assets during bundle compilation. You must use the `SHAKAPACKER_ASSET_HOST` environment variable instead (`WEBPACKER_ASSET_HOST` if you're using any version of Webpacker or Shakapacker before Shakapacker v7).
## Example Apps
* [React on Rails Tutorial With SSR, HMR fast refresh, and TypeScript](https://github.com/shakacode/react_on_rails_tutorial_with_ssr_and_hmr_fast_refresh)
@@ -930,10 +988,10 @@
<source media="(prefers-color-scheme: dark)" srcset="https://user-images.githubusercontent.com/4244251/184881147-0d077438-3978-40da-ace9-4f650d2efe2e.png">
<source media="(prefers-color-scheme: light)" srcset="https://user-images.githubusercontent.com/4244251/184881152-9f2d8fba-88ac-4ba6-873b-22387f8711c5.png">
<img alt="ScoutAPM" src="https://user-images.githubusercontent.com/4244251/184881152-9f2d8fba-88ac-4ba6-873b-22387f8711c5.png" height="120px">
</picture>
</a>
-<a href="https://controlplane.com">
+<a href="https://shakacode.controlplane.com">
<picture>
<img alt="Control Plane" src="https://github.com/shakacode/.github/assets/20628911/90babd87-62c4-4de3-baa4-3d78ef4bec25" height="120px">
</picture>
</a>
<br />