shakapacker 9.3.0 → 9.3.1
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/.claude/commands/update-changelog.md +224 -0
- data/.github/actionlint-matcher.json +17 -0
- data/.github/workflows/dummy.yml +9 -0
- data/.github/workflows/generator.yml +13 -0
- data/.github/workflows/node.yml +83 -0
- data/.github/workflows/ruby.yml +11 -0
- data/.github/workflows/test-bundlers.yml +10 -0
- data/CHANGELOG.md +15 -8
- data/CLAUDE.md +6 -10
- data/CONTRIBUTING.md +57 -0
- data/Gemfile.lock +1 -1
- data/README.md +58 -33
- data/docs/api-reference.md +519 -0
- data/docs/configuration.md +11 -5
- data/docs/css-modules-export-mode.md +40 -6
- data/docs/transpiler-migration.md +12 -9
- data/docs/using_swc_loader.md +13 -10
- data/docs/v9_upgrade.md +11 -2
- data/eslint.config.fast.js +120 -8
- data/eslint.config.js +50 -31
- data/lib/install/config/shakapacker.yml +14 -1
- data/lib/shakapacker/configuration.rb +47 -4
- data/lib/shakapacker/dev_server_runner.rb +4 -0
- data/lib/shakapacker/doctor.rb +1 -1
- data/lib/shakapacker/version.rb +1 -1
- data/package/config.ts +2 -3
- data/package/configExporter/cli.ts +29 -24
- data/package/dev_server.ts +2 -2
- data/package/env.ts +1 -1
- data/package/environments/__type-tests__/rspack-plugin-compatibility.ts +6 -6
- data/package/environments/base.ts +2 -2
- data/package/environments/development.ts +3 -6
- data/package/environments/production.ts +2 -2
- data/package/environments/test.ts +2 -1
- data/package/esbuild/index.ts +0 -2
- data/package/index.d.ts +1 -0
- data/package/index.d.ts.template +1 -0
- data/package/index.ts +0 -1
- data/package/plugins/rspack.ts +3 -1
- data/package/plugins/webpack.ts +5 -3
- data/package/rspack/index.ts +3 -3
- data/package/rules/file.ts +1 -1
- data/package/rules/raw.ts +3 -1
- data/package/rules/rspack.ts +0 -2
- data/package/rules/sass.ts +0 -2
- data/package/rules/webpack.ts +0 -1
- data/package/swc/index.ts +0 -2
- data/package/types.ts +8 -11
- data/package/utils/debug.ts +0 -4
- data/package/utils/getStyleRule.ts +17 -9
- data/package/utils/helpers.ts +8 -3
- data/package/utils/pathValidation.ts +10 -11
- data/package/utils/requireOrError.ts +4 -3
- data/package/webpackDevServerConfig.ts +4 -4
- data/package.json +1 -1
- data/test/package/transpiler-defaults.test.js +42 -0
- metadata +5 -2
data/package/utils/debug.ts
CHANGED
|
@@ -18,24 +18,20 @@ const isDebugMode = (): boolean => {
|
|
|
18
18
|
|
|
19
19
|
const debug = (message: string, ...args: unknown[]): void => {
|
|
20
20
|
if (isDebugMode()) {
|
|
21
|
-
// eslint-disable-next-line no-console
|
|
22
21
|
console.log(`[Shakapacker] ${message}`, ...args)
|
|
23
22
|
}
|
|
24
23
|
}
|
|
25
24
|
|
|
26
25
|
const warn = (message: string, ...args: unknown[]): void => {
|
|
27
|
-
// eslint-disable-next-line no-console
|
|
28
26
|
console.warn(`[Shakapacker] WARNING: ${message}`, ...args)
|
|
29
27
|
}
|
|
30
28
|
|
|
31
29
|
const error = (message: string, ...args: unknown[]): void => {
|
|
32
|
-
// eslint-disable-next-line no-console
|
|
33
30
|
console.error(`[Shakapacker] ERROR: ${message}`, ...args)
|
|
34
31
|
}
|
|
35
32
|
|
|
36
33
|
const info = (message: string, ...args: unknown[]): void => {
|
|
37
34
|
if (isDebugMode()) {
|
|
38
|
-
// eslint-disable-next-line no-console
|
|
39
35
|
console.info(`[Shakapacker] INFO: ${message}`, ...args)
|
|
40
36
|
}
|
|
41
37
|
}
|
|
@@ -1,18 +1,19 @@
|
|
|
1
|
-
|
|
1
|
+
import type { Config } from "../types"
|
|
2
|
+
|
|
2
3
|
const { canProcess, moduleExists } = require("./helpers")
|
|
3
4
|
const { requireOrError } = require("./requireOrError")
|
|
4
|
-
const config = require("../config")
|
|
5
|
+
const config = require("../config") as Config
|
|
5
6
|
const inliningCss = require("./inliningCss")
|
|
6
7
|
|
|
7
8
|
interface StyleRule {
|
|
8
9
|
test: RegExp
|
|
9
|
-
use:
|
|
10
|
+
use: unknown[]
|
|
10
11
|
type?: string
|
|
11
12
|
}
|
|
12
13
|
|
|
13
14
|
const getStyleRule = (
|
|
14
15
|
test: RegExp,
|
|
15
|
-
preprocessors:
|
|
16
|
+
preprocessors: unknown[] = []
|
|
16
17
|
): StyleRule | null => {
|
|
17
18
|
if (moduleExists("css-loader")) {
|
|
18
19
|
const tryPostcss = () =>
|
|
@@ -28,6 +29,11 @@ const getStyleRule = (
|
|
|
28
29
|
? requireOrError("@rspack/core").CssExtractRspackPlugin.loader
|
|
29
30
|
: requireOrError("mini-css-extract-plugin").loader
|
|
30
31
|
|
|
32
|
+
// Determine CSS Modules export mode based on configuration
|
|
33
|
+
// 'named' (default): Use named exports with camelCaseOnly (v9 behavior)
|
|
34
|
+
// 'default': Use default exports with camelCase (v8 behavior)
|
|
35
|
+
const useNamedExports = config.css_modules_export_mode !== "default"
|
|
36
|
+
|
|
31
37
|
const use = [
|
|
32
38
|
inliningCss ? "style-loader" : extractionPlugin,
|
|
33
39
|
{
|
|
@@ -37,11 +43,13 @@ const getStyleRule = (
|
|
|
37
43
|
importLoaders: 2,
|
|
38
44
|
modules: {
|
|
39
45
|
auto: true,
|
|
40
|
-
// v9
|
|
41
|
-
|
|
42
|
-
//
|
|
43
|
-
namedExport:
|
|
44
|
-
exportLocalsConvention:
|
|
46
|
+
// Use named exports for v9 (default), or default exports for v8 compatibility
|
|
47
|
+
namedExport: useNamedExports,
|
|
48
|
+
// 'camelCaseOnly' with namedExport: true (v9 default)
|
|
49
|
+
// 'camelCase' with namedExport: false (v8 behavior - exports both original and camelCase)
|
|
50
|
+
exportLocalsConvention: useNamedExports
|
|
51
|
+
? "camelCaseOnly"
|
|
52
|
+
: "camelCase"
|
|
45
53
|
}
|
|
46
54
|
}
|
|
47
55
|
},
|
data/package/utils/helpers.ts
CHANGED
|
@@ -38,6 +38,11 @@ const loaderMatches = <T = unknown>(
|
|
|
38
38
|
loaderToCheck: string,
|
|
39
39
|
fn: () => T
|
|
40
40
|
): T | null => {
|
|
41
|
+
// If transpiler is set to 'none', skip all transpiler rules (for custom webpack configs)
|
|
42
|
+
if (configLoader === "none") {
|
|
43
|
+
return null
|
|
44
|
+
}
|
|
45
|
+
|
|
41
46
|
if (configLoader !== loaderToCheck) {
|
|
42
47
|
return null
|
|
43
48
|
}
|
|
@@ -60,13 +65,13 @@ const loaderMatches = <T = unknown>(
|
|
|
60
65
|
const packageFullVersion = (packageName: string): string => {
|
|
61
66
|
try {
|
|
62
67
|
const packageJsonPath = require.resolve(`${packageName}/package.json`)
|
|
63
|
-
// eslint-disable-next-line import/no-dynamic-require
|
|
68
|
+
// eslint-disable-next-line import/no-dynamic-require
|
|
64
69
|
const packageJson = require(packageJsonPath) as { version: string }
|
|
65
70
|
return packageJson.version
|
|
66
|
-
} catch (error:
|
|
71
|
+
} catch (error: unknown) {
|
|
67
72
|
// Re-throw the error with proper code to maintain compatibility with babel preset
|
|
68
73
|
// The preset expects MODULE_NOT_FOUND errors to handle missing core-js gracefully
|
|
69
|
-
if (error.code === "MODULE_NOT_FOUND") {
|
|
74
|
+
if ((error as NodeJS.ErrnoException).code === "MODULE_NOT_FOUND") {
|
|
70
75
|
throw error
|
|
71
76
|
}
|
|
72
77
|
// For other errors, warn and re-throw
|
|
@@ -138,17 +138,16 @@ export function validatePaths(paths: string[], basePath: string): string[] {
|
|
|
138
138
|
console.warn(
|
|
139
139
|
`[SHAKAPACKER WARNING] Skipping potentially unsafe path: ${userPath}`
|
|
140
140
|
)
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
)
|
|
141
|
+
} else {
|
|
142
|
+
try {
|
|
143
|
+
const safePath = safeResolvePath(basePath, userPath)
|
|
144
|
+
validatedPaths.push(safePath)
|
|
145
|
+
} catch (error) {
|
|
146
|
+
console.warn(
|
|
147
|
+
`[SHAKAPACKER WARNING] Invalid path configuration: ${userPath}\n` +
|
|
148
|
+
`Error: ${error instanceof Error ? error.message : String(error)}`
|
|
149
|
+
)
|
|
150
|
+
}
|
|
152
151
|
}
|
|
153
152
|
}
|
|
154
153
|
|
|
@@ -1,12 +1,13 @@
|
|
|
1
|
-
/* eslint global-require: 0 */
|
|
2
1
|
/* eslint import/no-dynamic-require: 0 */
|
|
3
|
-
|
|
2
|
+
import type { Config } from "../types"
|
|
3
|
+
|
|
4
|
+
const config = require("../config") as Config
|
|
4
5
|
|
|
5
6
|
interface ErrorWithCause extends Error {
|
|
6
7
|
cause?: unknown
|
|
7
8
|
}
|
|
8
9
|
|
|
9
|
-
const requireOrError = (moduleName: string):
|
|
10
|
+
const requireOrError = (moduleName: string): unknown => {
|
|
10
11
|
try {
|
|
11
12
|
return require(moduleName)
|
|
12
13
|
} catch (originalError: unknown) {
|
|
@@ -25,11 +25,11 @@ interface WebpackDevServerConfig {
|
|
|
25
25
|
[key: string]: unknown
|
|
26
26
|
}
|
|
27
27
|
client?: Record<string, unknown>
|
|
28
|
-
allowedHosts?:
|
|
28
|
+
allowedHosts?: string | string[]
|
|
29
29
|
bonjour?: boolean | Record<string, unknown>
|
|
30
30
|
compress?: boolean
|
|
31
31
|
headers?: Record<string, unknown> | (() => Record<string, unknown>)
|
|
32
|
-
host?:
|
|
32
|
+
host?: string
|
|
33
33
|
http2?: boolean
|
|
34
34
|
https?: boolean | Record<string, unknown>
|
|
35
35
|
ipc?: boolean | string
|
|
@@ -42,12 +42,12 @@ interface WebpackDevServerConfig {
|
|
|
42
42
|
| string[]
|
|
43
43
|
| Record<string, unknown>
|
|
44
44
|
| Record<string, unknown>[]
|
|
45
|
-
port?:
|
|
45
|
+
port?: string | number
|
|
46
46
|
proxy?: unknown
|
|
47
47
|
server?: string | boolean | Record<string, unknown>
|
|
48
48
|
setupExitSignals?: boolean
|
|
49
49
|
setupMiddlewares?: (middlewares: unknown[], devServer: unknown) => unknown[]
|
|
50
|
-
watchFiles?:
|
|
50
|
+
watchFiles?: unknown
|
|
51
51
|
webSocketServer?: string | boolean | Record<string, unknown>
|
|
52
52
|
[key: string]: unknown
|
|
53
53
|
}
|
data/package.json
CHANGED
|
@@ -124,4 +124,46 @@ describe("JavaScript Transpiler Defaults", () => {
|
|
|
124
124
|
expect(config.javascript_transpiler).toBe("swc")
|
|
125
125
|
})
|
|
126
126
|
})
|
|
127
|
+
|
|
128
|
+
describe("none transpiler option", () => {
|
|
129
|
+
it("accepts 'none' as a valid transpiler value", () => {
|
|
130
|
+
process.env.SHAKAPACKER_JAVASCRIPT_TRANSPILER = "none"
|
|
131
|
+
|
|
132
|
+
jest.resetModules()
|
|
133
|
+
const config = require("../../package/config")
|
|
134
|
+
|
|
135
|
+
expect(config.javascript_transpiler).toBe("none")
|
|
136
|
+
})
|
|
137
|
+
|
|
138
|
+
it("'none' option doesn't throw errors for missing transpiler packages", () => {
|
|
139
|
+
process.env.SHAKAPACKER_JAVASCRIPT_TRANSPILER = "none"
|
|
140
|
+
|
|
141
|
+
jest.resetModules()
|
|
142
|
+
|
|
143
|
+
// Should not throw even though there's no 'none-loader' package
|
|
144
|
+
expect(() => {
|
|
145
|
+
require("../../package/config")
|
|
146
|
+
}).not.toThrow()
|
|
147
|
+
})
|
|
148
|
+
|
|
149
|
+
it("'none' option results in no transpiler rules being applied", () => {
|
|
150
|
+
process.env.SHAKAPACKER_JAVASCRIPT_TRANSPILER = "none"
|
|
151
|
+
delete process.env.SHAKAPACKER_ASSETS_BUNDLER
|
|
152
|
+
|
|
153
|
+
jest.resetModules()
|
|
154
|
+
|
|
155
|
+
// Load the webpack rules - should not include babel, swc, or esbuild rules
|
|
156
|
+
const rules = require("../../package/rules/webpack")
|
|
157
|
+
|
|
158
|
+
// Verify no transpiler rules are present by checking rules array
|
|
159
|
+
// When transpiler is 'none', loaderMatches returns null for all transpilers
|
|
160
|
+
// which means babel.ts, swc.ts, and esbuild.ts all export null
|
|
161
|
+
// These get filtered out, so rules array should not contain them
|
|
162
|
+
const rulesJson = JSON.stringify(rules)
|
|
163
|
+
|
|
164
|
+
expect(rulesJson).not.toContain("babel-loader")
|
|
165
|
+
expect(rulesJson).not.toContain("swc-loader")
|
|
166
|
+
expect(rulesJson).not.toContain("esbuild-loader")
|
|
167
|
+
})
|
|
168
|
+
})
|
|
127
169
|
})
|
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.
|
|
4
|
+
version: 9.3.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- David Heinemeier Hansson
|
|
@@ -131,11 +131,13 @@ executables: []
|
|
|
131
131
|
extensions: []
|
|
132
132
|
extra_rdoc_files: []
|
|
133
133
|
files:
|
|
134
|
+
- ".claude/commands/update-changelog.md"
|
|
134
135
|
- ".github/FUNDING.yml"
|
|
135
136
|
- ".github/ISSUE_TEMPLATE/bug_report.md"
|
|
136
137
|
- ".github/ISSUE_TEMPLATE/feature_request.md"
|
|
137
138
|
- ".github/PULL_REQUEST_TEMPLATE.md"
|
|
138
139
|
- ".github/STATUS.md"
|
|
140
|
+
- ".github/actionlint-matcher.json"
|
|
139
141
|
- ".github/workflows/claude-code-review.yml"
|
|
140
142
|
- ".github/workflows/claude.yml"
|
|
141
143
|
- ".github/workflows/dummy.yml"
|
|
@@ -171,6 +173,7 @@ files:
|
|
|
171
173
|
- conductor.json
|
|
172
174
|
- config/README.md
|
|
173
175
|
- config/shakapacker.yml
|
|
176
|
+
- docs/api-reference.md
|
|
174
177
|
- docs/cdn_setup.md
|
|
175
178
|
- docs/common-upgrades.md
|
|
176
179
|
- docs/configuration.md
|
|
@@ -386,7 +389,7 @@ homepage: https://github.com/shakacode/shakapacker
|
|
|
386
389
|
licenses:
|
|
387
390
|
- MIT
|
|
388
391
|
metadata:
|
|
389
|
-
source_code_uri: https://github.com/shakacode/shakapacker/tree/v9.3.
|
|
392
|
+
source_code_uri: https://github.com/shakacode/shakapacker/tree/v9.3.1
|
|
390
393
|
rdoc_options: []
|
|
391
394
|
require_paths:
|
|
392
395
|
- lib
|