shakapacker 9.3.0.beta.5 → 9.3.0.beta.7
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/CHANGELOG.md +34 -3
- data/ESLINT_TECHNICAL_DEBT.md +8 -2
- data/Gemfile.lock +1 -1
- data/docs/early_hints.md +7 -21
- data/docs/{early_hints_new_api.md → early_hints_manual_api.md} +53 -299
- data/lib/shakapacker/doctor.rb +125 -68
- data/lib/shakapacker/runner.rb +12 -8
- data/lib/shakapacker/swc_migrator.rb +7 -7
- data/lib/shakapacker/version.rb +1 -1
- data/package/configExporter/cli.ts +256 -82
- data/package/configExporter/fileWriter.ts +18 -9
- data/package/configExporter/types.ts +6 -1
- data/package/configExporter/yamlSerializer.ts +36 -0
- data/package/plugins/webpack.ts +2 -1
- data/package/utils/errorCodes.ts +1 -0
- data/package/utils/errorHelpers.ts +16 -12
- data/package.json +2 -2
- data/test/configExporter/integration.test.js +8 -8
- data/test/package/configExporter.test.js +48 -3
- metadata +3 -4
- data/package-lock.json +0 -13047
|
@@ -147,6 +147,22 @@ export class YamlSerializer {
|
|
|
147
147
|
|
|
148
148
|
arr.forEach((item, index) => {
|
|
149
149
|
const itemPath = `${keyPath}[${index}]`
|
|
150
|
+
|
|
151
|
+
// Check if this is a plugin object and add its name as a comment
|
|
152
|
+
const pluginName = this.getConstructorName(item)
|
|
153
|
+
const isPlugin = pluginName && /(^|\.)plugins\[\d+\]/.test(itemPath)
|
|
154
|
+
const isEmpty =
|
|
155
|
+
typeof item === "object" &&
|
|
156
|
+
item !== null &&
|
|
157
|
+
!Array.isArray(item) &&
|
|
158
|
+
Object.keys(item).length === 0
|
|
159
|
+
|
|
160
|
+
// For non-empty plugins, add comment before the plugin
|
|
161
|
+
// For empty plugins, the name will be shown inline
|
|
162
|
+
if (isPlugin && !isEmpty) {
|
|
163
|
+
lines.push(`${itemIndent}# ${pluginName}`)
|
|
164
|
+
}
|
|
165
|
+
|
|
150
166
|
const serialized = this.serializeValue(item, indent + 4, itemPath)
|
|
151
167
|
|
|
152
168
|
// Add documentation for array items if available
|
|
@@ -200,7 +216,13 @@ export class YamlSerializer {
|
|
|
200
216
|
|
|
201
217
|
private serializeObject(obj: any, indent: number, keyPath: string): string {
|
|
202
218
|
const keys = Object.keys(obj)
|
|
219
|
+
const constructorName = this.getConstructorName(obj)
|
|
220
|
+
|
|
221
|
+
// For empty objects, show constructor name if available
|
|
203
222
|
if (keys.length === 0) {
|
|
223
|
+
if (constructorName) {
|
|
224
|
+
return `{} # ${constructorName}`
|
|
225
|
+
}
|
|
204
226
|
return "{}"
|
|
205
227
|
}
|
|
206
228
|
|
|
@@ -277,4 +299,18 @@ export class YamlSerializer {
|
|
|
277
299
|
|
|
278
300
|
return "./" + rel
|
|
279
301
|
}
|
|
302
|
+
|
|
303
|
+
/**
|
|
304
|
+
* Extracts the constructor name from an object
|
|
305
|
+
* Returns null for plain objects (Object constructor)
|
|
306
|
+
*/
|
|
307
|
+
private getConstructorName(obj: any): string | null {
|
|
308
|
+
if (!obj || typeof obj !== "object") return null
|
|
309
|
+
if (Array.isArray(obj)) return null
|
|
310
|
+
|
|
311
|
+
const constructorName = obj.constructor?.name
|
|
312
|
+
if (!constructorName || constructorName === "Object") return null
|
|
313
|
+
|
|
314
|
+
return constructorName
|
|
315
|
+
}
|
|
280
316
|
}
|
data/package/plugins/webpack.ts
CHANGED
|
@@ -3,7 +3,7 @@ const { requireOrError } = require("../utils/requireOrError")
|
|
|
3
3
|
const WebpackAssetsManifest = requireOrError("webpack-assets-manifest")
|
|
4
4
|
const webpack = requireOrError("webpack")
|
|
5
5
|
const config = require("../config")
|
|
6
|
-
const { isProduction } = require("../env")
|
|
6
|
+
const { isProduction, isDevelopment } = require("../env")
|
|
7
7
|
const { moduleExists } = require("../utils/helpers")
|
|
8
8
|
|
|
9
9
|
const getPlugins = (): unknown[] => {
|
|
@@ -15,6 +15,7 @@ const getPlugins = (): unknown[] => {
|
|
|
15
15
|
const plugins = [
|
|
16
16
|
new webpack.EnvironmentPlugin(process.env),
|
|
17
17
|
new WebpackAssetsManifestConstructor({
|
|
18
|
+
merge: isDevelopment,
|
|
18
19
|
entrypoints: true,
|
|
19
20
|
writeToDisk: true,
|
|
20
21
|
output: config.manifestPath,
|
data/package/utils/errorCodes.ts
CHANGED
|
@@ -36,12 +36,14 @@ export function createFileOperationError(
|
|
|
36
36
|
filePath: string,
|
|
37
37
|
details?: string
|
|
38
38
|
): ShakapackerError {
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
39
|
+
let errorCode: ErrorCode
|
|
40
|
+
if (operation === "read") {
|
|
41
|
+
errorCode = ErrorCode.FILE_READ_ERROR
|
|
42
|
+
} else if (operation === "write") {
|
|
43
|
+
errorCode = ErrorCode.FILE_WRITE_ERROR
|
|
44
|
+
} else {
|
|
45
|
+
errorCode = ErrorCode.FILE_NOT_FOUND
|
|
46
|
+
}
|
|
45
47
|
|
|
46
48
|
return new ShakapackerError(errorCode, {
|
|
47
49
|
path: filePath,
|
|
@@ -60,12 +62,14 @@ export function createFileOperationErrorLegacy(
|
|
|
60
62
|
): Error {
|
|
61
63
|
const baseMessage = `Failed to ${operation} file at path '${filePath}'`
|
|
62
64
|
const errorDetails = details ? ` - ${details}` : ""
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
65
|
+
let suggestion: string
|
|
66
|
+
if (operation === "read") {
|
|
67
|
+
suggestion = " (check if file exists and permissions are correct)"
|
|
68
|
+
} else if (operation === "write") {
|
|
69
|
+
suggestion = " (check write permissions and disk space)"
|
|
70
|
+
} else {
|
|
71
|
+
suggestion = " (check permissions)"
|
|
72
|
+
}
|
|
69
73
|
return new Error(`${baseMessage}${errorDetails}${suggestion}`)
|
|
70
74
|
}
|
|
71
75
|
|
data/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "shakapacker",
|
|
3
|
-
"version": "9.3.0-beta.
|
|
3
|
+
"version": "9.3.0-beta.7",
|
|
4
4
|
"description": "Use webpack to manage app-like JavaScript modules in Rails",
|
|
5
5
|
"homepage": "https://github.com/shakacode/shakapacker",
|
|
6
6
|
"bugs": {
|
|
@@ -32,7 +32,7 @@
|
|
|
32
32
|
],
|
|
33
33
|
"scripts": {
|
|
34
34
|
"clean:ts": "find package -name '*.ts' -not -name '*.d.ts' | sed 's/\\.ts$//' | xargs -I {} rm -f {}.js {}.d.ts {}.d.ts.map {}.js.map",
|
|
35
|
-
"build": "tsc && cp package/index.d.ts.template package/index.d.ts && node scripts/remove-use-strict.js && yarn prettier --write 'package/**/*.js'",
|
|
35
|
+
"build": "tsc && cp package/index.d.ts.template package/index.d.ts && node scripts/remove-use-strict.js && yarn prettier --write 'package/**/*.js' 'package/**/*.ts'",
|
|
36
36
|
"build:types": "tsc",
|
|
37
37
|
"knip": "knip",
|
|
38
38
|
"knip:production": "knip --production",
|
|
@@ -127,21 +127,21 @@ builds:
|
|
|
127
127
|
|
|
128
128
|
// Should have 3 files (one per build)
|
|
129
129
|
expect(files).toHaveLength(3)
|
|
130
|
-
expect(files).toContain("webpack-dev-hmr-client.
|
|
131
|
-
expect(files).toContain("webpack-dev-client.
|
|
132
|
-
expect(files).toContain("webpack-prod-client.
|
|
130
|
+
expect(files).toContain("webpack-dev-hmr-client.yml")
|
|
131
|
+
expect(files).toContain("webpack-dev-client.yml")
|
|
132
|
+
expect(files).toContain("webpack-prod-client.yml")
|
|
133
133
|
|
|
134
134
|
// Verify files have different content (proving environment isolation)
|
|
135
135
|
const devHmrContent = require("fs").readFileSync(
|
|
136
|
-
join(outputDir, "webpack-dev-hmr-client.
|
|
136
|
+
join(outputDir, "webpack-dev-hmr-client.yml"),
|
|
137
137
|
"utf8"
|
|
138
138
|
)
|
|
139
139
|
const devContent = require("fs").readFileSync(
|
|
140
|
-
join(outputDir, "webpack-dev-client.
|
|
140
|
+
join(outputDir, "webpack-dev-client.yml"),
|
|
141
141
|
"utf8"
|
|
142
142
|
)
|
|
143
143
|
const prodContent = require("fs").readFileSync(
|
|
144
|
-
join(outputDir, "webpack-prod-client.
|
|
144
|
+
join(outputDir, "webpack-prod-client.yml"),
|
|
145
145
|
"utf8"
|
|
146
146
|
)
|
|
147
147
|
|
|
@@ -195,8 +195,8 @@ builds:
|
|
|
195
195
|
// Verify files
|
|
196
196
|
expect(existsSync(outputDir)).toBe(true)
|
|
197
197
|
const files = readdirSync(outputDir)
|
|
198
|
-
expect(files).toContain("webpack-custom-dev-client.
|
|
199
|
-
expect(files).toContain("webpack-custom-prod-client.
|
|
198
|
+
expect(files).toContain("webpack-custom-dev-client.yml")
|
|
199
|
+
expect(files).toContain("webpack-custom-prod-client.yml")
|
|
200
200
|
})
|
|
201
201
|
|
|
202
202
|
it("should use fallback builds when no config file exists", () => {
|
|
@@ -23,7 +23,7 @@ describe("configExporter", () => {
|
|
|
23
23
|
"client",
|
|
24
24
|
"yaml"
|
|
25
25
|
)
|
|
26
|
-
expect(filename).toBe("webpack-development-client.
|
|
26
|
+
expect(filename).toBe("webpack-development-client.yml")
|
|
27
27
|
})
|
|
28
28
|
|
|
29
29
|
test("generates correct filename for server config", () => {
|
|
@@ -34,7 +34,7 @@ describe("configExporter", () => {
|
|
|
34
34
|
"server",
|
|
35
35
|
"yaml"
|
|
36
36
|
)
|
|
37
|
-
expect(filename).toBe("webpack-production-server.
|
|
37
|
+
expect(filename).toBe("webpack-production-server.yml")
|
|
38
38
|
})
|
|
39
39
|
|
|
40
40
|
test("generates correct filename for client-hmr config", () => {
|
|
@@ -45,7 +45,7 @@ describe("configExporter", () => {
|
|
|
45
45
|
"client-hmr",
|
|
46
46
|
"yaml"
|
|
47
47
|
)
|
|
48
|
-
expect(filename).toBe("webpack-development-client-hmr.
|
|
48
|
+
expect(filename).toBe("webpack-development-client-hmr.yml")
|
|
49
49
|
})
|
|
50
50
|
|
|
51
51
|
test("generates correct filename for json format", () => {
|
|
@@ -58,6 +58,51 @@ describe("configExporter", () => {
|
|
|
58
58
|
)
|
|
59
59
|
expect(filename).toBe("rspack-production-client.json")
|
|
60
60
|
})
|
|
61
|
+
|
|
62
|
+
test("generates correct filename for custom output name client-modern", () => {
|
|
63
|
+
const { FileWriter } = require("../../package/configExporter/fileWriter")
|
|
64
|
+
const filename = FileWriter.generateFilename(
|
|
65
|
+
"webpack",
|
|
66
|
+
"development",
|
|
67
|
+
"client-modern",
|
|
68
|
+
"yaml"
|
|
69
|
+
)
|
|
70
|
+
expect(filename).toBe("webpack-development-client-modern.yml")
|
|
71
|
+
})
|
|
72
|
+
|
|
73
|
+
test("generates correct filename for custom output name client-legacy", () => {
|
|
74
|
+
const { FileWriter } = require("../../package/configExporter/fileWriter")
|
|
75
|
+
const filename = FileWriter.generateFilename(
|
|
76
|
+
"webpack",
|
|
77
|
+
"production",
|
|
78
|
+
"client-legacy",
|
|
79
|
+
"yaml"
|
|
80
|
+
)
|
|
81
|
+
expect(filename).toBe("webpack-production-client-legacy.yml")
|
|
82
|
+
})
|
|
83
|
+
|
|
84
|
+
test("generates correct filename for custom output name server-bundle", () => {
|
|
85
|
+
const { FileWriter } = require("../../package/configExporter/fileWriter")
|
|
86
|
+
const filename = FileWriter.generateFilename(
|
|
87
|
+
"rspack",
|
|
88
|
+
"development",
|
|
89
|
+
"server-bundle",
|
|
90
|
+
"yaml"
|
|
91
|
+
)
|
|
92
|
+
expect(filename).toBe("rspack-development-server-bundle.yml")
|
|
93
|
+
})
|
|
94
|
+
|
|
95
|
+
test("generates correct filename with buildName override", () => {
|
|
96
|
+
const { FileWriter } = require("../../package/configExporter/fileWriter")
|
|
97
|
+
const filename = FileWriter.generateFilename(
|
|
98
|
+
"webpack",
|
|
99
|
+
"development",
|
|
100
|
+
"client-modern",
|
|
101
|
+
"yaml",
|
|
102
|
+
"dev-hmr"
|
|
103
|
+
)
|
|
104
|
+
expect(filename).toBe("webpack-dev-hmr-client-modern.yml")
|
|
105
|
+
})
|
|
61
106
|
})
|
|
62
107
|
|
|
63
108
|
describe("environment variable preservation in runDoctorMode", () => {
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: shakapacker
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 9.3.0.beta.
|
|
4
|
+
version: 9.3.0.beta.7
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- David Heinemeier Hansson
|
|
@@ -181,7 +181,7 @@ files:
|
|
|
181
181
|
- docs/deployment.md
|
|
182
182
|
- docs/developing_shakapacker.md
|
|
183
183
|
- docs/early_hints.md
|
|
184
|
-
- docs/
|
|
184
|
+
- docs/early_hints_manual_api.md
|
|
185
185
|
- docs/feature_testing.md
|
|
186
186
|
- docs/optional-peer-dependencies.md
|
|
187
187
|
- docs/peer-dependencies.md
|
|
@@ -273,7 +273,6 @@ files:
|
|
|
273
273
|
- lib/tasks/shakapacker/switch_bundler.rake
|
|
274
274
|
- lib/tasks/shakapacker/verify_config.rake
|
|
275
275
|
- lib/tasks/shakapacker/verify_install.rake
|
|
276
|
-
- package-lock.json
|
|
277
276
|
- package.json
|
|
278
277
|
- package/.npmignore
|
|
279
278
|
- package/babel/preset.ts
|
|
@@ -385,7 +384,7 @@ homepage: https://github.com/shakacode/shakapacker
|
|
|
385
384
|
licenses:
|
|
386
385
|
- MIT
|
|
387
386
|
metadata:
|
|
388
|
-
source_code_uri: https://github.com/shakacode/shakapacker/tree/v9.3.0.beta.
|
|
387
|
+
source_code_uri: https://github.com/shakacode/shakapacker/tree/v9.3.0.beta.7
|
|
389
388
|
rdoc_options: []
|
|
390
389
|
require_paths:
|
|
391
390
|
- lib
|