shakapacker 9.3.0.beta.1 → 9.3.0.beta.4
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/eslint-validation.yml +46 -0
- data/ESLINT_TECHNICAL_DEBT.md +159 -0
- data/Gemfile.lock +1 -1
- data/README.md +9 -6
- data/docs/common-upgrades.md +80 -0
- data/docs/configuration.md +101 -0
- data/docs/preventing_fouc.md +132 -0
- data/docs/troubleshooting.md +4 -0
- data/docs/v9_upgrade.md +90 -8
- data/eslint.config.js +119 -7
- data/lib/shakapacker/build_config_loader.rb +147 -0
- data/lib/shakapacker/configuration.rb +6 -2
- data/lib/shakapacker/dev_server_runner.rb +73 -0
- data/lib/shakapacker/runner.rb +263 -15
- data/lib/shakapacker/version.rb +1 -1
- data/package/configExporter/buildValidator.ts +2 -2
- data/package/configExporter/cli.ts +260 -173
- data/package/configExporter/configFile.ts +182 -46
- data/package/configExporter/fileWriter.ts +20 -13
- data/package/configExporter/types.ts +2 -0
- data/package/utils/pathValidation.ts +3 -3
- data/package-lock.json +2 -2
- data/package.json +1 -1
- data/test/configExporter/buildValidator.test.js +31 -28
- data/test/configExporter/configFile.test.js +3 -2
- data/test/configExporter/integration.test.js +14 -27
- data/test/package/configExporter.test.js +4 -8
- metadata +8 -4
- /data/bin/{export-bundler-config → shakapacker-config} +0 -0
- /data/lib/install/bin/{export-bundler-config → shakapacker-config} +0 -0
data/docs/v9_upgrade.md
CHANGED
|
@@ -4,6 +4,15 @@ This guide outlines new features, breaking changes, and migration steps for upgr
|
|
|
4
4
|
|
|
5
5
|
**📖 For detailed configuration options, see the [Configuration Guide](./configuration.md)**
|
|
6
6
|
|
|
7
|
+
> **⚠️ Important:** Shakapacker is both a Ruby gem AND an npm package. **You must update BOTH**:
|
|
8
|
+
>
|
|
9
|
+
> - Update the version in `Gemfile`
|
|
10
|
+
> - Update the version in `package.json`
|
|
11
|
+
> - Run `bundle update shakapacker`
|
|
12
|
+
> - Run your package manager install command (`yarn install`, `npm install`, or `pnpm install`)
|
|
13
|
+
>
|
|
14
|
+
> See [Migration Steps](#migration-steps) below for detailed instructions including version format differences and testing.
|
|
15
|
+
|
|
7
16
|
> **⚠️ Important for v9.1.0 Users:** If you're upgrading to v9.1.0 or later, please note the [SWC Configuration Breaking Change](#swc-loose-mode-breaking-change-v910) below. This affects users who previously configured SWC in v9.0.0.
|
|
8
17
|
|
|
9
18
|
## New Features
|
|
@@ -264,15 +273,49 @@ You won't get warnings about missing Babel, Rspack, or esbuild packages.
|
|
|
264
273
|
|
|
265
274
|
## Migration Steps
|
|
266
275
|
|
|
267
|
-
|
|
276
|
+
> **💡 Tip:** For general upgrade instructions applicable to all Shakapacker versions, see [Upgrading Shakapacker](./common-upgrades.md#upgrading-shakapacker) in the Common Upgrades guide.
|
|
277
|
+
|
|
278
|
+
### Step 1: Update Gemfile
|
|
279
|
+
|
|
280
|
+
Update the shakapacker version in your `Gemfile`:
|
|
281
|
+
|
|
282
|
+
```ruby
|
|
283
|
+
# Gemfile
|
|
284
|
+
gem "shakapacker", "9.3.0" # or latest version
|
|
285
|
+
```
|
|
286
|
+
|
|
287
|
+
**Note:** Ruby gems use dot notation for pre-release versions (e.g., `9.3.0.beta.1`), while npm uses hyphen notation (e.g., `9.3.0-beta.1`). See [Version Format Differences](#version-format-differences) below.
|
|
288
|
+
|
|
289
|
+
### Step 2: Update package.json
|
|
290
|
+
|
|
291
|
+
Update the shakapacker version in your `package.json`:
|
|
292
|
+
|
|
293
|
+
```json
|
|
294
|
+
{
|
|
295
|
+
"dependencies": {
|
|
296
|
+
"shakapacker": "9.3.0"
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
```
|
|
300
|
+
|
|
301
|
+
**Note:** For pre-release versions, npm uses hyphen notation (e.g., `"shakapacker": "9.3.0-beta.1"`).
|
|
302
|
+
|
|
303
|
+
### Step 3: Install Updates
|
|
304
|
+
|
|
305
|
+
Run both bundler and your package manager:
|
|
268
306
|
|
|
269
307
|
```bash
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
308
|
+
# Update Ruby gem
|
|
309
|
+
bundle update shakapacker
|
|
310
|
+
|
|
311
|
+
# Update npm package (choose one based on your package manager)
|
|
312
|
+
yarn install # if using Yarn
|
|
313
|
+
npm install # if using npm
|
|
314
|
+
pnpm install # if using pnpm
|
|
315
|
+
bun install # if using Bun
|
|
273
316
|
```
|
|
274
317
|
|
|
275
|
-
### Step
|
|
318
|
+
### Step 4: Update CSS Module Imports
|
|
276
319
|
|
|
277
320
|
#### For each CSS module import:
|
|
278
321
|
|
|
@@ -299,7 +342,7 @@ declare module "*.module.css" {
|
|
|
299
342
|
}
|
|
300
343
|
```
|
|
301
344
|
|
|
302
|
-
### Step
|
|
345
|
+
### Step 5: Handle Kebab-Case Class Names
|
|
303
346
|
|
|
304
347
|
v9 automatically converts kebab-case to camelCase with `exportLocalsConvention: 'camelCaseOnly'`:
|
|
305
348
|
|
|
@@ -340,7 +383,7 @@ const buttonClass = styles['my-button'];
|
|
|
340
383
|
|
|
341
384
|
**Note:** With `'camelCaseOnly'` (default) or `'dashesOnly'`, only one version is exported. If you need both the original and camelCase versions, you would need to use `'camelCase'` instead, but this requires `namedExport: false` (v8 behavior). See the [CSS Modules Export Mode documentation](./css-modules-export-mode.md) for details on reverting to v8 behavior.
|
|
342
385
|
|
|
343
|
-
### Step
|
|
386
|
+
### Step 6: Update Configuration Files
|
|
344
387
|
|
|
345
388
|
If you have `webpack_loader` in your configuration:
|
|
346
389
|
|
|
@@ -353,7 +396,7 @@ If you have `webpack_loader` in your configuration:
|
|
|
353
396
|
javascript_transpiler: "babel"
|
|
354
397
|
```
|
|
355
398
|
|
|
356
|
-
### Step
|
|
399
|
+
### Step 7: Run Tests
|
|
357
400
|
|
|
358
401
|
```bash
|
|
359
402
|
# Run your test suite
|
|
@@ -366,6 +409,45 @@ bin/shakapacker
|
|
|
366
409
|
bin/shakapacker-dev-server
|
|
367
410
|
```
|
|
368
411
|
|
|
412
|
+
## Version Format Differences
|
|
413
|
+
|
|
414
|
+
Shakapacker version numbers differ between the Ruby gem and npm package for pre-release versions:
|
|
415
|
+
|
|
416
|
+
| Version Type | Ruby Gem (Gemfile) | npm Package (package.json) |
|
|
417
|
+
| ------------ | ------------------ | -------------------------- |
|
|
418
|
+
| Stable | `"9.3.0"` | `"9.3.0"` |
|
|
419
|
+
| Pre-release | `"9.3.0.beta.1"` | `"9.3.0-beta.1"` |
|
|
420
|
+
|
|
421
|
+
**Examples:**
|
|
422
|
+
|
|
423
|
+
```ruby
|
|
424
|
+
# Gemfile - uses dots for pre-release versions
|
|
425
|
+
gem "shakapacker", "9.3.0" # stable
|
|
426
|
+
gem "shakapacker", "9.3.0.beta.1" # pre-release
|
|
427
|
+
```
|
|
428
|
+
|
|
429
|
+
Stable version in package.json:
|
|
430
|
+
|
|
431
|
+
```json
|
|
432
|
+
{
|
|
433
|
+
"dependencies": {
|
|
434
|
+
"shakapacker": "9.3.0"
|
|
435
|
+
}
|
|
436
|
+
}
|
|
437
|
+
```
|
|
438
|
+
|
|
439
|
+
Pre-release version in package.json:
|
|
440
|
+
|
|
441
|
+
```json
|
|
442
|
+
{
|
|
443
|
+
"dependencies": {
|
|
444
|
+
"shakapacker": "9.3.0-beta.1"
|
|
445
|
+
}
|
|
446
|
+
}
|
|
447
|
+
```
|
|
448
|
+
|
|
449
|
+
This is due to different versioning conventions between RubyGems (which uses dots) and npm (which follows semantic versioning with hyphens for pre-release identifiers).
|
|
450
|
+
|
|
369
451
|
## Troubleshooting
|
|
370
452
|
|
|
371
453
|
### CSS Classes Not Applying
|
data/eslint.config.js
CHANGED
|
@@ -14,11 +14,16 @@ module.exports = [
|
|
|
14
14
|
// Global ignores (replaces .eslintignore)
|
|
15
15
|
{
|
|
16
16
|
ignores: [
|
|
17
|
-
"lib/**",
|
|
18
|
-
"**/node_modules/**",
|
|
19
|
-
"vendor/**",
|
|
20
|
-
"spec/**",
|
|
21
|
-
"package
|
|
17
|
+
"lib/**", // Ruby files, not JavaScript
|
|
18
|
+
"**/node_modules/**", // Third-party dependencies
|
|
19
|
+
"vendor/**", // Vendored dependencies
|
|
20
|
+
"spec/**", // Ruby specs, not JavaScript
|
|
21
|
+
"package/**/*.js", // Generated/compiled JavaScript from TypeScript
|
|
22
|
+
"package/**/*.d.ts", // Generated TypeScript declaration files
|
|
23
|
+
// Temporarily ignore TypeScript files until technical debt is resolved
|
|
24
|
+
// See ESLINT_TECHNICAL_DEBT.md for tracking
|
|
25
|
+
// TODO: Remove this once ESLint issues are fixed (tracked in #723)
|
|
26
|
+
"package/**/*.ts"
|
|
22
27
|
]
|
|
23
28
|
},
|
|
24
29
|
|
|
@@ -52,7 +57,11 @@ module.exports = [
|
|
|
52
57
|
"import/no-extraneous-dependencies": "off",
|
|
53
58
|
// TypeScript handles extensions, not needed for JS imports
|
|
54
59
|
"import/extensions": "off",
|
|
55
|
-
indent: ["error", 2]
|
|
60
|
+
indent: ["error", 2],
|
|
61
|
+
// Allow for...of loops - modern JS syntax, won't pollute client code
|
|
62
|
+
"no-restricted-syntax": "off",
|
|
63
|
+
// Allow console statements - used for debugging/logging throughout
|
|
64
|
+
"no-console": "off"
|
|
56
65
|
},
|
|
57
66
|
settings: {
|
|
58
67
|
react: {
|
|
@@ -131,7 +140,110 @@ module.exports = [
|
|
|
131
140
|
// Strict: no 'any' types allowed - use 'unknown' or specific types instead
|
|
132
141
|
"@typescript-eslint/no-explicit-any": "error",
|
|
133
142
|
// Allow implicit return types - TypeScript can infer them
|
|
134
|
-
"@typescript-eslint/explicit-module-boundary-types": "off"
|
|
143
|
+
"@typescript-eslint/explicit-module-boundary-types": "off",
|
|
144
|
+
// Disable no-undef for TypeScript - TypeScript compiler handles this
|
|
145
|
+
// This prevents false positives for ambient types like NodeJS.ProcessEnv
|
|
146
|
+
"no-undef": "off"
|
|
147
|
+
}
|
|
148
|
+
},
|
|
149
|
+
|
|
150
|
+
// Temporary overrides for files with remaining errors
|
|
151
|
+
// See ESLINT_TECHNICAL_DEBT.md for detailed documentation
|
|
152
|
+
//
|
|
153
|
+
// These overrides suppress ~172 errors that require either:
|
|
154
|
+
// 1. Major type refactoring (any/unsafe-* rules)
|
|
155
|
+
// 2. Potential breaking changes (module system)
|
|
156
|
+
// 3. Significant code restructuring
|
|
157
|
+
//
|
|
158
|
+
// GitHub Issues tracking this technical debt:
|
|
159
|
+
// - #707: TypeScript: Refactor configExporter module for type safety
|
|
160
|
+
// - #708: Module System: Modernize to ES6 modules with codemod
|
|
161
|
+
// - #709: Code Style: Fix remaining ESLint style issues
|
|
162
|
+
{
|
|
163
|
+
// Consolidated override for package/config.ts and package/babel/preset.ts
|
|
164
|
+
// Combines rules from both previous override blocks to avoid duplication
|
|
165
|
+
files: ["package/babel/preset.ts", "package/config.ts"],
|
|
166
|
+
rules: {
|
|
167
|
+
// From first override block
|
|
168
|
+
"@typescript-eslint/no-require-imports": "off",
|
|
169
|
+
"@typescript-eslint/no-unused-vars": "off",
|
|
170
|
+
"@typescript-eslint/no-unsafe-call": "off",
|
|
171
|
+
"import/order": "off",
|
|
172
|
+
"import/newline-after-import": "off",
|
|
173
|
+
"import/first": "off",
|
|
174
|
+
// Additional rules that were in the second override for config.ts
|
|
175
|
+
"@typescript-eslint/no-unsafe-assignment": "off",
|
|
176
|
+
"@typescript-eslint/no-unsafe-member-access": "off",
|
|
177
|
+
"@typescript-eslint/no-unsafe-argument": "off",
|
|
178
|
+
"@typescript-eslint/no-explicit-any": "off",
|
|
179
|
+
"no-useless-escape": "off",
|
|
180
|
+
"no-continue": "off"
|
|
181
|
+
}
|
|
182
|
+
},
|
|
183
|
+
{
|
|
184
|
+
files: ["package/configExporter/**/*.ts"],
|
|
185
|
+
rules: {
|
|
186
|
+
"@typescript-eslint/no-explicit-any": "off",
|
|
187
|
+
"@typescript-eslint/no-unsafe-assignment": "off",
|
|
188
|
+
"@typescript-eslint/no-unsafe-member-access": "off",
|
|
189
|
+
"@typescript-eslint/no-unsafe-call": "off",
|
|
190
|
+
"@typescript-eslint/no-unsafe-return": "off",
|
|
191
|
+
"@typescript-eslint/no-unsafe-argument": "off",
|
|
192
|
+
"@typescript-eslint/no-unsafe-function-type": "off",
|
|
193
|
+
"@typescript-eslint/no-unused-vars": "off",
|
|
194
|
+
"@typescript-eslint/require-await": "off",
|
|
195
|
+
"no-await-in-loop": "off",
|
|
196
|
+
"import/prefer-default-export": "off",
|
|
197
|
+
"global-require": "off",
|
|
198
|
+
"no-underscore-dangle": "off"
|
|
199
|
+
}
|
|
200
|
+
},
|
|
201
|
+
{
|
|
202
|
+
// Remaining utils files (removed package/config.ts from this block)
|
|
203
|
+
files: [
|
|
204
|
+
"package/utils/inliningCss.ts",
|
|
205
|
+
"package/utils/errorCodes.ts",
|
|
206
|
+
"package/utils/errorHelpers.ts",
|
|
207
|
+
"package/utils/pathValidation.ts"
|
|
208
|
+
],
|
|
209
|
+
rules: {
|
|
210
|
+
"@typescript-eslint/no-unsafe-assignment": "off",
|
|
211
|
+
"@typescript-eslint/no-unsafe-member-access": "off",
|
|
212
|
+
"@typescript-eslint/no-unsafe-argument": "off",
|
|
213
|
+
"@typescript-eslint/no-explicit-any": "off",
|
|
214
|
+
"no-useless-escape": "off",
|
|
215
|
+
"no-continue": "off"
|
|
216
|
+
}
|
|
217
|
+
},
|
|
218
|
+
{
|
|
219
|
+
files: ["package/plugins/**/*.ts", "package/optimization/**/*.ts"],
|
|
220
|
+
rules: {
|
|
221
|
+
"@typescript-eslint/no-unsafe-assignment": "off",
|
|
222
|
+
"@typescript-eslint/no-unsafe-call": "off",
|
|
223
|
+
"@typescript-eslint/no-redundant-type-constituents": "off",
|
|
224
|
+
"import/prefer-default-export": "off"
|
|
225
|
+
}
|
|
226
|
+
},
|
|
227
|
+
{
|
|
228
|
+
files: [
|
|
229
|
+
"package/environments/**/*.ts",
|
|
230
|
+
"package/index.ts",
|
|
231
|
+
"package/rspack/index.ts",
|
|
232
|
+
"package/rules/**/*.ts",
|
|
233
|
+
"package/swc/index.ts",
|
|
234
|
+
"package/esbuild/index.ts",
|
|
235
|
+
"package/dev_server.ts",
|
|
236
|
+
"package/env.ts"
|
|
237
|
+
],
|
|
238
|
+
rules: {
|
|
239
|
+
"@typescript-eslint/no-unsafe-assignment": "off",
|
|
240
|
+
"@typescript-eslint/no-unsafe-call": "off",
|
|
241
|
+
"@typescript-eslint/no-unsafe-return": "off",
|
|
242
|
+
"@typescript-eslint/no-redundant-type-constituents": "off",
|
|
243
|
+
"@typescript-eslint/no-unused-vars": "off",
|
|
244
|
+
"@typescript-eslint/no-unsafe-function-type": "off",
|
|
245
|
+
"import/prefer-default-export": "off",
|
|
246
|
+
"no-underscore-dangle": "off"
|
|
135
247
|
}
|
|
136
248
|
},
|
|
137
249
|
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
require "yaml"
|
|
2
|
+
|
|
3
|
+
module Shakapacker
|
|
4
|
+
class BuildConfigLoader
|
|
5
|
+
attr_reader :config_file_path
|
|
6
|
+
|
|
7
|
+
def initialize(config_file_path = nil)
|
|
8
|
+
@config_file_path = config_file_path || File.join(Dir.pwd, "config", "shakapacker-builds.yml")
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def exists?
|
|
12
|
+
File.exist?(@config_file_path)
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def load_build(build_name)
|
|
16
|
+
unless exists?
|
|
17
|
+
raise ArgumentError, "Config file not found: #{@config_file_path}\n" \
|
|
18
|
+
"Run 'bin/shakapacker --init' to generate a sample config file."
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
config = load_config
|
|
22
|
+
fetch_build_or_raise(config, build_name)
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def resolve_build_config(build_name, default_bundler: "webpack")
|
|
26
|
+
config = load_config
|
|
27
|
+
build = fetch_build_or_raise(config, build_name)
|
|
28
|
+
|
|
29
|
+
# Resolve bundler with precedence: build.bundler > config.default_bundler > default_bundler
|
|
30
|
+
bundler = build["bundler"] || config["default_bundler"] || default_bundler
|
|
31
|
+
|
|
32
|
+
# Get environment variables
|
|
33
|
+
environment = build["environment"] || {}
|
|
34
|
+
|
|
35
|
+
# Get config file path if specified
|
|
36
|
+
config_file = build["config"]
|
|
37
|
+
if config_file
|
|
38
|
+
# Expand ${BUNDLER} variable
|
|
39
|
+
config_file = config_file.gsub("${BUNDLER}", bundler)
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
# Get bundler_env for --env flags
|
|
43
|
+
bundler_env = build["bundler_env"] || {}
|
|
44
|
+
|
|
45
|
+
# Get outputs
|
|
46
|
+
outputs = build["outputs"] || []
|
|
47
|
+
|
|
48
|
+
# Validate outputs
|
|
49
|
+
if outputs.empty?
|
|
50
|
+
raise ArgumentError, "Build '#{build_name}' has empty outputs array. " \
|
|
51
|
+
"Please specify at least one output type (client, server, or all)."
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
{
|
|
55
|
+
name: build_name,
|
|
56
|
+
description: build["description"],
|
|
57
|
+
bundler: bundler,
|
|
58
|
+
dev_server: build["dev_server"],
|
|
59
|
+
environment: environment,
|
|
60
|
+
bundler_env: bundler_env,
|
|
61
|
+
outputs: outputs,
|
|
62
|
+
config_file: config_file
|
|
63
|
+
}
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def uses_dev_server?(build_config)
|
|
67
|
+
# Check explicit dev_server flag first (preferred)
|
|
68
|
+
# Only return early if the value is explicitly set (not nil)
|
|
69
|
+
return build_config[:dev_server] unless build_config[:dev_server].nil?
|
|
70
|
+
|
|
71
|
+
# Fallback: check environment variables for backward compatibility
|
|
72
|
+
env = build_config[:environment]
|
|
73
|
+
return false unless env
|
|
74
|
+
|
|
75
|
+
# Handle both string "true" and boolean true from YAML
|
|
76
|
+
%w[WEBPACK_SERVE HMR].any? do |key|
|
|
77
|
+
value = env[key]
|
|
78
|
+
value.to_s.strip.casecmp("true").zero?
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
def list_builds
|
|
83
|
+
config = load_config
|
|
84
|
+
builds = config["builds"]
|
|
85
|
+
|
|
86
|
+
puts "\nAvailable builds in #{@config_file_path}:\n\n"
|
|
87
|
+
|
|
88
|
+
builds.each do |name, build|
|
|
89
|
+
bundler = build["bundler"] || config["default_bundler"] || "webpack (default)"
|
|
90
|
+
outputs = build["outputs"] ? build["outputs"].join(", ") : "missing (invalid)"
|
|
91
|
+
|
|
92
|
+
puts " #{name}"
|
|
93
|
+
puts " Description: #{build["description"]}" if build["description"]
|
|
94
|
+
puts " Bundler: #{bundler}"
|
|
95
|
+
puts " Outputs: #{outputs}"
|
|
96
|
+
puts ""
|
|
97
|
+
end
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
private
|
|
101
|
+
|
|
102
|
+
def fetch_build_or_raise(config, build_name)
|
|
103
|
+
build = config["builds"][build_name]
|
|
104
|
+
unless build
|
|
105
|
+
available = config["builds"].keys.join(", ")
|
|
106
|
+
raise ArgumentError, "Build '#{build_name}' not found in config file.\n" \
|
|
107
|
+
"Available builds: #{available}\n" \
|
|
108
|
+
"Use 'bin/shakapacker --list-builds' to see all available builds."
|
|
109
|
+
end
|
|
110
|
+
build
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
# Load YAML config file safely with Ruby version compatibility
|
|
114
|
+
# Ruby 3.1+ supports safe_load_file with aliases, older versions need safe_load
|
|
115
|
+
def load_config
|
|
116
|
+
begin
|
|
117
|
+
config = if YAML.respond_to?(:safe_load_file)
|
|
118
|
+
# Ruby 3.1+: Use safe_load_file with aliases enabled
|
|
119
|
+
YAML.safe_load_file(@config_file_path, aliases: true)
|
|
120
|
+
else
|
|
121
|
+
# Ruby 2.7-3.0: Use safe_load with aliases enabled
|
|
122
|
+
YAML.safe_load(
|
|
123
|
+
File.read(@config_file_path),
|
|
124
|
+
permitted_classes: [],
|
|
125
|
+
permitted_symbols: [],
|
|
126
|
+
aliases: true
|
|
127
|
+
)
|
|
128
|
+
end
|
|
129
|
+
rescue ArgumentError
|
|
130
|
+
# Fallback for older Psych versions without aliases support
|
|
131
|
+
config = YAML.safe_load(
|
|
132
|
+
File.read(@config_file_path),
|
|
133
|
+
permitted_classes: [],
|
|
134
|
+
permitted_symbols: []
|
|
135
|
+
)
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
unless config["builds"]&.is_a?(Hash)
|
|
139
|
+
raise ArgumentError, "Config file must contain a 'builds' object"
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
config
|
|
143
|
+
rescue Psych::SyntaxError => e
|
|
144
|
+
raise ArgumentError, "Invalid YAML in config file: #{e.message}"
|
|
145
|
+
end
|
|
146
|
+
end
|
|
147
|
+
end
|
|
@@ -8,12 +8,13 @@ class Shakapacker::Configuration
|
|
|
8
8
|
attr_accessor :installing
|
|
9
9
|
end
|
|
10
10
|
|
|
11
|
-
attr_reader :root_path, :config_path, :env
|
|
11
|
+
attr_reader :root_path, :config_path, :env, :bundler_override
|
|
12
12
|
|
|
13
|
-
def initialize(root_path:, config_path:, env:)
|
|
13
|
+
def initialize(root_path:, config_path:, env:, bundler_override: nil)
|
|
14
14
|
@root_path = root_path
|
|
15
15
|
@env = env
|
|
16
16
|
@config_path = config_path
|
|
17
|
+
@bundler_override = bundler_override
|
|
17
18
|
end
|
|
18
19
|
|
|
19
20
|
def dev_server
|
|
@@ -97,6 +98,9 @@ class Shakapacker::Configuration
|
|
|
97
98
|
end
|
|
98
99
|
|
|
99
100
|
def assets_bundler
|
|
101
|
+
# CLI --bundler flag takes highest precedence
|
|
102
|
+
return @bundler_override if @bundler_override
|
|
103
|
+
|
|
100
104
|
# Show deprecation warning if using old 'bundler' key
|
|
101
105
|
if data.has_key?(:bundler) && !data.has_key?(:assets_bundler)
|
|
102
106
|
$stderr.puts "⚠️ DEPRECATION WARNING: The 'bundler' configuration option is deprecated. Please use 'assets_bundler' instead to avoid confusion with Ruby's Bundler gem manager."
|
|
@@ -18,9 +18,71 @@ module Shakapacker
|
|
|
18
18
|
exit(0)
|
|
19
19
|
end
|
|
20
20
|
|
|
21
|
+
# Check for --build flag
|
|
22
|
+
build_index = argv.index("--build")
|
|
23
|
+
if build_index
|
|
24
|
+
build_name = argv[build_index + 1]
|
|
25
|
+
|
|
26
|
+
unless build_name
|
|
27
|
+
$stderr.puts "[Shakapacker] Error: --build requires a build name"
|
|
28
|
+
$stderr.puts "Usage: bin/shakapacker-dev-server --build <name>"
|
|
29
|
+
exit(1)
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
loader = BuildConfigLoader.new
|
|
33
|
+
|
|
34
|
+
unless loader.exists?
|
|
35
|
+
$stderr.puts "[Shakapacker] Config file not found: #{loader.config_file_path}"
|
|
36
|
+
$stderr.puts "Run 'bin/shakapacker --init' to create one"
|
|
37
|
+
exit(1)
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
begin
|
|
41
|
+
build_config = loader.resolve_build_config(build_name)
|
|
42
|
+
|
|
43
|
+
# Check if this build is meant for dev server
|
|
44
|
+
unless loader.uses_dev_server?(build_config)
|
|
45
|
+
$stderr.puts "[Shakapacker] Error: Build '#{build_name}' is not configured for dev server (dev_server: false)"
|
|
46
|
+
$stderr.puts "[Shakapacker] Use this command instead:"
|
|
47
|
+
$stderr.puts " bin/shakapacker --build #{build_name}"
|
|
48
|
+
exit(1)
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
# Remove --build and build name from argv
|
|
52
|
+
remaining_argv = argv.dup
|
|
53
|
+
remaining_argv.delete_at(build_index + 1)
|
|
54
|
+
remaining_argv.delete_at(build_index)
|
|
55
|
+
|
|
56
|
+
run_with_build_config(remaining_argv, build_config)
|
|
57
|
+
return
|
|
58
|
+
rescue ArgumentError => e
|
|
59
|
+
$stderr.puts "[Shakapacker] #{e.message}"
|
|
60
|
+
exit(1)
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
|
|
21
64
|
new(argv).run
|
|
22
65
|
end
|
|
23
66
|
|
|
67
|
+
def self.run_with_build_config(argv, build_config)
|
|
68
|
+
# Apply build config environment variables
|
|
69
|
+
build_config[:environment].each do |key, value|
|
|
70
|
+
ENV[key] = value.to_s
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
# Set SHAKAPACKER_ASSETS_BUNDLER so JS/TS config files use the correct bundler
|
|
74
|
+
# This ensures the bundler override (from --bundler or build config) is respected
|
|
75
|
+
ENV["SHAKAPACKER_ASSETS_BUNDLER"] = build_config[:bundler]
|
|
76
|
+
|
|
77
|
+
puts "[Shakapacker] Running dev server for build: #{build_config[:name]}"
|
|
78
|
+
puts "[Shakapacker] Description: #{build_config[:description]}" if build_config[:description]
|
|
79
|
+
puts "[Shakapacker] Bundler: #{build_config[:bundler]}"
|
|
80
|
+
puts "[Shakapacker] Config file: #{build_config[:config_file]}" if build_config[:config_file]
|
|
81
|
+
|
|
82
|
+
# Pass bundler override so Configuration.assets_bundler reflects the build
|
|
83
|
+
new(argv, build_config, build_config[:bundler]).run
|
|
84
|
+
end
|
|
85
|
+
|
|
24
86
|
def self.print_help
|
|
25
87
|
puts <<~HELP
|
|
26
88
|
================================================================================
|
|
@@ -33,6 +95,17 @@ module Shakapacker
|
|
|
33
95
|
-h, --help Show this help message
|
|
34
96
|
-v, --version Show Shakapacker version
|
|
35
97
|
--debug-shakapacker Enable Node.js debugging (--inspect-brk)
|
|
98
|
+
--build <name> Run a specific build configuration
|
|
99
|
+
|
|
100
|
+
Build configurations (config/shakapacker-builds.yml):
|
|
101
|
+
bin/shakapacker-dev-server --build dev-hmr # Run the 'dev-hmr' build
|
|
102
|
+
|
|
103
|
+
To manage builds:
|
|
104
|
+
bin/shakapacker --init # Create config file
|
|
105
|
+
bin/shakapacker --list-builds # List available builds
|
|
106
|
+
|
|
107
|
+
Note: You can also use bin/shakapacker --build with a build that has
|
|
108
|
+
WEBPACK_SERVE=true, and it will automatically use the dev server.
|
|
36
109
|
|
|
37
110
|
Examples:
|
|
38
111
|
bin/shakapacker-dev-server # Start dev server
|