shakapacker 9.2.0 → 9.3.0.beta.0
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/ISSUE_TEMPLATE/bug_report.md +6 -9
- data/.github/ISSUE_TEMPLATE/feature_request.md +6 -8
- data/.github/workflows/claude-code-review.yml +4 -5
- data/.github/workflows/claude.yml +1 -2
- data/.github/workflows/dummy.yml +4 -4
- data/.github/workflows/generator.yml +9 -9
- data/.github/workflows/node.yml +11 -2
- data/.github/workflows/ruby.yml +16 -16
- data/.github/workflows/test-bundlers.yml +9 -9
- data/.gitignore +4 -0
- data/CHANGELOG.md +19 -4
- data/CLAUDE.md +6 -1
- data/CONTRIBUTING.md +0 -1
- data/Gemfile.lock +1 -1
- data/README.md +14 -14
- data/TODO.md +10 -2
- data/TODO_v9.md +13 -3
- data/bin/export-bundler-config +1 -1
- data/conductor-setup.sh +1 -1
- data/conductor.json +1 -1
- data/docs/cdn_setup.md +13 -8
- data/docs/common-upgrades.md +2 -1
- data/docs/configuration.md +630 -0
- data/docs/css-modules-export-mode.md +120 -100
- data/docs/customizing_babel_config.md +16 -16
- data/docs/deployment.md +18 -0
- data/docs/developing_shakapacker.md +6 -0
- data/docs/optional-peer-dependencies.md +9 -4
- data/docs/peer-dependencies.md +17 -6
- data/docs/precompile_hook.md +342 -0
- data/docs/react.md +57 -47
- data/docs/releasing.md +0 -2
- data/docs/rspack.md +25 -21
- data/docs/rspack_migration_guide.md +335 -8
- data/docs/sprockets.md +1 -0
- data/docs/style_loader_vs_mini_css.md +12 -12
- data/docs/subresource_integrity.md +13 -7
- data/docs/transpiler-performance.md +40 -19
- data/docs/troubleshooting.md +0 -2
- data/docs/typescript-migration.md +48 -39
- data/docs/typescript.md +12 -8
- data/docs/using_esbuild_loader.md +10 -10
- data/docs/v6_upgrade.md +33 -20
- data/docs/v7_upgrade.md +8 -6
- data/docs/v8_upgrade.md +13 -12
- data/docs/v9_upgrade.md +2 -1
- data/eslint.config.fast.js +134 -0
- data/eslint.config.js +140 -0
- data/knip.ts +54 -0
- data/lib/install/bin/export-bundler-config +1 -1
- data/lib/install/config/shakapacker.yml +16 -5
- data/lib/shakapacker/compiler.rb +80 -0
- data/lib/shakapacker/configuration.rb +33 -5
- data/lib/shakapacker/dev_server_runner.rb +140 -1
- data/lib/shakapacker/doctor.rb +294 -65
- data/lib/shakapacker/instance.rb +8 -3
- data/lib/shakapacker/runner.rb +244 -8
- data/lib/shakapacker/version.rb +1 -1
- data/lib/tasks/shakapacker/doctor.rake +42 -2
- data/package/babel/preset.ts +7 -4
- data/package/config.ts +42 -30
- data/package/configExporter/cli.ts +799 -208
- data/package/configExporter/configFile.ts +520 -0
- data/package/configExporter/fileWriter.ts +12 -8
- data/package/configExporter/index.ts +9 -1
- data/package/configExporter/types.ts +36 -2
- data/package/configExporter/yamlSerializer.ts +22 -8
- data/package/dev_server.ts +1 -1
- data/package/environments/__type-tests__/rspack-plugin-compatibility.ts +11 -5
- data/package/environments/base.ts +18 -13
- data/package/environments/development.ts +1 -1
- data/package/environments/production.ts +4 -1
- data/package/index.d.ts +50 -3
- data/package/index.d.ts.template +50 -0
- data/package/index.ts +7 -7
- data/package/loaders.d.ts +2 -2
- data/package/optimization/rspack.ts +1 -1
- data/package/plugins/rspack.ts +15 -4
- data/package/plugins/webpack.ts +7 -3
- data/package/rspack/index.ts +10 -2
- data/package/rules/raw.ts +3 -2
- data/package/rules/sass.ts +1 -1
- data/package/types/README.md +15 -13
- data/package/types/index.ts +5 -5
- data/package/types.ts +0 -1
- data/package/utils/defaultConfigPath.ts +4 -1
- data/package/utils/errorCodes.ts +129 -100
- data/package/utils/errorHelpers.ts +34 -29
- data/package/utils/getStyleRule.ts +5 -2
- data/package/utils/helpers.ts +21 -11
- data/package/utils/pathValidation.ts +43 -35
- data/package/utils/requireOrError.ts +1 -1
- data/package/utils/snakeToCamelCase.ts +1 -1
- data/package/utils/typeGuards.ts +132 -83
- data/package/utils/validateDependencies.ts +1 -1
- data/package/webpack-types.d.ts +3 -3
- data/package/webpackDevServerConfig.ts +22 -10
- data/package-lock.json +2 -2
- data/package.json +36 -28
- data/scripts/type-check-no-emit.js +1 -1
- data/test/configExporter/configFile.test.js +392 -0
- data/test/configExporter/integration.test.js +275 -0
- data/test/helpers.js +1 -1
- data/test/package/configExporter.test.js +154 -0
- data/test/package/helpers.test.js +2 -2
- data/test/package/rules/sass-version-parsing.test.js +71 -0
- data/test/package/rules/sass.test.js +2 -4
- data/test/package/rules/sass1.test.js +1 -3
- data/test/package/rules/sass16.test.js +23 -0
- data/tools/README.md +15 -5
- data/tsconfig.eslint.json +2 -9
- data/yarn.lock +1894 -1492
- metadata +19 -3
- data/.eslintignore +0 -5
data/docs/peer-dependencies.md
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
# Shakapacker's Peer Dependencies
|
2
|
+
|
2
3
|
## Last updated for our 9.0.0 version — see lib/install/package.json
|
3
4
|
|
4
5
|
To simplify peer dependencies while supporting both webpack & rspack, we decided to document the dependencies here instead of creating two separate npm packages.
|
@@ -6,13 +7,16 @@ To simplify peer dependencies while supporting both webpack & rspack, we decided
|
|
6
7
|
**Important Note**: Starting with v9, Babel dependencies are no longer included as peer dependencies. They will be installed automatically only if you're using Babel as your JavaScript transpiler.
|
7
8
|
|
8
9
|
## Essential for Rspack
|
9
|
-
|
10
|
+
|
11
|
+
```text
|
10
12
|
"@rspack/cli": "^1.0.0",
|
11
13
|
"@rspack/core": "^1.0.0",
|
12
14
|
"rspack-manifest-plugin": "^5.0.0",
|
13
15
|
```
|
16
|
+
|
14
17
|
## Essential for Webpack
|
15
|
-
|
18
|
+
|
19
|
+
```text
|
16
20
|
"mini-css-extract-plugin": "^2.0.0",
|
17
21
|
"terser-webpack-plugin": "^5.3.1",
|
18
22
|
"webpack": "^5.76.0",
|
@@ -24,7 +28,8 @@ To simplify peer dependencies while supporting both webpack & rspack, we decided
|
|
24
28
|
```
|
25
29
|
|
26
30
|
## Highly recommended
|
27
|
-
|
31
|
+
|
32
|
+
```text
|
28
33
|
"compression-webpack-plugin": "^9.0.0 || ^10.0.0|| ^11.0.0",
|
29
34
|
"css-loader": "^6.0.0 || ^7.0.0",
|
30
35
|
"sass-loader": "^13.0.0 || ^14.0.0 || ^15.0.0 || ^16.0.0",
|
@@ -34,27 +39,33 @@ To simplify peer dependencies while supporting both webpack & rspack, we decided
|
|
34
39
|
## Optional JavaScript Transpilers
|
35
40
|
|
36
41
|
### Babel (installed automatically when `javascript_transpiler: 'babel'`)
|
37
|
-
|
42
|
+
|
43
|
+
```text
|
38
44
|
"@babel/core": "^7.17.9",
|
39
45
|
"@babel/plugin-transform-runtime": "^7.17.0",
|
40
46
|
"@babel/preset-env": "^7.16.11",
|
41
47
|
"@babel/runtime": "^7.17.9",
|
42
48
|
"babel-loader": "^8.2.4 || ^9.0.0 || ^10.0.0",
|
43
49
|
```
|
50
|
+
|
44
51
|
Note: These dependencies are only installed if you're using Babel as your JavaScript transpiler. Consider using SWC or esbuild for better performance.
|
45
52
|
|
46
53
|
### SWC (default - 20x faster than Babel)
|
47
|
-
|
54
|
+
|
55
|
+
```text
|
48
56
|
"@swc/core": "latest",
|
49
57
|
"swc-loader": "latest"
|
50
58
|
```
|
59
|
+
|
51
60
|
- **For webpack**: Installed automatically when using default configuration
|
52
61
|
- **For rspack**: Built-in, no additional installation needed (rspack includes SWC natively)
|
53
62
|
- Manual install: `npm install @swc/core swc-loader`
|
54
63
|
|
55
64
|
### esbuild
|
56
|
-
|
65
|
+
|
66
|
+
```text
|
57
67
|
"esbuild": "latest",
|
58
68
|
"esbuild-loader": "latest"
|
59
69
|
```
|
70
|
+
|
60
71
|
Install manually with: `npm install esbuild esbuild-loader`
|
@@ -0,0 +1,342 @@
|
|
1
|
+
# Precompile Hook
|
2
|
+
|
3
|
+
The `precompile_hook` configuration option allows you to run a custom command before asset compilation.
|
4
|
+
|
5
|
+
**📖 For other configuration options, see the [Configuration Guide](./configuration.md)**
|
6
|
+
|
7
|
+
This is useful for:
|
8
|
+
|
9
|
+
- Dynamically generating entry points (e.g., from database records)
|
10
|
+
- Running preparatory tasks before bundling
|
11
|
+
- Integrating with tools like React on Rails that need to generate packs
|
12
|
+
|
13
|
+
## When to Use
|
14
|
+
|
15
|
+
The precompile hook is especially useful when you need to run commands like:
|
16
|
+
|
17
|
+
- `bin/rails react_on_rails:generate_packs` - Generate dynamic entry points
|
18
|
+
- `bin/rails react_on_rails:locale` - Generate locale files
|
19
|
+
- Any custom script that prepares files before asset compilation
|
20
|
+
|
21
|
+
**Important:** The hook runs in **both development and production**:
|
22
|
+
|
23
|
+
- **Development**: Runs before `bin/shakapacker --watch` or dev server starts
|
24
|
+
- **Production**: Runs before `rails assets:precompile`
|
25
|
+
|
26
|
+
## Configuration
|
27
|
+
|
28
|
+
Add the `precompile_hook` option to your `config/shakapacker.yml`:
|
29
|
+
|
30
|
+
```yaml
|
31
|
+
# For all environments
|
32
|
+
default: &default
|
33
|
+
precompile_hook: "bin/shakapacker-precompile-hook"
|
34
|
+
|
35
|
+
# Or environment-specific
|
36
|
+
development:
|
37
|
+
<<: *default
|
38
|
+
precompile_hook: "bin/dev-setup"
|
39
|
+
|
40
|
+
production:
|
41
|
+
<<: *default
|
42
|
+
precompile_hook: "bin/rails react_on_rails:generate_packs"
|
43
|
+
```
|
44
|
+
|
45
|
+
## Creating a Precompile Hook Script
|
46
|
+
|
47
|
+
### Simple Shell Script
|
48
|
+
|
49
|
+
```bash
|
50
|
+
#!/usr/bin/env bash
|
51
|
+
# bin/shakapacker-precompile-hook
|
52
|
+
|
53
|
+
echo "Preparing assets..."
|
54
|
+
bin/rails react_on_rails:generate_packs
|
55
|
+
bin/rails react_on_rails:locale
|
56
|
+
echo "Assets prepared successfully"
|
57
|
+
```
|
58
|
+
|
59
|
+
### Ruby Script with Database Access
|
60
|
+
|
61
|
+
```ruby
|
62
|
+
#!/usr/bin/env ruby
|
63
|
+
# bin/shakapacker-precompile-hook
|
64
|
+
|
65
|
+
require_relative "../config/environment"
|
66
|
+
|
67
|
+
puts "Generating dynamic entry points..."
|
68
|
+
|
69
|
+
# Generate entry points from database
|
70
|
+
Theme.find_each do |theme|
|
71
|
+
entry_point = Rails.root.join("app/javascript/packs/theme_#{theme.id}.js")
|
72
|
+
File.write(entry_point, "import '../themes/#{theme.identifier}';")
|
73
|
+
puts " Created #{entry_point}"
|
74
|
+
end
|
75
|
+
|
76
|
+
puts "Entry points generated successfully"
|
77
|
+
exit 0
|
78
|
+
```
|
79
|
+
|
80
|
+
Make the script executable:
|
81
|
+
|
82
|
+
```bash
|
83
|
+
chmod +x bin/shakapacker-precompile-hook
|
84
|
+
```
|
85
|
+
|
86
|
+
## How It Works
|
87
|
+
|
88
|
+
### Execution Flow
|
89
|
+
|
90
|
+
1. **Triggered** when asset compilation starts
|
91
|
+
2. **Hook runs** in your project root directory
|
92
|
+
3. **Environment variables** are passed through (including `NODE_ENV`, `RAILS_ENV`, `SHAKAPACKER_ASSET_HOST`)
|
93
|
+
4. **On success** (exit code 0): Compilation proceeds
|
94
|
+
5. **On failure** (non-zero exit code): Compilation stops with error
|
95
|
+
|
96
|
+
**Migration Note:** If you're migrating from custom `assets:precompile` enhancements (e.g., in `lib/tasks/assets.rake`), ensure you don't run the same commands twice. React on Rails versions before 16.1.1 automatically prepend `react_on_rails:generate_packs` to `assets:precompile`. Versions 16.1.1+ detect `precompile_hook` and skip automatic task enhancement to avoid duplicate execution. For custom Rake task enhancements, remove manual invocations when adding `precompile_hook`.
|
97
|
+
|
98
|
+
To verify correct migration, run `rake assets:precompile` and check the logs. Commands like `react_on_rails:generate_packs` should appear **only once** in the output. If you see duplicate execution, either upgrade React on Rails to 16.1.1+ or remove your custom task enhancements.
|
99
|
+
|
100
|
+
### Logging
|
101
|
+
|
102
|
+
The hook's stdout and stderr are logged:
|
103
|
+
|
104
|
+
```
|
105
|
+
Running precompile hook: bin/shakapacker-precompile-hook
|
106
|
+
Preparing assets...
|
107
|
+
Entry points generated successfully
|
108
|
+
Precompile hook completed successfully
|
109
|
+
Compiling...
|
110
|
+
```
|
111
|
+
|
112
|
+
## React on Rails Integration
|
113
|
+
|
114
|
+
For React on Rails projects, the hook replaces manual steps in your workflow:
|
115
|
+
|
116
|
+
### Before (Manual)
|
117
|
+
|
118
|
+
```bash
|
119
|
+
# Development
|
120
|
+
bin/rails react_on_rails:generate_packs
|
121
|
+
bin/rails react_on_rails:locale
|
122
|
+
bin/shakapacker-dev-server
|
123
|
+
|
124
|
+
# Production
|
125
|
+
bin/rails react_on_rails:generate_packs
|
126
|
+
bin/rails react_on_rails:locale
|
127
|
+
RAILS_ENV=production bin/rails assets:precompile
|
128
|
+
```
|
129
|
+
|
130
|
+
### After (Automatic)
|
131
|
+
|
132
|
+
```yaml
|
133
|
+
# config/shakapacker.yml
|
134
|
+
default: &default
|
135
|
+
precompile_hook: "bin/react-on-rails-hook"
|
136
|
+
```
|
137
|
+
|
138
|
+
```bash
|
139
|
+
#!/usr/bin/env bash
|
140
|
+
# bin/react-on-rails-hook
|
141
|
+
bin/rails react_on_rails:generate_packs
|
142
|
+
bin/rails react_on_rails:locale
|
143
|
+
```
|
144
|
+
|
145
|
+
Now simply run:
|
146
|
+
|
147
|
+
```bash
|
148
|
+
# Development
|
149
|
+
bin/shakapacker-dev-server
|
150
|
+
|
151
|
+
# Production
|
152
|
+
RAILS_ENV=production bin/rails assets:precompile
|
153
|
+
```
|
154
|
+
|
155
|
+
## Security
|
156
|
+
|
157
|
+
For security reasons, the precompile hook is validated to ensure:
|
158
|
+
|
159
|
+
### 1. Project Root Restriction
|
160
|
+
|
161
|
+
The hook **must** reference a script within your project root:
|
162
|
+
|
163
|
+
```yaml
|
164
|
+
# ✅ Valid - within project
|
165
|
+
precompile_hook: 'bin/shakapacker-precompile-hook'
|
166
|
+
precompile_hook: 'script/prepare-assets'
|
167
|
+
precompile_hook: 'bin/hook --arg1 --arg2'
|
168
|
+
|
169
|
+
# ❌ Invalid - outside project
|
170
|
+
precompile_hook: '/usr/bin/malicious-script'
|
171
|
+
precompile_hook: '../../../etc/passwd'
|
172
|
+
```
|
173
|
+
|
174
|
+
### 2. Symlink Resolution
|
175
|
+
|
176
|
+
Symlinks are resolved to their real paths before validation:
|
177
|
+
|
178
|
+
```bash
|
179
|
+
# If bin/hook is a symlink to /usr/bin/evil
|
180
|
+
# The validation will detect and reject it
|
181
|
+
```
|
182
|
+
|
183
|
+
### 3. Path Traversal Protection
|
184
|
+
|
185
|
+
Path traversal attempts are blocked:
|
186
|
+
|
187
|
+
```yaml
|
188
|
+
# ❌ These will be rejected
|
189
|
+
precompile_hook: 'bin/../../etc/passwd'
|
190
|
+
precompile_hook: '../outside-project/script'
|
191
|
+
```
|
192
|
+
|
193
|
+
### 4. Proper Path Boundary Checking
|
194
|
+
|
195
|
+
Partial path matches are prevented:
|
196
|
+
|
197
|
+
```
|
198
|
+
# /project won't match /project-evil
|
199
|
+
# Uses File::SEPARATOR for proper validation
|
200
|
+
```
|
201
|
+
|
202
|
+
## Error Handling
|
203
|
+
|
204
|
+
### Hook Failure
|
205
|
+
|
206
|
+
If the hook fails, you'll see a detailed error:
|
207
|
+
|
208
|
+
```
|
209
|
+
PRECOMPILE HOOK FAILED:
|
210
|
+
EXIT STATUS: 1
|
211
|
+
COMMAND: bin/shakapacker-precompile-hook
|
212
|
+
OUTPUTS:
|
213
|
+
Error: Theme not found
|
214
|
+
|
215
|
+
To fix this:
|
216
|
+
1. Check that the hook script exists and is executable
|
217
|
+
2. Test the hook command manually: bin/shakapacker-precompile-hook
|
218
|
+
3. Review the error output above for details
|
219
|
+
4. You can disable the hook temporarily by commenting out 'precompile_hook' in shakapacker.yml
|
220
|
+
```
|
221
|
+
|
222
|
+
### Missing Executable
|
223
|
+
|
224
|
+
If the script doesn't exist, you'll see a warning:
|
225
|
+
|
226
|
+
```
|
227
|
+
⚠️ Warning: precompile_hook executable not found: /path/to/project/bin/hook
|
228
|
+
The hook command is configured but the script does not exist within the project root.
|
229
|
+
Please ensure the script exists or remove 'precompile_hook' from your shakapacker.yml configuration.
|
230
|
+
```
|
231
|
+
|
232
|
+
## Troubleshooting
|
233
|
+
|
234
|
+
### Test the Hook Manually
|
235
|
+
|
236
|
+
Run the hook directly to see what happens:
|
237
|
+
|
238
|
+
```bash
|
239
|
+
bin/shakapacker-precompile-hook
|
240
|
+
echo $? # Should output 0 for success
|
241
|
+
```
|
242
|
+
|
243
|
+
### Check Permissions
|
244
|
+
|
245
|
+
Ensure the script is executable:
|
246
|
+
|
247
|
+
```bash
|
248
|
+
ls -la bin/shakapacker-precompile-hook
|
249
|
+
# Should show: -rwxr-xr-x (executable)
|
250
|
+
|
251
|
+
# If not executable:
|
252
|
+
chmod +x bin/shakapacker-precompile-hook
|
253
|
+
```
|
254
|
+
|
255
|
+
### Debug with Verbose Output
|
256
|
+
|
257
|
+
Add debug output to your hook:
|
258
|
+
|
259
|
+
```bash
|
260
|
+
#!/usr/bin/env bash
|
261
|
+
set -x # Enable verbose mode
|
262
|
+
echo "Current directory: $(pwd)"
|
263
|
+
echo "Environment: $RAILS_ENV"
|
264
|
+
# Your commands here
|
265
|
+
```
|
266
|
+
|
267
|
+
### Temporarily Disable
|
268
|
+
|
269
|
+
To disable the hook for testing:
|
270
|
+
|
271
|
+
```yaml
|
272
|
+
# config/shakapacker.yml
|
273
|
+
default:
|
274
|
+
# precompile_hook: 'bin/shakapacker-precompile-hook'
|
275
|
+
```
|
276
|
+
|
277
|
+
### Common Issues
|
278
|
+
|
279
|
+
**Issue:** Hook fails in production but works in development - Verify all dependencies are available (database, commands, gems)
|
280
|
+
|
281
|
+
**Issue:** Generated files not found - Check `source_path` and `source_entry_path` in `shakapacker.yml`
|
282
|
+
|
283
|
+
**Issue:** Permission denied - Run `chmod +x bin/shakapacker-precompile-hook`
|
284
|
+
|
285
|
+
## Advanced Usage
|
286
|
+
|
287
|
+
### Conditional Execution
|
288
|
+
|
289
|
+
```bash
|
290
|
+
#!/usr/bin/env bash
|
291
|
+
# bin/shakapacker-precompile-hook
|
292
|
+
|
293
|
+
if [ "$RAILS_ENV" = "production" ]; then
|
294
|
+
echo "Running production-specific setup..."
|
295
|
+
bin/rails react_on_rails:generate_packs
|
296
|
+
else
|
297
|
+
echo "Running development setup..."
|
298
|
+
# Lighter-weight setup for development
|
299
|
+
fi
|
300
|
+
```
|
301
|
+
|
302
|
+
### Hook with Arguments
|
303
|
+
|
304
|
+
```yaml
|
305
|
+
precompile_hook: "bin/prepare-assets --verbose --cache-bust"
|
306
|
+
```
|
307
|
+
|
308
|
+
```bash
|
309
|
+
#!/usr/bin/env bash
|
310
|
+
# bin/prepare-assets
|
311
|
+
|
312
|
+
VERBOSE=false
|
313
|
+
CACHE_BUST=false
|
314
|
+
|
315
|
+
while [[ $# -gt 0 ]]; do
|
316
|
+
case $1 in
|
317
|
+
--verbose) VERBOSE=true ;;
|
318
|
+
--cache-bust) CACHE_BUST=true ;;
|
319
|
+
esac
|
320
|
+
shift
|
321
|
+
done
|
322
|
+
|
323
|
+
if [ "$VERBOSE" = true ]; then
|
324
|
+
echo "Preparing assets..."
|
325
|
+
fi
|
326
|
+
```
|
327
|
+
|
328
|
+
### Handling Spaces in Paths
|
329
|
+
|
330
|
+
Use quotes for paths with spaces:
|
331
|
+
|
332
|
+
```yaml
|
333
|
+
precompile_hook: "'bin/my hook script' --arg1"
|
334
|
+
```
|
335
|
+
|
336
|
+
The hook system uses `Shellwords` to properly parse quoted arguments.
|
337
|
+
|
338
|
+
## See Also
|
339
|
+
|
340
|
+
- [Deployment Guide](deployment.md) - Production deployment considerations
|
341
|
+
- [React on Rails Integration](https://github.com/shakacode/react_on_rails) - Main use case documentation
|
342
|
+
- [Configuration](../README.md#configuration-and-code) - General shakapacker configuration
|
data/docs/react.md
CHANGED
@@ -53,19 +53,17 @@ npm install --dev react-refresh @pmmmwh/react-refresh-webpack-plugin
|
|
53
53
|
Alter `config/webpack/webpack.config.js` like so:
|
54
54
|
|
55
55
|
```js
|
56
|
-
const { generateWebpackConfig, inliningCss } = require(
|
57
|
-
const ReactRefreshWebpackPlugin = require(
|
58
|
-
const isDevelopment = process.env.NODE_ENV !==
|
56
|
+
const { generateWebpackConfig, inliningCss } = require("shakapacker")
|
57
|
+
const ReactRefreshWebpackPlugin = require("@pmmmwh/react-refresh-webpack-plugin")
|
58
|
+
const isDevelopment = process.env.NODE_ENV !== "production"
|
59
59
|
|
60
|
-
const webpackConfig = generateWebpackConfig()
|
60
|
+
const webpackConfig = generateWebpackConfig()
|
61
61
|
|
62
62
|
if (isDevelopment && inliningCss) {
|
63
|
-
webpackConfig.plugins.push(
|
64
|
-
new ReactRefreshWebpackPlugin()
|
65
|
-
);
|
63
|
+
webpackConfig.plugins.push(new ReactRefreshWebpackPlugin())
|
66
64
|
}
|
67
65
|
|
68
|
-
module.exports = webpackConfig
|
66
|
+
module.exports = webpackConfig
|
69
67
|
```
|
70
68
|
|
71
69
|
This applies the plugin to the webpack configuration.
|
@@ -85,16 +83,16 @@ Then create a `babel.config.js` file in the root of project and add the followin
|
|
85
83
|
|
86
84
|
```js
|
87
85
|
module.exports = function (api) {
|
88
|
-
const defaultConfigFunc = require(
|
86
|
+
const defaultConfigFunc = require("shakapacker/package/babel/preset.js")
|
89
87
|
const resultConfig = defaultConfigFunc(api)
|
90
|
-
const isDevelopmentEnv = api.env(
|
91
|
-
const isProductionEnv = api.env(
|
92
|
-
const isTestEnv = api.env(
|
88
|
+
const isDevelopmentEnv = api.env("development")
|
89
|
+
const isProductionEnv = api.env("production")
|
90
|
+
const isTestEnv = api.env("test")
|
93
91
|
|
94
92
|
const changesOnDefault = {
|
95
93
|
presets: [
|
96
94
|
[
|
97
|
-
|
95
|
+
"@babel/preset-react",
|
98
96
|
{
|
99
97
|
development: isDevelopmentEnv || isTestEnv,
|
100
98
|
useBuiltIns: true
|
@@ -102,17 +100,18 @@ module.exports = function (api) {
|
|
102
100
|
]
|
103
101
|
].filter(Boolean),
|
104
102
|
plugins: [
|
105
|
-
isProductionEnv && [
|
103
|
+
isProductionEnv && [
|
104
|
+
"babel-plugin-transform-react-remove-prop-types",
|
106
105
|
{
|
107
106
|
removeImport: true
|
108
107
|
}
|
109
108
|
],
|
110
|
-
process.env.WEBPACK_SERVE &&
|
111
|
-
].filter(Boolean)
|
109
|
+
process.env.WEBPACK_SERVE && "react-refresh/babel"
|
110
|
+
].filter(Boolean)
|
112
111
|
}
|
113
112
|
|
114
113
|
resultConfig.presets = [...resultConfig.presets, ...changesOnDefault.presets]
|
115
|
-
resultConfig.plugins = [...resultConfig.plugins, ...changesOnDefault.plugins
|
114
|
+
resultConfig.plugins = [...resultConfig.plugins, ...changesOnDefault.plugins]
|
116
115
|
|
117
116
|
return resultConfig
|
118
117
|
}
|
@@ -127,6 +126,7 @@ HMR for your React app is now enabled. 🚀
|
|
127
126
|
To test that all of the above is working, you can follow these instructions to create a basic React app using Shakapacker.
|
128
127
|
|
129
128
|
1. Create a new Rails app:
|
129
|
+
|
130
130
|
```shell
|
131
131
|
rails new myapp --skip-javascript
|
132
132
|
cd myapp
|
@@ -138,44 +138,52 @@ npm install css-loader style-loader mini-css-extract-plugin css-minimizer-webpac
|
|
138
138
|
```
|
139
139
|
|
140
140
|
2. Generate a controller
|
141
|
+
|
141
142
|
```shell
|
142
143
|
rails g controller site index
|
143
144
|
echo '<div id="root"></div>' > app/views/site/index.html.erb
|
144
145
|
```
|
145
146
|
|
146
147
|
3. Create a CSS file and a React component:
|
148
|
+
|
147
149
|
```shell
|
148
150
|
touch app/javascript/App.css app/javascript/App.js
|
149
151
|
```
|
150
152
|
|
151
153
|
4. Edit `app/javascript/packs/application.js` like so:
|
154
|
+
|
152
155
|
```jsx
|
153
|
-
import React from
|
154
|
-
import { createRoot } from
|
155
|
-
import HelloMessage from
|
156
|
+
import React from "react"
|
157
|
+
import { createRoot } from "react-dom/client"
|
158
|
+
import HelloMessage from "../App"
|
156
159
|
|
157
|
-
const container = document.getElementById(
|
158
|
-
const root = createRoot(container)
|
160
|
+
const container = document.getElementById("root")
|
161
|
+
const root = createRoot(container)
|
159
162
|
|
160
|
-
document.addEventListener(
|
161
|
-
root.render(<HelloMessage name="World" />)
|
162
|
-
})
|
163
|
+
document.addEventListener("DOMContentLoaded", () => {
|
164
|
+
root.render(<HelloMessage name="World" />)
|
165
|
+
})
|
163
166
|
```
|
164
167
|
|
165
168
|
5. Add the following to `app/javascript/App.js`:
|
169
|
+
|
166
170
|
```jsx
|
167
|
-
import React from
|
168
|
-
import
|
169
|
-
const HelloMessage = ({ name }) => <h1>Hello, {name}!</h1
|
170
|
-
export default HelloMessage
|
171
|
+
import React from "react"
|
172
|
+
import "App.css"
|
173
|
+
const HelloMessage = ({ name }) => <h1>Hello, {name}!</h1>
|
174
|
+
export default HelloMessage
|
171
175
|
```
|
172
176
|
|
173
177
|
6. Add the following to `app/javascript/App.css`:
|
178
|
+
|
174
179
|
```css
|
175
|
-
h1 {
|
180
|
+
h1 {
|
181
|
+
color: blue;
|
182
|
+
}
|
176
183
|
```
|
177
184
|
|
178
185
|
7. Enable HMR in config/shakapacker.yml:
|
186
|
+
|
179
187
|
```shell
|
180
188
|
hmr: true
|
181
189
|
```
|
@@ -189,22 +197,21 @@ npm install --dev react-refresh @pmmmwh/react-refresh-webpack-plugin
|
|
189
197
|
9. Alter `config/webpack/webpack.config.js` like so:
|
190
198
|
|
191
199
|
```js
|
192
|
-
const { generateWebpackConfig, inliningCss } = require(
|
193
|
-
const ReactRefreshWebpackPlugin = require(
|
194
|
-
const isDevelopment = process.env.NODE_ENV !==
|
200
|
+
const { generateWebpackConfig, inliningCss } = require("shakapacker")
|
201
|
+
const ReactRefreshWebpackPlugin = require("@pmmmwh/react-refresh-webpack-plugin")
|
202
|
+
const isDevelopment = process.env.NODE_ENV !== "production"
|
195
203
|
|
196
|
-
const webpackConfig = generateWebpackConfig()
|
204
|
+
const webpackConfig = generateWebpackConfig()
|
197
205
|
|
198
206
|
if (isDevelopment && inliningCss) {
|
199
|
-
webpackConfig.plugins.push(
|
200
|
-
new ReactRefreshWebpackPlugin()
|
201
|
-
);
|
207
|
+
webpackConfig.plugins.push(new ReactRefreshWebpackPlugin())
|
202
208
|
}
|
203
209
|
|
204
|
-
module.exports = webpackConfig
|
210
|
+
module.exports = webpackConfig
|
205
211
|
```
|
206
212
|
|
207
213
|
10. Remove the Babel configuration from `package.json`
|
214
|
+
|
208
215
|
```diff
|
209
216
|
- "babel": {
|
210
217
|
- "presets": [
|
@@ -214,18 +221,19 @@ module.exports = webpackConfig;
|
|
214
221
|
```
|
215
222
|
|
216
223
|
11. Create a `babel.config.js` file in the project root and add the following [sample code](https://github.com/shakacode/shakapacker/blob/main/docs/customizing_babel_config.md#react-configuration):
|
224
|
+
|
217
225
|
```js
|
218
226
|
module.exports = function (api) {
|
219
|
-
const defaultConfigFunc = require(
|
227
|
+
const defaultConfigFunc = require("shakapacker/package/babel/preset.js")
|
220
228
|
const resultConfig = defaultConfigFunc(api)
|
221
|
-
const isDevelopmentEnv = api.env(
|
222
|
-
const isProductionEnv = api.env(
|
223
|
-
const isTestEnv = api.env(
|
229
|
+
const isDevelopmentEnv = api.env("development")
|
230
|
+
const isProductionEnv = api.env("production")
|
231
|
+
const isTestEnv = api.env("test")
|
224
232
|
|
225
233
|
const changesOnDefault = {
|
226
234
|
presets: [
|
227
235
|
[
|
228
|
-
|
236
|
+
"@babel/preset-react",
|
229
237
|
{
|
230
238
|
development: isDevelopmentEnv || isTestEnv,
|
231
239
|
useBuiltIns: true
|
@@ -233,23 +241,25 @@ module.exports = function (api) {
|
|
233
241
|
]
|
234
242
|
].filter(Boolean),
|
235
243
|
plugins: [
|
236
|
-
isProductionEnv && [
|
244
|
+
isProductionEnv && [
|
245
|
+
"babel-plugin-transform-react-remove-prop-types",
|
237
246
|
{
|
238
247
|
removeImport: true
|
239
248
|
}
|
240
249
|
],
|
241
|
-
process.env.WEBPACK_SERVE &&
|
242
|
-
].filter(Boolean)
|
250
|
+
process.env.WEBPACK_SERVE && "react-refresh/babel"
|
251
|
+
].filter(Boolean)
|
243
252
|
}
|
244
253
|
|
245
254
|
resultConfig.presets = [...resultConfig.presets, ...changesOnDefault.presets]
|
246
|
-
resultConfig.plugins = [...resultConfig.plugins, ...changesOnDefault.plugins
|
255
|
+
resultConfig.plugins = [...resultConfig.plugins, ...changesOnDefault.plugins]
|
247
256
|
|
248
257
|
return resultConfig
|
249
258
|
}
|
250
259
|
```
|
251
260
|
|
252
261
|
9. Start the Rails server and the `shakapacker-dev-server` in separate console windows:
|
262
|
+
|
253
263
|
```shell
|
254
264
|
rails s
|
255
265
|
./bin/shakapacker-dev-server
|
data/docs/releasing.md
CHANGED
@@ -12,7 +12,6 @@ This guide is for Shakapacker maintainers who need to publish a new release.
|
|
12
12
|
```
|
13
13
|
|
14
14
|
2. **Ensure you have publishing access:**
|
15
|
-
|
16
15
|
- npm: You must be a collaborator on the [shakapacker npm package](https://www.npmjs.com/package/shakapacker)
|
17
16
|
- RubyGems: You must be an owner of the [shakapacker gem](https://rubygems.org/gems/shakapacker)
|
18
17
|
|
@@ -103,7 +102,6 @@ rake create_release[10.0.0.rc.1] # Gem: 10.0.0.rc.1, npm: 10.0.0-rc.1
|
|
103
102
|
### 6. After Release
|
104
103
|
|
105
104
|
1. Verify the release on:
|
106
|
-
|
107
105
|
- [npm](https://www.npmjs.com/package/shakapacker)
|
108
106
|
- [RubyGems](https://rubygems.org/gems/shakapacker)
|
109
107
|
- [GitHub releases](https://github.com/shakacode/shakapacker/releases)
|