shakapacker 9.0.0.beta.0 → 9.0.0.beta.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.github/workflows/claude-code-review.yml +54 -0
- data/.github/workflows/claude.yml +50 -0
- data/.github/workflows/dummy.yml +3 -3
- data/.github/workflows/test-bundlers.yml +152 -0
- data/.rubocop.yml +1 -0
- data/CHANGELOG.md +15 -3
- data/CLAUDE.md +29 -0
- data/Gemfile.lock +1 -1
- data/README.md +42 -1
- data/Rakefile +39 -4
- data/TODO.md +51 -0
- data/TODO_v9.md +84 -0
- data/conductor-setup.sh +58 -0
- data/conductor.json +7 -0
- data/docs/cdn_setup.md +379 -0
- data/docs/css-modules-export-mode.md +216 -86
- data/docs/deployment.md +10 -1
- data/docs/rspack.md +7 -7
- data/docs/rspack_migration_guide.md +202 -0
- data/docs/using_esbuild_loader.md +3 -3
- data/docs/using_swc_loader.md +5 -3
- data/docs/v6_upgrade.md +10 -0
- data/docs/v9_upgrade.md +185 -0
- data/lib/install/bin/shakapacker +3 -17
- data/lib/install/config/shakapacker.yml +9 -4
- data/lib/shakapacker/configuration.rb +75 -3
- data/lib/shakapacker/dev_server_runner.rb +19 -9
- data/lib/shakapacker/manifest.rb +4 -3
- data/lib/shakapacker/rspack_runner.rb +4 -42
- data/lib/shakapacker/runner.rb +105 -11
- data/lib/shakapacker/utils/manager.rb +2 -0
- data/lib/shakapacker/version.rb +1 -1
- data/lib/shakapacker/version_checker.rb +1 -1
- data/lib/shakapacker/webpack_runner.rb +4 -42
- data/lib/tasks/shakapacker/install.rake +6 -2
- data/package/config.js +24 -0
- data/package/environments/base.js +12 -2
- data/package/environments/development.js +52 -12
- data/package/environments/production.js +8 -3
- data/package/environments/test.js +5 -3
- data/package/index.d.ts +69 -30
- data/package/index.js +1 -1
- data/package/optimization/rspack.js +9 -5
- data/package/plugins/rspack.js +12 -28
- data/package/rspack/index.js +57 -0
- data/package/rules/babel.js +2 -2
- data/package/rules/esbuild.js +2 -2
- data/package/rules/raw.js +5 -5
- data/package/rules/rspack.js +77 -7
- data/package/rules/swc.js +2 -2
- data/package/utils/debug.js +49 -0
- data/package/utils/getStyleRule.js +19 -10
- data/package/utils/requireOrError.js +1 -1
- data/package/utils/validateCssModulesConfig.js +91 -0
- data/package/utils/validateDependencies.js +61 -0
- data/package/webpackDevServerConfig.js +2 -0
- data/package-lock.json +11966 -0
- data/package.json +9 -2
- data/test/package/rules/esbuild.test.js +1 -1
- data/test/package/rules/swc.test.js +1 -1
- data/tools/README.md +124 -0
- data/tools/css-modules-v9-codemod.js +179 -0
- data/yarn.lock +199 -81
- metadata +20 -3
- data/lib/install/bin/shakapacker-rspack +0 -13
@@ -0,0 +1,202 @@
|
|
1
|
+
# Rspack Migration Guide for Shakapacker
|
2
|
+
|
3
|
+
## Overview
|
4
|
+
This guide documents the differences between webpack and Rspack configurations in Shakapacker, and provides migration guidance for users switching to Rspack.
|
5
|
+
|
6
|
+
## Key Differences from Webpack
|
7
|
+
|
8
|
+
### 1. Built-in Loaders
|
9
|
+
Rspack provides built-in loaders for better performance:
|
10
|
+
|
11
|
+
**JavaScript/TypeScript:**
|
12
|
+
- Use `builtin:swc-loader` instead of `babel-loader` or `ts-loader`
|
13
|
+
- 20x faster than Babel on single thread, 70x on multiple cores
|
14
|
+
- Configuration example:
|
15
|
+
```javascript
|
16
|
+
{
|
17
|
+
test: /\.(js|jsx|ts|tsx)$/,
|
18
|
+
loader: 'builtin:swc-loader',
|
19
|
+
options: {
|
20
|
+
jsc: {
|
21
|
+
parser: {
|
22
|
+
syntax: 'typescript', // or 'ecmascript'
|
23
|
+
tsx: true, // for TSX files
|
24
|
+
jsx: true // for JSX files
|
25
|
+
},
|
26
|
+
transform: {
|
27
|
+
react: {
|
28
|
+
runtime: 'automatic'
|
29
|
+
}
|
30
|
+
}
|
31
|
+
}
|
32
|
+
}
|
33
|
+
}
|
34
|
+
```
|
35
|
+
|
36
|
+
### 2. Plugin Replacements
|
37
|
+
|
38
|
+
#### Built-in Rspack Alternatives
|
39
|
+
| Webpack Plugin | Rspack Alternative | Status |
|
40
|
+
|---------------|-------------------|---------|
|
41
|
+
| `copy-webpack-plugin` | `rspack.CopyRspackPlugin` | ✅ Built-in |
|
42
|
+
| `mini-css-extract-plugin` | `rspack.CssExtractRspackPlugin` | ✅ Built-in |
|
43
|
+
| `terser-webpack-plugin` | `rspack.SwcJsMinimizerRspackPlugin` | ✅ Built-in |
|
44
|
+
| `css-minimizer-webpack-plugin` | `rspack.LightningCssMinimizerRspackPlugin` | ✅ Built-in |
|
45
|
+
|
46
|
+
#### Community Alternatives
|
47
|
+
| Webpack Plugin | Rspack Alternative | Package |
|
48
|
+
|---------------|-------------------|----------|
|
49
|
+
| `fork-ts-checker-webpack-plugin` | `ts-checker-rspack-plugin` | `npm i -D ts-checker-rspack-plugin` |
|
50
|
+
| `@pmmmwh/react-refresh-webpack-plugin` | `@rspack/plugin-react-refresh` | `npm i -D @rspack/plugin-react-refresh` |
|
51
|
+
| `eslint-webpack-plugin` | `eslint-rspack-plugin` | `npm i -D eslint-rspack-plugin` |
|
52
|
+
|
53
|
+
#### Incompatible Plugins
|
54
|
+
The following webpack plugins are NOT compatible with Rspack:
|
55
|
+
- `webpack.optimize.LimitChunkCountPlugin` - Use `optimization.splitChunks` configuration instead
|
56
|
+
- `webpack-manifest-plugin` - Use `rspack-manifest-plugin` instead
|
57
|
+
- Git revision plugins - Use alternative approaches
|
58
|
+
|
59
|
+
### 3. Asset Module Types
|
60
|
+
Replace file loaders with asset modules:
|
61
|
+
- `file-loader` → `type: 'asset/resource'`
|
62
|
+
- `url-loader` → `type: 'asset/inline'`
|
63
|
+
- `raw-loader` → `type: 'asset/source'`
|
64
|
+
|
65
|
+
### 4. Configuration Differences
|
66
|
+
|
67
|
+
#### TypeScript Configuration
|
68
|
+
**Required:** Add `isolatedModules: true` to your `tsconfig.json`:
|
69
|
+
```json
|
70
|
+
{
|
71
|
+
"compilerOptions": {
|
72
|
+
"isolatedModules": true
|
73
|
+
}
|
74
|
+
}
|
75
|
+
```
|
76
|
+
|
77
|
+
#### React Fast Refresh
|
78
|
+
```javascript
|
79
|
+
// Development configuration
|
80
|
+
const ReactRefreshPlugin = require('@rspack/plugin-react-refresh');
|
81
|
+
|
82
|
+
module.exports = {
|
83
|
+
plugins: [
|
84
|
+
new ReactRefreshPlugin(),
|
85
|
+
new rspack.HotModuleReplacementPlugin()
|
86
|
+
]
|
87
|
+
};
|
88
|
+
```
|
89
|
+
|
90
|
+
### 5. Optimization Differences
|
91
|
+
|
92
|
+
#### Code Splitting
|
93
|
+
Rspack's `splitChunks` configuration is similar to webpack but with some differences:
|
94
|
+
```javascript
|
95
|
+
optimization: {
|
96
|
+
splitChunks: {
|
97
|
+
chunks: 'all',
|
98
|
+
cacheGroups: {
|
99
|
+
vendor: {
|
100
|
+
test: /[\\/]node_modules[\\/]/,
|
101
|
+
priority: -10,
|
102
|
+
reuseExistingChunk: true
|
103
|
+
}
|
104
|
+
}
|
105
|
+
}
|
106
|
+
}
|
107
|
+
```
|
108
|
+
|
109
|
+
#### Minimization
|
110
|
+
```javascript
|
111
|
+
optimization: {
|
112
|
+
minimize: true,
|
113
|
+
minimizer: [
|
114
|
+
new rspack.SwcJsMinimizerRspackPlugin(),
|
115
|
+
new rspack.LightningCssMinimizerRspackPlugin()
|
116
|
+
]
|
117
|
+
}
|
118
|
+
```
|
119
|
+
|
120
|
+
### 6. Development Server
|
121
|
+
Rspack uses its own dev server with some configuration differences:
|
122
|
+
```javascript
|
123
|
+
devServer: {
|
124
|
+
// Rspack-specific: Force writing assets to disk
|
125
|
+
devMiddleware: {
|
126
|
+
writeToDisk: true
|
127
|
+
}
|
128
|
+
}
|
129
|
+
```
|
130
|
+
|
131
|
+
## Migration Checklist
|
132
|
+
|
133
|
+
### Step 1: Update Dependencies
|
134
|
+
```bash
|
135
|
+
# Remove webpack dependencies
|
136
|
+
npm uninstall webpack webpack-cli webpack-dev-server
|
137
|
+
|
138
|
+
# Install Rspack
|
139
|
+
npm install --save-dev @rspack/core @rspack/cli
|
140
|
+
```
|
141
|
+
|
142
|
+
### Step 2: Update Configuration Files
|
143
|
+
1. Create `config/rspack/rspack.config.js` based on your webpack config
|
144
|
+
2. Update `config/shakapacker.yml`:
|
145
|
+
```yaml
|
146
|
+
assets_bundler: 'rspack'
|
147
|
+
```
|
148
|
+
|
149
|
+
### Step 3: Replace Loaders
|
150
|
+
- Replace `babel-loader` with `builtin:swc-loader`
|
151
|
+
- Remove `file-loader`, `url-loader`, `raw-loader` - use asset modules
|
152
|
+
- Update CSS loaders to use Rspack's built-in support
|
153
|
+
|
154
|
+
### Step 4: Update Plugins
|
155
|
+
- Replace plugins with Rspack alternatives (see table above)
|
156
|
+
- Remove incompatible plugins
|
157
|
+
- Add Rspack-specific plugins as needed
|
158
|
+
|
159
|
+
### Step 5: TypeScript Setup
|
160
|
+
1. Add `isolatedModules: true` to `tsconfig.json`
|
161
|
+
2. Optional: Add `ts-checker-rspack-plugin` for type checking
|
162
|
+
|
163
|
+
### Step 6: Test Your Build
|
164
|
+
```bash
|
165
|
+
# Development build
|
166
|
+
bin/shakapacker
|
167
|
+
|
168
|
+
# Production build
|
169
|
+
bin/shakapacker --mode production
|
170
|
+
```
|
171
|
+
|
172
|
+
## Common Issues and Solutions
|
173
|
+
|
174
|
+
### Issue: LimitChunkCountPlugin Error
|
175
|
+
**Error:** `Cannot read properties of undefined (reading 'tap')`
|
176
|
+
**Solution:** Remove `webpack.optimize.LimitChunkCountPlugin` and use `splitChunks` configuration instead.
|
177
|
+
|
178
|
+
### Issue: Missing Loaders
|
179
|
+
**Error:** Module parse errors
|
180
|
+
**Solution:** Check console logs for skipped loaders and install missing dependencies.
|
181
|
+
|
182
|
+
### Issue: CSS Extraction
|
183
|
+
**Error:** CSS not being extracted properly
|
184
|
+
**Solution:** Use `rspack.CssExtractRspackPlugin` instead of `mini-css-extract-plugin`.
|
185
|
+
|
186
|
+
### Issue: TypeScript Errors
|
187
|
+
**Error:** TypeScript compilation errors
|
188
|
+
**Solution:** Ensure `isolatedModules: true` is set in `tsconfig.json`.
|
189
|
+
|
190
|
+
## Performance Tips
|
191
|
+
|
192
|
+
1. **Use Built-in Loaders:** Always prefer Rspack's built-in loaders for better performance
|
193
|
+
2. **Minimize Plugins:** Use only necessary plugins as each adds overhead
|
194
|
+
3. **Enable Caching:** Rspack has built-in persistent caching
|
195
|
+
4. **Use SWC:** The built-in SWC loader is significantly faster than Babel
|
196
|
+
|
197
|
+
## Resources
|
198
|
+
|
199
|
+
- [Rspack Documentation](https://rspack.rs)
|
200
|
+
- [Rspack Examples](https://github.com/rspack-contrib/rspack-examples)
|
201
|
+
- [Awesome Rspack](https://github.com/rspack-contrib/awesome-rspack)
|
202
|
+
- [Migration Guide](https://rspack.rs/guide/migration/webpack)
|
@@ -27,7 +27,7 @@ To use esbuild as your transpiler today. You need to do two things:
|
|
27
27
|
npm install esbuild esbuild-loader
|
28
28
|
```
|
29
29
|
|
30
|
-
2. Add or change `
|
30
|
+
2. Add or change `javascript_transpiler` value in your default `shakapacker.yml` config to `esbuild`
|
31
31
|
The default configuration of babel is done by using `package.json` to use the file within the `shakapacker` package.
|
32
32
|
|
33
33
|
```yml
|
@@ -46,8 +46,8 @@ default: &default
|
|
46
46
|
# Reload manifest.json on all requests so we reload latest compiled packs
|
47
47
|
cache_manifest: false
|
48
48
|
|
49
|
-
# Select
|
50
|
-
|
49
|
+
# Select JavaScript transpiler to use, available options are 'babel' (default), 'swc' or 'esbuild'
|
50
|
+
javascript_transpiler: 'esbuild'
|
51
51
|
```
|
52
52
|
|
53
53
|
### (Optional) Replace minification with esbuild
|
data/docs/using_swc_loader.md
CHANGED
@@ -12,6 +12,8 @@ It supports all ECMAScript features and it's designed to be a drop-in replacemen
|
|
12
12
|
|
13
13
|
For comparison between SWC and Babel, see the docs at https://swc.rs/docs/migrating-from-babel.
|
14
14
|
|
15
|
+
> **Note:** SWC is also natively built into RSpack bundler, providing even faster compilation speeds. When using RSpack (`assets_bundler: 'rspack'`), SWC is used automatically regardless of the `javascript_transpiler` setting.
|
16
|
+
|
15
17
|
## Switching your Shakapacker project to SWC
|
16
18
|
|
17
19
|
In order to use SWC as your compiler today. You need to do two things:
|
@@ -22,7 +24,7 @@ In order to use SWC as your compiler today. You need to do two things:
|
|
22
24
|
npm install @swc/core swc-loader
|
23
25
|
```
|
24
26
|
|
25
|
-
2. Add or change `
|
27
|
+
2. Add or change `javascript_transpiler` value in your default `shakapacker.yml` config to `swc`
|
26
28
|
The default configuration of babel is done by using `package.json` to use the file within the `shakapacker` package.
|
27
29
|
|
28
30
|
```yml
|
@@ -41,8 +43,8 @@ default: &default
|
|
41
43
|
# Reload manifest.json on all requests so we reload latest compiled packs
|
42
44
|
cache_manifest: false
|
43
45
|
|
44
|
-
# Select
|
45
|
-
|
46
|
+
# Select JavaScript transpiler to use, available options are 'babel' (default) or 'swc'
|
47
|
+
javascript_transpiler: 'swc'
|
46
48
|
```
|
47
49
|
|
48
50
|
## Usage
|
data/docs/v6_upgrade.md
CHANGED
@@ -101,6 +101,16 @@ _If you're on webpacker v5, follow [how to upgrade to webpacker v6.0.0.rc.6 from
|
|
101
101
|
|
102
102
|
1. Update `webpack-dev-server` to the current version, greater than 4.2, updating `package.json`.
|
103
103
|
|
104
|
+
**Important:** If you encounter the error `[webpack-cli] Invalid options object. Dev Server has been initialized using an options object that does not match the API schema` with an unknown property `_assetEmittingPreviousFiles`, this indicates your webpack-dev-server configuration contains deprecated options.
|
105
|
+
|
106
|
+
To resolve this issue:
|
107
|
+
- Ensure you're using webpack-cli >= 4.7.0 with webpack-dev-server 5.x (webpack-cli 4.7+ is compatible with webpack-dev-server v5)
|
108
|
+
- Check your current versions: `npm list webpack-cli webpack-dev-server`
|
109
|
+
- Remove any legacy options like `_assetEmittingPreviousFiles` from your dev-server configuration
|
110
|
+
- Review the [webpack-dev-server migration guide](https://github.com/webpack/webpack-dev-server/blob/master/migration-v5.md) for proper v4 to v5 migration steps
|
111
|
+
|
112
|
+
See [issue #526](https://github.com/shakacode/shakapacker/issues/526) for more details.
|
113
|
+
|
104
114
|
1. Update API usage of the view helpers by changing `javascript_packs_with_chunks_tag` and `stylesheet_packs_with_chunks_tag` to `javascript_pack_tag` and `stylesheet_pack_tag`. Ensure that your layouts and views will only have **at most one call** to `javascript_pack_tag` and **at most one call** to `stylesheet_pack_tag`. You can now pass multiple bundles to these view helper methods. If you fail to changes this, you may experience performance issues, and other bugs related to multiple copies of React, like [issue 2932](https://github.com/rails/webpacker/issues/2932). If you expose jquery globally with `expose-loader` by using `import $ from "expose-loader?exposes=$,jQuery!jquery"` in your `app/javascript/application.js`, pass the option `defer: false` to your `javascript_pack_tag`.
|
105
115
|
|
106
116
|
1. If you are using any integrations like `css`, `postcss`, `React` or `TypeScript`. Please see https://github.com/shakacode/shakapacker#integrations section on how they work in v6.
|
data/docs/v9_upgrade.md
ADDED
@@ -0,0 +1,185 @@
|
|
1
|
+
# Shakapacker v9 Upgrade Guide
|
2
|
+
|
3
|
+
This guide outlines breaking changes and migration steps for upgrading from Shakapacker v8 to v9.
|
4
|
+
|
5
|
+
## Breaking Changes
|
6
|
+
|
7
|
+
### 1. CSS Modules Configuration Changed to Named Exports
|
8
|
+
|
9
|
+
**What changed:** CSS Modules are now configured with `namedExport: true` and `exportLocalsConvention: 'camelCase'` by default, aligning with Next.js and modern tooling standards.
|
10
|
+
|
11
|
+
**JavaScript Projects:**
|
12
|
+
```js
|
13
|
+
// Before (v8)
|
14
|
+
import styles from './Component.module.css';
|
15
|
+
<button className={styles.button} />
|
16
|
+
|
17
|
+
// After (v9)
|
18
|
+
import { button } from './Component.module.css';
|
19
|
+
<button className={button} />
|
20
|
+
```
|
21
|
+
|
22
|
+
**TypeScript Projects:**
|
23
|
+
```typescript
|
24
|
+
// Before (v8)
|
25
|
+
import styles from './Component.module.css';
|
26
|
+
<button className={styles.button} />
|
27
|
+
|
28
|
+
// After (v9) - namespace import due to TypeScript limitations
|
29
|
+
import * as styles from './Component.module.css';
|
30
|
+
<button className={styles.button} />
|
31
|
+
```
|
32
|
+
|
33
|
+
**Migration Options:**
|
34
|
+
|
35
|
+
1. **Update your code** (Recommended):
|
36
|
+
- JavaScript: Change to named imports (`import { className }`)
|
37
|
+
- TypeScript: Change to namespace imports (`import * as styles`)
|
38
|
+
- Kebab-case class names are automatically converted to camelCase
|
39
|
+
|
40
|
+
2. **Keep v8 behavior** temporarily:
|
41
|
+
- Override the css-loader configuration as shown in [CSS Modules Export Mode documentation](./css-modules-export-mode.md)
|
42
|
+
- This gives you time to migrate gradually
|
43
|
+
|
44
|
+
**Benefits of the change:**
|
45
|
+
- Eliminates webpack/TypeScript warnings
|
46
|
+
- Better tree-shaking of unused CSS classes
|
47
|
+
- More explicit about which classes are used
|
48
|
+
- Aligns with modern JavaScript standards
|
49
|
+
|
50
|
+
### 2. Configuration Option Renamed: `webpack_loader` → `javascript_transpiler`
|
51
|
+
|
52
|
+
**What changed:** The configuration option has been renamed to better reflect its purpose.
|
53
|
+
|
54
|
+
**Before (v8):**
|
55
|
+
```yml
|
56
|
+
# config/shakapacker.yml
|
57
|
+
webpack_loader: 'babel'
|
58
|
+
```
|
59
|
+
|
60
|
+
**After (v9):**
|
61
|
+
```yml
|
62
|
+
# config/shakapacker.yml
|
63
|
+
javascript_transpiler: 'babel'
|
64
|
+
```
|
65
|
+
|
66
|
+
**Note:** The old `webpack_loader` option is deprecated but still supported with a warning.
|
67
|
+
|
68
|
+
### 3. Rspack Support Added
|
69
|
+
|
70
|
+
**New feature:** Shakapacker v9 adds support for Rspack as an alternative bundler to webpack.
|
71
|
+
|
72
|
+
```yml
|
73
|
+
# config/shakapacker.yml
|
74
|
+
assets_bundler: 'rspack' # or 'webpack' (default)
|
75
|
+
```
|
76
|
+
|
77
|
+
## Migration Steps
|
78
|
+
|
79
|
+
### Step 1: Update Dependencies
|
80
|
+
|
81
|
+
```bash
|
82
|
+
npm update shakapacker@^9.0.0
|
83
|
+
# or
|
84
|
+
yarn upgrade shakapacker@^9.0.0
|
85
|
+
```
|
86
|
+
|
87
|
+
### Step 2: Update CSS Module Imports
|
88
|
+
|
89
|
+
#### For each CSS module import:
|
90
|
+
|
91
|
+
```js
|
92
|
+
// Find imports like this:
|
93
|
+
import styles from './styles.module.css';
|
94
|
+
|
95
|
+
// Replace with named imports:
|
96
|
+
import { className1, className2 } from './styles.module.css';
|
97
|
+
```
|
98
|
+
|
99
|
+
#### Update TypeScript definitions:
|
100
|
+
|
101
|
+
```typescript
|
102
|
+
// Update your CSS module type definitions
|
103
|
+
declare module '*.module.css' {
|
104
|
+
// With namedExport: true, css-loader generates individual named exports
|
105
|
+
// TypeScript can't know the exact names at compile time, so we declare
|
106
|
+
// a module with any number of string exports
|
107
|
+
const classes: { readonly [key: string]: string };
|
108
|
+
export = classes;
|
109
|
+
// Note: This allows 'import * as styles' but not 'import styles from'
|
110
|
+
// because css-loader with namedExport: true doesn't generate a default export
|
111
|
+
}
|
112
|
+
```
|
113
|
+
|
114
|
+
### Step 3: Handle Kebab-Case Class Names
|
115
|
+
|
116
|
+
v9 automatically converts kebab-case to camelCase:
|
117
|
+
|
118
|
+
```css
|
119
|
+
/* styles.module.css */
|
120
|
+
.my-button { }
|
121
|
+
.primary-color { }
|
122
|
+
```
|
123
|
+
|
124
|
+
```js
|
125
|
+
// v9 imports
|
126
|
+
import { myButton, primaryColor } from './styles.module.css';
|
127
|
+
```
|
128
|
+
|
129
|
+
### Step 4: Update Configuration Files
|
130
|
+
|
131
|
+
If you have `webpack_loader` in your configuration:
|
132
|
+
|
133
|
+
```yml
|
134
|
+
# config/shakapacker.yml
|
135
|
+
# OLD:
|
136
|
+
# webpack_loader: 'babel'
|
137
|
+
|
138
|
+
# NEW:
|
139
|
+
javascript_transpiler: 'babel'
|
140
|
+
```
|
141
|
+
|
142
|
+
### Step 5: Run Tests
|
143
|
+
|
144
|
+
```bash
|
145
|
+
# Run your test suite
|
146
|
+
npm test
|
147
|
+
|
148
|
+
# Build your application
|
149
|
+
bin/shakapacker
|
150
|
+
|
151
|
+
# Test in development
|
152
|
+
bin/shakapacker-dev-server
|
153
|
+
```
|
154
|
+
|
155
|
+
## Troubleshooting
|
156
|
+
|
157
|
+
### CSS Classes Not Applying
|
158
|
+
|
159
|
+
- Ensure you're using named imports: `import { className } from '...'`
|
160
|
+
- Check camelCase conversion for kebab-case names
|
161
|
+
- Clear cache: `rm -rf tmp/cache && bin/shakapacker`
|
162
|
+
|
163
|
+
### TypeScript Errors
|
164
|
+
|
165
|
+
Update your global type definitions as shown in Step 2.
|
166
|
+
|
167
|
+
### Build Warnings
|
168
|
+
|
169
|
+
If you see warnings about CSS module exports, ensure you've updated all imports to use named exports or have properly configured the override.
|
170
|
+
|
171
|
+
## Need Help?
|
172
|
+
|
173
|
+
- See [CSS Modules Export Mode documentation](./css-modules-export-mode.md) for detailed configuration options
|
174
|
+
- Check the [CHANGELOG](../CHANGELOG.md) for all changes
|
175
|
+
- File issues at [GitHub Issues](https://github.com/shakacode/shakapacker/issues)
|
176
|
+
|
177
|
+
## Gradual Migration Strategy
|
178
|
+
|
179
|
+
If you have a large codebase and need to migrate gradually:
|
180
|
+
|
181
|
+
1. Override the CSS configuration to keep v8 behavior (see [documentation](./css-modules-export-mode.md))
|
182
|
+
2. Migrate files incrementally
|
183
|
+
3. Remove the override once migration is complete
|
184
|
+
|
185
|
+
This allows you to upgrade to v9 immediately while taking time to update your CSS module imports.
|
data/lib/install/bin/shakapacker
CHANGED
@@ -2,24 +2,10 @@
|
|
2
2
|
|
3
3
|
ENV["RAILS_ENV"] ||= "development"
|
4
4
|
ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile", __FILE__)
|
5
|
+
ENV["APP_ROOT"] ||= File.expand_path("..", __dir__)
|
5
6
|
|
6
7
|
require "bundler/setup"
|
7
|
-
require "pathname"
|
8
8
|
require "shakapacker"
|
9
|
+
require "shakapacker/runner"
|
9
10
|
|
10
|
-
|
11
|
-
Dir.chdir(APP_ROOT) do
|
12
|
-
config = Shakapacker::Configuration.new(
|
13
|
-
root_path: Pathname.new(APP_ROOT),
|
14
|
-
config_path: Pathname.new(File.join(APP_ROOT, "config/shakapacker.yml")),
|
15
|
-
env: ENV["RAILS_ENV"] || ENV["NODE_ENV"] || "development"
|
16
|
-
)
|
17
|
-
|
18
|
-
if config.rspack?
|
19
|
-
require "shakapacker/rspack_runner"
|
20
|
-
Shakapacker::RspackRunner.run(ARGV)
|
21
|
-
else
|
22
|
-
require "shakapacker/webpack_runner"
|
23
|
-
Shakapacker::WebpackRunner.run(ARGV)
|
24
|
-
end
|
25
|
-
end
|
11
|
+
Shakapacker::Runner.run(ARGV)
|
@@ -29,6 +29,10 @@ default: &default
|
|
29
29
|
# Location for manifest.json, defaults to {public_output_path}/manifest.json if unset
|
30
30
|
# manifest_path: public/packs/manifest.json
|
31
31
|
|
32
|
+
# Location for private server-side bundles (e.g., for SSR)
|
33
|
+
# These bundles are not served publicly, unlike public_output_path
|
34
|
+
# private_output_path: ssr-generated
|
35
|
+
|
32
36
|
# Additional paths webpack should look up modules
|
33
37
|
# ['app/assets', 'engine/foo/app/assets']
|
34
38
|
additional_paths: []
|
@@ -36,11 +40,12 @@ default: &default
|
|
36
40
|
# Reload manifest.json on all requests so we reload latest compiled packs
|
37
41
|
cache_manifest: false
|
38
42
|
|
39
|
-
# Select
|
40
|
-
|
43
|
+
# Select JavaScript transpiler to use, available options are 'babel' (default), 'swc' or 'esbuild'
|
44
|
+
javascript_transpiler: 'babel'
|
41
45
|
|
42
|
-
# Select bundler to use
|
43
|
-
|
46
|
+
# Select assets bundler to use
|
47
|
+
# Available options: 'webpack' (default) or 'rspack'
|
48
|
+
assets_bundler: 'webpack'
|
44
49
|
|
45
50
|
# Raises an error if there is a mismatch in the shakapacker gem and npm package being used
|
46
51
|
ensure_consistent_versioning: true
|
@@ -68,6 +68,13 @@ class Shakapacker::Configuration
|
|
68
68
|
root_path.join(fetch(:public_root_path))
|
69
69
|
end
|
70
70
|
|
71
|
+
def private_output_path
|
72
|
+
private_path = fetch(:private_output_path)
|
73
|
+
return nil unless private_path
|
74
|
+
validate_output_paths!
|
75
|
+
root_path.join(private_path)
|
76
|
+
end
|
77
|
+
|
71
78
|
def public_output_path
|
72
79
|
public_path.join(fetch(:public_output_path))
|
73
80
|
end
|
@@ -88,18 +95,51 @@ class Shakapacker::Configuration
|
|
88
95
|
fetch(:compiler_strategy)
|
89
96
|
end
|
90
97
|
|
98
|
+
def assets_bundler
|
99
|
+
# Show deprecation warning if using old 'bundler' key
|
100
|
+
if data.has_key?(:bundler) && !data.has_key?(:assets_bundler)
|
101
|
+
$stderr.puts "⚠️ DEPRECATION WARNING: The 'bundler' configuration option is deprecated. Please use 'assets_bundler' instead to avoid confusion with Ruby's Bundler gem manager."
|
102
|
+
end
|
103
|
+
ENV["SHAKAPACKER_ASSETS_BUNDLER"] || fetch(:assets_bundler) || fetch(:bundler) || "webpack"
|
104
|
+
end
|
105
|
+
|
106
|
+
# Deprecated: Use assets_bundler instead
|
91
107
|
def bundler
|
92
|
-
|
108
|
+
assets_bundler
|
93
109
|
end
|
94
110
|
|
95
111
|
def rspack?
|
96
|
-
|
112
|
+
assets_bundler == "rspack"
|
97
113
|
end
|
98
114
|
|
99
115
|
def webpack?
|
100
|
-
|
116
|
+
assets_bundler == "webpack"
|
101
117
|
end
|
102
118
|
|
119
|
+
def javascript_transpiler
|
120
|
+
# Show deprecation warning if using old 'webpack_loader' key
|
121
|
+
if data.has_key?(:webpack_loader) && !data.has_key?(:javascript_transpiler)
|
122
|
+
$stderr.puts "⚠️ DEPRECATION WARNING: The 'webpack_loader' configuration option is deprecated. Please use 'javascript_transpiler' instead as it better reflects its purpose of configuring JavaScript transpilation regardless of the bundler used."
|
123
|
+
end
|
124
|
+
|
125
|
+
# Use explicit config if set, otherwise default based on bundler
|
126
|
+
fetch(:javascript_transpiler) || fetch(:webpack_loader) || default_javascript_transpiler
|
127
|
+
end
|
128
|
+
|
129
|
+
# Deprecated: Use javascript_transpiler instead
|
130
|
+
def webpack_loader
|
131
|
+
javascript_transpiler
|
132
|
+
end
|
133
|
+
|
134
|
+
private
|
135
|
+
|
136
|
+
def default_javascript_transpiler
|
137
|
+
# RSpack has built-in SWC support, use it by default
|
138
|
+
rspack? ? "swc" : "babel"
|
139
|
+
end
|
140
|
+
|
141
|
+
public
|
142
|
+
|
103
143
|
def fetch(key)
|
104
144
|
data.fetch(key, defaults[key])
|
105
145
|
end
|
@@ -116,6 +156,38 @@ class Shakapacker::Configuration
|
|
116
156
|
end
|
117
157
|
|
118
158
|
private
|
159
|
+
def validate_output_paths!
|
160
|
+
# Skip validation if already validated to avoid redundant checks
|
161
|
+
return if @validated_output_paths
|
162
|
+
@validated_output_paths = true
|
163
|
+
|
164
|
+
# Only validate when both paths are configured
|
165
|
+
return unless fetch(:private_output_path) && fetch(:public_output_path)
|
166
|
+
|
167
|
+
private_path_str, public_path_str = resolve_paths_for_comparison
|
168
|
+
|
169
|
+
if private_path_str == public_path_str
|
170
|
+
raise "Shakapacker configuration error: private_output_path and public_output_path must be different. " \
|
171
|
+
"Both paths resolve to '#{private_path_str}'. " \
|
172
|
+
"The private_output_path is for server-side bundles (e.g., SSR) that should not be served publicly."
|
173
|
+
end
|
174
|
+
end
|
175
|
+
|
176
|
+
def resolve_paths_for_comparison
|
177
|
+
private_full_path = root_path.join(fetch(:private_output_path))
|
178
|
+
public_full_path = root_path.join(fetch(:public_root_path), fetch(:public_output_path))
|
179
|
+
|
180
|
+
# Create directories if they don't exist (for testing)
|
181
|
+
private_full_path.mkpath unless private_full_path.exist?
|
182
|
+
public_full_path.mkpath unless public_full_path.exist?
|
183
|
+
|
184
|
+
# Use realpath to resolve symbolic links and relative paths
|
185
|
+
[private_full_path.realpath.to_s, public_full_path.realpath.to_s]
|
186
|
+
rescue Errno::ENOENT
|
187
|
+
# If paths don't exist yet, fall back to cleanpath for comparison
|
188
|
+
[private_full_path.cleanpath.to_s, public_full_path.cleanpath.to_s]
|
189
|
+
end
|
190
|
+
|
119
191
|
def data
|
120
192
|
@data ||= load
|
121
193
|
end
|
@@ -7,6 +7,10 @@ require_relative "runner"
|
|
7
7
|
|
8
8
|
module Shakapacker
|
9
9
|
class DevServerRunner < Shakapacker::Runner
|
10
|
+
def self.run(argv)
|
11
|
+
new(argv).run
|
12
|
+
end
|
13
|
+
|
10
14
|
def run
|
11
15
|
load_config
|
12
16
|
detect_unsupported_switches!
|
@@ -75,17 +79,16 @@ module Shakapacker
|
|
75
79
|
env["NODE_OPTIONS"] = "#{env["NODE_OPTIONS"]} --inspect-brk --trace-warnings"
|
76
80
|
end
|
77
81
|
|
78
|
-
# Add
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
+
# Add config file
|
83
|
+
cmd += ["--config", @webpack_config]
|
84
|
+
|
85
|
+
# Add assets bundler-specific flags
|
86
|
+
if webpack?
|
82
87
|
cmd += ["--progress", "--color"] if @pretty
|
83
88
|
# Default behavior of webpack-dev-server is @hot = true
|
84
89
|
cmd += ["--hot", "only"] if @hot == "only"
|
85
90
|
cmd += ["--no-hot"] if !@hot
|
86
|
-
elsif
|
87
|
-
# Only add config for rspack if it's not a rspack-specific command
|
88
|
-
cmd += ["--config", @webpack_config]
|
91
|
+
elsif rspack?
|
89
92
|
# Rspack supports --hot but not --no-hot or --progress/--color
|
90
93
|
cmd += ["--hot"] if @hot && @hot != false
|
91
94
|
end
|
@@ -98,9 +101,16 @@ module Shakapacker
|
|
98
101
|
end
|
99
102
|
|
100
103
|
def build_cmd
|
101
|
-
|
102
|
-
command = bundler == "rspack" ? "rspack" : "webpack"
|
104
|
+
command = @config.rspack? ? "rspack" : "webpack"
|
103
105
|
package_json.manager.native_exec_command(command, ["serve"])
|
104
106
|
end
|
107
|
+
|
108
|
+
def webpack?
|
109
|
+
@config.webpack?
|
110
|
+
end
|
111
|
+
|
112
|
+
def rspack?
|
113
|
+
@config.rspack?
|
114
|
+
end
|
105
115
|
end
|
106
116
|
end
|