shakapacker 9.0.0.beta.3 → 9.0.0.beta.5

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.
Files changed (63) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/dummy.yml +4 -0
  3. data/.github/workflows/generator.yml +7 -0
  4. data/.github/workflows/node.yml +22 -0
  5. data/.github/workflows/ruby.yml +11 -0
  6. data/.github/workflows/test-bundlers.yml +18 -0
  7. data/.gitignore +20 -0
  8. data/.yalcignore +26 -0
  9. data/CHANGELOG.md +58 -19
  10. data/Gemfile.lock +1 -1
  11. data/README.md +3 -1
  12. data/docs/peer-dependencies.md +23 -3
  13. data/docs/transpiler-performance.md +179 -0
  14. data/docs/typescript.md +99 -0
  15. data/docs/v9_upgrade.md +58 -2
  16. data/lib/install/config/shakapacker.yml +4 -2
  17. data/lib/install/package.json +8 -0
  18. data/lib/install/template.rb +128 -51
  19. data/lib/shakapacker/configuration.rb +58 -1
  20. data/lib/shakapacker/doctor.rb +752 -0
  21. data/lib/shakapacker/swc_migrator.rb +292 -0
  22. data/lib/shakapacker/version.rb +1 -1
  23. data/lib/shakapacker.rb +1 -0
  24. data/lib/tasks/shakapacker/doctor.rake +8 -0
  25. data/lib/tasks/shakapacker/migrate_to_swc.rake +13 -0
  26. data/lib/tasks/shakapacker.rake +1 -0
  27. data/package/config.ts +162 -0
  28. data/package/{dev_server.js → dev_server.ts} +8 -5
  29. data/package/env.ts +67 -0
  30. data/package/environments/base.js +21 -31
  31. data/package/environments/base.ts +137 -0
  32. data/package/index.d.ts +3 -150
  33. data/package/{index.js → index.ts} +17 -8
  34. data/package/loaders.d.ts +27 -0
  35. data/package/types.ts +108 -0
  36. data/package/utils/configPath.ts +6 -0
  37. data/package/utils/{debug.js → debug.ts} +7 -7
  38. data/package/utils/defaultConfigPath.ts +4 -0
  39. data/package/utils/errorHelpers.ts +77 -0
  40. data/package/utils/{getStyleRule.js → getStyleRule.ts} +17 -20
  41. data/package/utils/helpers.ts +85 -0
  42. data/package/utils/{inliningCss.js → inliningCss.ts} +3 -3
  43. data/package/utils/{requireOrError.js → requireOrError.ts} +2 -2
  44. data/package/utils/snakeToCamelCase.ts +5 -0
  45. data/package/utils/typeGuards.ts +228 -0
  46. data/package/utils/{validateDependencies.js → validateDependencies.ts} +4 -4
  47. data/package/webpack-types.d.ts +32 -0
  48. data/package/webpackDevServerConfig.ts +117 -0
  49. data/package.json +6 -2
  50. data/test/package/rules/babel.test.js +16 -0
  51. data/test/typescript/build.test.js +117 -0
  52. data/tsconfig.json +39 -0
  53. data/yarn.lock +5 -5
  54. metadata +32 -18
  55. data/package/config.js +0 -80
  56. data/package/env.js +0 -48
  57. data/package/utils/configPath.js +0 -4
  58. data/package/utils/defaultConfigPath.js +0 -2
  59. data/package/utils/helpers.js +0 -62
  60. data/package/utils/snakeToCamelCase.js +0 -5
  61. data/package/utils/validateCssModulesConfig.js +0 -91
  62. data/package/webpackDevServerConfig.js +0 -73
  63. data/package-lock.json +0 -11966
@@ -11,6 +11,7 @@ jest.mock("../../../package/config", () => {
11
11
  const original = jest.requireActual("../../../package/config")
12
12
  return {
13
13
  ...original,
14
+ javascript_transpiler: "babel", // Force babel for this test
14
15
  additional_paths: [...original.additional_paths, "node_modules/included"]
15
16
  }
16
17
  })
@@ -32,6 +33,21 @@ const createWebpackConfig = (file, use) => ({
32
33
  })
33
34
 
34
35
  describe("babel", () => {
36
+ // Mock validateBabelDependencies to avoid actual dependency checking in tests
37
+ beforeAll(() => {
38
+ jest.mock("../../../package/utils/helpers", () => {
39
+ const original = jest.requireActual("../../../package/utils/helpers")
40
+ return {
41
+ ...original,
42
+ validateBabelDependencies: jest.fn() // Mock to do nothing
43
+ }
44
+ })
45
+ })
46
+
47
+ afterAll(() => {
48
+ jest.unmock("../../../package/utils/helpers")
49
+ })
50
+
35
51
  test("process source path", async () => {
36
52
  const normalPath = `${pathToAppJavascript}/a.js`
37
53
  const [tracked, loader] = createTrackLoader()
@@ -0,0 +1,117 @@
1
+ /* eslint-env jest */
2
+ const { execSync } = require("child_process")
3
+ const { existsSync, readFileSync } = require("fs")
4
+ const { join } = require("path")
5
+
6
+ describe("typescript build", () => {
7
+ const rootPath = join(__dirname, "..", "..")
8
+
9
+ describe("typescript compilation", () => {
10
+ it("should compile TypeScript files without errors", () => {
11
+ expect(() => {
12
+ execSync("npx tsc --noEmit", { cwd: rootPath, stdio: "pipe" })
13
+ }).not.toThrow()
14
+ })
15
+
16
+ it("should generate JavaScript files from TypeScript", () => {
17
+ // Check that key TypeScript files compile to JavaScript
18
+ const tsFiles = ["config", "env", "index", "dev_server"]
19
+
20
+ tsFiles.forEach((file) => {
21
+ const jsPath = join(rootPath, "package", `${file}.js`)
22
+ const tsPath = join(rootPath, "package", `${file}.ts`)
23
+
24
+ expect(existsSync(tsPath)).toBe(true)
25
+ expect(existsSync(jsPath)).toBe(true)
26
+
27
+ // Verify JS file is newer than TS file (has been compiled)
28
+ const jsContent = readFileSync(jsPath, "utf8")
29
+ expect(jsContent).toContain("use strict")
30
+ })
31
+ })
32
+
33
+ it("should generate type definition files", () => {
34
+ const dtsFiles = ["config", "env", "index", "types", "dev_server"]
35
+
36
+ dtsFiles.forEach((file) => {
37
+ const dtsPath = join(rootPath, "package", `${file}.d.ts`)
38
+ expect(existsSync(dtsPath)).toBe(true)
39
+ })
40
+ })
41
+ })
42
+
43
+ describe("commonJS compatibility", () => {
44
+ it("should export modules using CommonJS format", () => {
45
+ const config = require("../../package/config")
46
+ const env = require("../../package/env")
47
+ const helpers = require("../../package/utils/helpers")
48
+
49
+ expect(config).toBeDefined()
50
+ expect(env.railsEnv).toBeDefined()
51
+ expect(helpers.moduleExists).toBeDefined()
52
+ })
53
+
54
+ it("should maintain backward compatibility", () => {
55
+ const index = require("../../package/index")
56
+
57
+ // Check all expected exports are present
58
+ expect(index.config).toBeDefined()
59
+ expect(index.env).toBeDefined()
60
+ expect(index.generateWebpackConfig).toBeInstanceOf(Function)
61
+ expect(index.moduleExists).toBeInstanceOf(Function)
62
+ expect(index.canProcess).toBeInstanceOf(Function)
63
+ })
64
+ })
65
+
66
+ describe("type guards", () => {
67
+ it("should have runtime type validation functions", () => {
68
+ const typeGuards = require("../../package/utils/typeGuards")
69
+
70
+ expect(typeGuards.isValidConfig).toBeInstanceOf(Function)
71
+ expect(typeGuards.isValidDevServerConfig).toBeInstanceOf(Function)
72
+ expect(typeGuards.isValidYamlConfig).toBeInstanceOf(Function)
73
+ expect(typeGuards.isPartialConfig).toBeInstanceOf(Function)
74
+ })
75
+
76
+ it("should validate config objects correctly", () => {
77
+ const { isPartialConfig } = require("../../package/utils/typeGuards")
78
+
79
+ const validPartial = {
80
+ source_path: "app/javascript",
81
+ nested_entries: true
82
+ }
83
+
84
+ const invalidPartial = {
85
+ source_path: 123, // Should be string
86
+ nested_entries: "yes" // Should be boolean
87
+ }
88
+
89
+ expect(isPartialConfig(validPartial)).toBe(true)
90
+ expect(isPartialConfig(invalidPartial)).toBe(false)
91
+ })
92
+ })
93
+
94
+ describe("error helpers", () => {
95
+ it("should have error handling utilities", () => {
96
+ const errorHelpers = require("../../package/utils/errorHelpers")
97
+
98
+ expect(errorHelpers.isFileNotFoundError).toBeInstanceOf(Function)
99
+ expect(errorHelpers.isModuleNotFoundError).toBeInstanceOf(Function)
100
+ expect(errorHelpers.getErrorMessage).toBeInstanceOf(Function)
101
+ })
102
+
103
+ it("should correctly identify ENOENT errors", () => {
104
+ const {
105
+ isFileNotFoundError
106
+ } = require("../../package/utils/errorHelpers")
107
+
108
+ const enoentError = new Error("File not found")
109
+ enoentError.code = "ENOENT"
110
+
111
+ const otherError = new Error("Other error")
112
+
113
+ expect(isFileNotFoundError(enoentError)).toBe(true)
114
+ expect(isFileNotFoundError(otherError)).toBe(false)
115
+ })
116
+ })
117
+ })
data/tsconfig.json ADDED
@@ -0,0 +1,39 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2020",
4
+ "module": "commonjs",
5
+ "lib": ["ES2020"],
6
+ "typeRoots": ["./node_modules/@types", "node_modules/@types", "../node_modules/@types"],
7
+ "declaration": true,
8
+ "declarationMap": true,
9
+ "outDir": "./package",
10
+ "rootDir": "./package",
11
+ "strict": true,
12
+ "esModuleInterop": true,
13
+ "skipLibCheck": true,
14
+ "forceConsistentCasingInFileNames": true,
15
+ "resolveJsonModule": true,
16
+ "moduleResolution": "node",
17
+ "allowJs": true,
18
+ "checkJs": false,
19
+ "noImplicitAny": true,
20
+ "strictNullChecks": true,
21
+ "strictFunctionTypes": true,
22
+ "strictBindCallApply": true,
23
+ "strictPropertyInitialization": false,
24
+ "noImplicitThis": true,
25
+ "alwaysStrict": false,
26
+ "allowSyntheticDefaultImports": true,
27
+ "preserveConstEnums": true,
28
+ "isolatedModules": true,
29
+ "removeComments": false
30
+ },
31
+ "include": [
32
+ "package/**/*.ts"
33
+ ],
34
+ "exclude": [
35
+ "node_modules",
36
+ "package/**/*.test.ts",
37
+ "package/**/*.spec.ts"
38
+ ]
39
+ }
data/yarn.lock CHANGED
@@ -1042,7 +1042,7 @@
1042
1042
 
1043
1043
  "@types/eslint-scope@^3.7.3", "@types/eslint-scope@^3.7.7":
1044
1044
  version "3.7.7"
1045
- resolved "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.7.tgz"
1045
+ resolved "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.7.tgz#3108bd5f18b0cdb277c867b3dd449c9ed7079ac5"
1046
1046
  integrity sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg==
1047
1047
  dependencies:
1048
1048
  "@types/eslint" "*"
@@ -1389,7 +1389,7 @@
1389
1389
 
1390
1390
  "@webassemblyjs/wasm-edit@^1.12.1", "@webassemblyjs/wasm-edit@^1.14.1":
1391
1391
  version "1.14.1"
1392
- resolved "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.14.1.tgz"
1392
+ resolved "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.14.1.tgz#ac6689f502219b59198ddec42dcd496b1004d597"
1393
1393
  integrity sha512-RNJUIQH/J8iA/1NzlE4N7KtyZNHi3w7at7hDjvRNm5rcUXa00z1vRz3glZoULfJ5mpvYhLybmVcwcjGrC1pRrQ==
1394
1394
  dependencies:
1395
1395
  "@webassemblyjs/ast" "1.14.1"
@@ -5629,7 +5629,7 @@ tapable@^2.1.1, tapable@^2.2.0, tapable@^2.2.1:
5629
5629
 
5630
5630
  terser-webpack-plugin@^5.3.10, terser-webpack-plugin@^5.3.11:
5631
5631
  version "5.3.14"
5632
- resolved "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.14.tgz"
5632
+ resolved "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.14.tgz#9031d48e57ab27567f02ace85c7d690db66c3e06"
5633
5633
  integrity sha512-vkZjpUjb6OMS7dhV+tILUW6BhpDR7P2L/aQSAv+Uwk+m8KATX9EccViHTJR2qDtACKPIYndLGCyl3FMo+r2LMw==
5634
5634
  dependencies:
5635
5635
  "@jridgewell/trace-mapping" "^0.3.25"
@@ -5997,7 +5997,7 @@ webpack-merge@*:
5997
5997
 
5998
5998
  webpack-merge@^5.8.0:
5999
5999
  version "5.10.0"
6000
- resolved "https://registry.npmjs.org/webpack-merge/-/webpack-merge-5.10.0.tgz"
6000
+ resolved "https://registry.npmjs.org/webpack-merge/-/webpack-merge-5.10.0.tgz#a3ad5d773241e9c682803abf628d4cd62b8a4177"
6001
6001
  integrity sha512-+4zXKdx7UnO+1jaN4l2lHVD+mFvnlZQP/6ljaJVb4SZiwIKeUnrT5l0gkT8z+n4hKpC+jpOv6O9R+gLtag7pSA==
6002
6002
  dependencies:
6003
6003
  clone-deep "^4.0.1"
@@ -6166,7 +6166,7 @@ which@^2.0.1:
6166
6166
 
6167
6167
  wildcard@^2.0.0, wildcard@^2.0.1:
6168
6168
  version "2.0.1"
6169
- resolved "https://registry.npmjs.org/wildcard/-/wildcard-2.0.1.tgz"
6169
+ resolved "https://registry.npmjs.org/wildcard/-/wildcard-2.0.1.tgz#5ab10d02487198954836b6349f74fff961e10f67"
6170
6170
  integrity sha512-CC1bOL87PIWSBhDcTrdeLo6eGT7mCFtrg0uIJtqJUFyK+eJnzl8A1niH56uu7KMa5XFrtiV+AQuHO3n7DsHnLQ==
6171
6171
 
6172
6172
  word-wrap@^1.2.5:
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.0.0.beta.3
4
+ version: 9.0.0.beta.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - David Heinemeier Hansson
@@ -149,6 +149,7 @@ files:
149
149
  - ".node-version"
150
150
  - ".rspec"
151
151
  - ".rubocop.yml"
152
+ - ".yalcignore"
152
153
  - CHANGELOG.md
153
154
  - CLAUDE.md
154
155
  - CONTRIBUTING.md
@@ -178,7 +179,9 @@ files:
178
179
  - docs/sprockets.md
179
180
  - docs/style_loader_vs_mini_css.md
180
181
  - docs/subresource_integrity.md
182
+ - docs/transpiler-performance.md
181
183
  - docs/troubleshooting.md
184
+ - docs/typescript.md
182
185
  - docs/using_esbuild_loader.md
183
186
  - docs/using_swc_loader.md
184
187
  - docs/v6_upgrade.md
@@ -213,6 +216,7 @@ files:
213
216
  - lib/shakapacker/dev_server_proxy.rb
214
217
  - lib/shakapacker/dev_server_runner.rb
215
218
  - lib/shakapacker/digest_strategy.rb
219
+ - lib/shakapacker/doctor.rb
216
220
  - lib/shakapacker/env.rb
217
221
  - lib/shakapacker/helper.rb
218
222
  - lib/shakapacker/instance.rb
@@ -221,6 +225,7 @@ files:
221
225
  - lib/shakapacker/railtie.rb
222
226
  - lib/shakapacker/rspack_runner.rb
223
227
  - lib/shakapacker/runner.rb
228
+ - lib/shakapacker/swc_migrator.rb
224
229
  - lib/shakapacker/utils/manager.rb
225
230
  - lib/shakapacker/utils/misc.rb
226
231
  - lib/shakapacker/utils/version_syntax_converter.rb
@@ -235,23 +240,26 @@ files:
235
240
  - lib/tasks/shakapacker/clean.rake
236
241
  - lib/tasks/shakapacker/clobber.rake
237
242
  - lib/tasks/shakapacker/compile.rake
243
+ - lib/tasks/shakapacker/doctor.rake
238
244
  - lib/tasks/shakapacker/info.rake
239
245
  - lib/tasks/shakapacker/install.rake
246
+ - lib/tasks/shakapacker/migrate_to_swc.rake
240
247
  - lib/tasks/shakapacker/verify_config.rake
241
248
  - lib/tasks/shakapacker/verify_install.rake
242
- - package-lock.json
243
249
  - package.json
244
250
  - package/babel/preset.js
245
- - package/config.js
246
- - package/dev_server.js
247
- - package/env.js
251
+ - package/config.ts
252
+ - package/dev_server.ts
253
+ - package/env.ts
248
254
  - package/environments/base.js
255
+ - package/environments/base.ts
249
256
  - package/environments/development.js
250
257
  - package/environments/production.js
251
258
  - package/environments/test.js
252
259
  - package/esbuild/index.js
253
260
  - package/index.d.ts
254
- - package/index.js
261
+ - package/index.ts
262
+ - package/loaders.d.ts
255
263
  - package/optimization/rspack.js
256
264
  - package/optimization/webpack.js
257
265
  - package/plugins/rspack.js
@@ -272,17 +280,20 @@ files:
272
280
  - package/rules/swc.js
273
281
  - package/rules/webpack.js
274
282
  - package/swc/index.js
275
- - package/utils/configPath.js
276
- - package/utils/debug.js
277
- - package/utils/defaultConfigPath.js
278
- - package/utils/getStyleRule.js
279
- - package/utils/helpers.js
280
- - package/utils/inliningCss.js
281
- - package/utils/requireOrError.js
282
- - package/utils/snakeToCamelCase.js
283
- - package/utils/validateCssModulesConfig.js
284
- - package/utils/validateDependencies.js
285
- - package/webpackDevServerConfig.js
283
+ - package/types.ts
284
+ - package/utils/configPath.ts
285
+ - package/utils/debug.ts
286
+ - package/utils/defaultConfigPath.ts
287
+ - package/utils/errorHelpers.ts
288
+ - package/utils/getStyleRule.ts
289
+ - package/utils/helpers.ts
290
+ - package/utils/inliningCss.ts
291
+ - package/utils/requireOrError.ts
292
+ - package/utils/snakeToCamelCase.ts
293
+ - package/utils/typeGuards.ts
294
+ - package/utils/validateDependencies.ts
295
+ - package/webpack-types.d.ts
296
+ - package/webpackDevServerConfig.ts
286
297
  - prettier.config.js
287
298
  - shakapacker.gemspec
288
299
  - test/helpers.js
@@ -307,14 +318,16 @@ files:
307
318
  - test/package/staging.test.js
308
319
  - test/package/test.test.js
309
320
  - test/resolver.js
321
+ - test/typescript/build.test.js
310
322
  - tools/README.md
311
323
  - tools/css-modules-v9-codemod.js
324
+ - tsconfig.json
312
325
  - yarn.lock
313
326
  homepage: https://github.com/shakacode/shakapacker
314
327
  licenses:
315
328
  - MIT
316
329
  metadata:
317
- source_code_uri: https://github.com/shakacode/shakapacker/tree/v9.0.0.beta.3
330
+ source_code_uri: https://github.com/shakacode/shakapacker/tree/v9.0.0.beta.5
318
331
  rdoc_options: []
319
332
  require_paths:
320
333
  - lib
@@ -355,3 +368,4 @@ test_files:
355
368
  - test/package/staging.test.js
356
369
  - test/package/test.test.js
357
370
  - test/resolver.js
371
+ - test/typescript/build.test.js
data/package/config.js DELETED
@@ -1,80 +0,0 @@
1
- const { resolve } = require("path")
2
- const { load } = require("js-yaml")
3
- const { existsSync, readFileSync } = require("fs")
4
-
5
- const { merge } = require("webpack-merge")
6
- const { ensureTrailingSlash } = require("./utils/helpers")
7
- const { railsEnv } = require("./env")
8
- const configPath = require("./utils/configPath")
9
-
10
- const defaultConfigPath = require("./utils/defaultConfigPath")
11
-
12
- const getDefaultConfig = () => {
13
- const defaultConfig = load(readFileSync(defaultConfigPath), "utf8")
14
- return defaultConfig[railsEnv] || defaultConfig.production
15
- }
16
-
17
- const defaults = getDefaultConfig()
18
- let config
19
-
20
- if (existsSync(configPath)) {
21
- const appYmlObject = load(readFileSync(configPath), "utf8")
22
- const envAppConfig = appYmlObject[railsEnv]
23
-
24
- if (!envAppConfig) {
25
- /* eslint no-console:0 */
26
- console.warn(
27
- `Warning: ${railsEnv} key not found in the configuration file. Using production configuration as a fallback.`
28
- )
29
- }
30
-
31
- config = merge(defaults, envAppConfig || {})
32
- } else {
33
- config = merge(defaults, {})
34
- }
35
-
36
- config.outputPath = resolve(config.public_root_path, config.public_output_path)
37
-
38
- // Ensure that the publicPath includes our asset host so dynamic imports
39
- // (code-splitting chunks and static assets) load from the CDN instead of a relative path.
40
- const getPublicPath = () => {
41
- const rootUrl = ensureTrailingSlash(process.env.SHAKAPACKER_ASSET_HOST || "/")
42
- return `${rootUrl}${config.public_output_path}/`
43
- }
44
-
45
- config.publicPath = getPublicPath()
46
- config.publicPathWithoutCDN = `/${config.public_output_path}/`
47
-
48
- if (config.manifest_path) {
49
- config.manifestPath = resolve(config.manifest_path)
50
- } else {
51
- config.manifestPath = resolve(config.outputPath, "manifest.json")
52
- }
53
- // Ensure no duplicate hash functions exist in the returned config object
54
- config.integrity.hash_functions = [...new Set(config.integrity.hash_functions)]
55
-
56
- // Allow ENV variable to override assets_bundler
57
- if (process.env.SHAKAPACKER_ASSETS_BUNDLER) {
58
- config.assets_bundler = process.env.SHAKAPACKER_ASSETS_BUNDLER
59
- }
60
-
61
- // Define clear defaults
62
- const DEFAULT_JAVASCRIPT_TRANSPILER =
63
- config.assets_bundler === "rspack" ? "swc" : "babel"
64
-
65
- // Backward compatibility: Add webpack_loader property that maps to javascript_transpiler
66
- // Show deprecation warning if webpack_loader is used
67
- if (config.webpack_loader && !config.javascript_transpiler) {
68
- console.warn(
69
- "⚠️ DEPRECATION WARNING: The 'webpack_loader' configuration option is deprecated. Please use 'javascript_transpiler' instead as it better reflects its purpose of configuring JavaScript transpilation regardless of the bundler used."
70
- )
71
- config.javascript_transpiler = config.webpack_loader
72
- } else if (!config.javascript_transpiler) {
73
- config.javascript_transpiler =
74
- config.webpack_loader || DEFAULT_JAVASCRIPT_TRANSPILER
75
- }
76
-
77
- // Ensure webpack_loader is always available for backward compatibility
78
- config.webpack_loader = config.javascript_transpiler
79
-
80
- module.exports = config
data/package/env.js DELETED
@@ -1,48 +0,0 @@
1
- const { load } = require("js-yaml")
2
- const { readFileSync } = require("fs")
3
- const defaultConfigPath = require("./utils/defaultConfigPath")
4
-
5
- const NODE_ENVIRONMENTS = ["development", "production", "test"]
6
- const DEFAULT = "production"
7
- const configPath = require("./utils/configPath")
8
-
9
- const railsEnv = process.env.RAILS_ENV
10
- const rawNodeEnv = process.env.NODE_ENV
11
- const nodeEnv =
12
- rawNodeEnv && NODE_ENVIRONMENTS.includes(rawNodeEnv) ? rawNodeEnv : DEFAULT
13
- const isProduction = nodeEnv === "production"
14
- const isDevelopment = nodeEnv === "development"
15
-
16
- let config
17
- try {
18
- config = load(readFileSync(configPath), "utf8")
19
- } catch (error) {
20
- if (error.code === "ENOENT") {
21
- // File not found, use default configuration
22
- config = load(readFileSync(defaultConfigPath), "utf8")
23
- } else {
24
- throw error
25
- }
26
- }
27
-
28
- const availableEnvironments = Object.keys(config).join("|")
29
- const regex = new RegExp(`^(${availableEnvironments})$`, "g")
30
-
31
- const runningWebpackDevServer = process.env.WEBPACK_SERVE === "true"
32
-
33
- const validatedRailsEnv = railsEnv && railsEnv.match(regex) ? railsEnv : DEFAULT
34
-
35
- if (railsEnv && validatedRailsEnv !== railsEnv) {
36
- /* eslint no-console:0 */
37
- console.warn(
38
- `Warning: '${railsEnv}' environment not found in the configuration. Using '${DEFAULT}' configuration as a fallback.`
39
- )
40
- }
41
-
42
- module.exports = {
43
- railsEnv: validatedRailsEnv,
44
- nodeEnv,
45
- isProduction,
46
- isDevelopment,
47
- runningWebpackDevServer
48
- }
@@ -1,4 +0,0 @@
1
- const { resolve } = require("path")
2
-
3
- module.exports =
4
- process.env.SHAKAPACKER_CONFIG || resolve("config", "shakapacker.yml")
@@ -1,2 +0,0 @@
1
- const path = require.resolve("../../lib/install/config/shakapacker.yml")
2
- module.exports = path
@@ -1,62 +0,0 @@
1
- const isBoolean = (str) => /^true/.test(str) || /^false/.test(str)
2
-
3
- const ensureTrailingSlash = (path) => (path.endsWith("/") ? path : `${path}/`)
4
-
5
- const resolvedPath = (packageName) => {
6
- try {
7
- return require.resolve(packageName)
8
- } catch (e) {
9
- if (e.code !== "MODULE_NOT_FOUND") {
10
- throw e
11
- }
12
- return null
13
- }
14
- }
15
-
16
- const moduleExists = (packageName) => !!resolvedPath(packageName)
17
-
18
- const canProcess = (rule, fn) => {
19
- const modulePath = resolvedPath(rule)
20
-
21
- if (modulePath) {
22
- return fn(modulePath)
23
- }
24
-
25
- return null
26
- }
27
-
28
- const loaderMatches = (configLoader, loaderToCheck, fn) => {
29
- if (configLoader !== loaderToCheck) {
30
- return null
31
- }
32
-
33
- const loaderName = `${configLoader}-loader`
34
-
35
- if (!moduleExists(loaderName)) {
36
- throw new Error(
37
- `Your Shakapacker config specified using ${configLoader}, but ${loaderName} package is not installed. Please install ${loaderName} first.`
38
- )
39
- }
40
-
41
- return fn()
42
- }
43
-
44
- const packageFullVersion = (packageName) => {
45
- // eslint-disable-next-line import/no-dynamic-require
46
- const packageJsonPath = require.resolve(`${packageName}/package.json`)
47
- // eslint-disable-next-line import/no-dynamic-require, global-require
48
- return require(packageJsonPath).version
49
- }
50
-
51
- const packageMajorVersion = (packageName) =>
52
- packageFullVersion(packageName).match(/^\d+/)[0]
53
-
54
- module.exports = {
55
- isBoolean,
56
- ensureTrailingSlash,
57
- canProcess,
58
- moduleExists,
59
- loaderMatches,
60
- packageFullVersion,
61
- packageMajorVersion
62
- }
@@ -1,5 +0,0 @@
1
- function snakeToCamelCase(s) {
2
- return s.replace(/(_\w)/g, (match) => match[1].toUpperCase())
3
- }
4
-
5
- module.exports = snakeToCamelCase
@@ -1,91 +0,0 @@
1
- /* eslint global-require: 0 */
2
- const { warn } = require("./debug")
3
-
4
- /**
5
- * Validates CSS modules configuration and warns about potential issues
6
- * with v9 defaults or conflicting settings.
7
- */
8
- const validateCssModulesConfig = (cssLoaderOptions) => {
9
- // Skip validation in production by default for performance
10
- if (
11
- process.env.NODE_ENV === "production" &&
12
- process.env.SHAKAPACKER_VALIDATE_CSS_MODULES !== "true"
13
- ) {
14
- return
15
- }
16
-
17
- if (!cssLoaderOptions || !cssLoaderOptions.modules) {
18
- return
19
- }
20
-
21
- const { modules } = cssLoaderOptions
22
-
23
- // Check for conflicting namedExport and esModule settings
24
- if (modules.namedExport === true && modules.esModule === false) {
25
- warn(
26
- "⚠️ CSS Modules Configuration Warning:\n" +
27
- " namedExport: true with esModule: false may cause issues.\n" +
28
- " Consider setting esModule: true or removing it (defaults to true)."
29
- )
30
- }
31
-
32
- // Check for v8-style configuration with v9
33
- if (modules.namedExport === false) {
34
- warn(
35
- "ℹ️ CSS Modules Configuration Note:\n" +
36
- " You are using namedExport: false (v8 behavior).\n" +
37
- " Shakapacker v9 defaults to namedExport: true for better tree-shaking.\n" +
38
- " See docs/css-modules-export-mode.md for migration instructions."
39
- )
40
- }
41
-
42
- // Check for inconsistent exportLocalsConvention with namedExport
43
- if (
44
- modules.namedExport === true &&
45
- modules.exportLocalsConvention === "asIs"
46
- ) {
47
- warn(
48
- "⚠️ CSS Modules Configuration Warning:\n" +
49
- " Using namedExport: true with exportLocalsConvention: 'asIs' may cause issues\n" +
50
- " with kebab-case class names (e.g., 'my-button').\n" +
51
- " Consider using exportLocalsConvention: 'camelCase' (v9 default)."
52
- )
53
- }
54
-
55
- // Check for deprecated localIdentName pattern
56
- if (
57
- modules.localIdentName &&
58
- modules.localIdentName.includes("[hash:base64]")
59
- ) {
60
- warn(
61
- "⚠️ CSS Modules Configuration Warning:\n" +
62
- " [hash:base64] is deprecated in css-loader v6+.\n" +
63
- " Use [hash] instead for better compatibility."
64
- )
65
- }
66
-
67
- // Check for potential TypeScript issues
68
- if (
69
- modules.namedExport === true &&
70
- process.env.SHAKAPACKER_ASSET_COMPILER_TYPESCRIPT === "true"
71
- ) {
72
- warn(
73
- "ℹ️ TypeScript CSS Modules Note:\n" +
74
- " With namedExport: true, TypeScript projects should use:\n" +
75
- " import * as styles from './styles.module.css'\n" +
76
- " instead of: import styles from './styles.module.css'\n" +
77
- " See docs/css-modules-export-mode.md for TypeScript setup."
78
- )
79
- }
80
-
81
- // Check for auto: true with getLocalIdent (potential conflict)
82
- if (modules.auto === true && modules.getLocalIdent) {
83
- warn(
84
- "⚠️ CSS Modules Configuration Warning:\n" +
85
- " Using both 'auto: true' and 'getLocalIdent' may cause conflicts.\n" +
86
- " The 'auto' option determines which files are treated as CSS modules."
87
- )
88
- }
89
- }
90
-
91
- module.exports = { validateCssModulesConfig }