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.
@@ -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
  }
@@ -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,
@@ -165,6 +165,7 @@ export const ErrorMessages: Record<ErrorCode, string> = {
165
165
  */
166
166
  export class ShakapackerError extends Error {
167
167
  public readonly code: ErrorCode
168
+
168
169
  public readonly details?: Record<string, any>
169
170
 
170
171
  constructor(
@@ -36,12 +36,14 @@ export function createFileOperationError(
36
36
  filePath: string,
37
37
  details?: string
38
38
  ): ShakapackerError {
39
- const errorCode =
40
- operation === "read"
41
- ? ErrorCode.FILE_READ_ERROR
42
- : operation === "write"
43
- ? ErrorCode.FILE_WRITE_ERROR
44
- : ErrorCode.FILE_NOT_FOUND
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
- const suggestion =
64
- operation === "read"
65
- ? " (check if file exists and permissions are correct)"
66
- : operation === "write"
67
- ? " (check write permissions and disk space)"
68
- : " (check permissions)"
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.5",
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.yaml")
131
- expect(files).toContain("webpack-dev-client.yaml")
132
- expect(files).toContain("webpack-prod-client.yaml")
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.yaml"),
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.yaml"),
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.yaml"),
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.yaml")
199
- expect(files).toContain("webpack-custom-prod-client.yaml")
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.yaml")
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.yaml")
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.yaml")
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.5
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/early_hints_new_api.md
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.5
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