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.
Files changed (58) hide show
  1. checksums.yaml +4 -4
  2. data/.claude/commands/update-changelog.md +224 -0
  3. data/.github/actionlint-matcher.json +17 -0
  4. data/.github/workflows/dummy.yml +9 -0
  5. data/.github/workflows/generator.yml +13 -0
  6. data/.github/workflows/node.yml +83 -0
  7. data/.github/workflows/ruby.yml +11 -0
  8. data/.github/workflows/test-bundlers.yml +10 -0
  9. data/CHANGELOG.md +15 -8
  10. data/CLAUDE.md +6 -10
  11. data/CONTRIBUTING.md +57 -0
  12. data/Gemfile.lock +1 -1
  13. data/README.md +58 -33
  14. data/docs/api-reference.md +519 -0
  15. data/docs/configuration.md +11 -5
  16. data/docs/css-modules-export-mode.md +40 -6
  17. data/docs/transpiler-migration.md +12 -9
  18. data/docs/using_swc_loader.md +13 -10
  19. data/docs/v9_upgrade.md +11 -2
  20. data/eslint.config.fast.js +120 -8
  21. data/eslint.config.js +50 -31
  22. data/lib/install/config/shakapacker.yml +14 -1
  23. data/lib/shakapacker/configuration.rb +47 -4
  24. data/lib/shakapacker/dev_server_runner.rb +4 -0
  25. data/lib/shakapacker/doctor.rb +1 -1
  26. data/lib/shakapacker/version.rb +1 -1
  27. data/package/config.ts +2 -3
  28. data/package/configExporter/cli.ts +29 -24
  29. data/package/dev_server.ts +2 -2
  30. data/package/env.ts +1 -1
  31. data/package/environments/__type-tests__/rspack-plugin-compatibility.ts +6 -6
  32. data/package/environments/base.ts +2 -2
  33. data/package/environments/development.ts +3 -6
  34. data/package/environments/production.ts +2 -2
  35. data/package/environments/test.ts +2 -1
  36. data/package/esbuild/index.ts +0 -2
  37. data/package/index.d.ts +1 -0
  38. data/package/index.d.ts.template +1 -0
  39. data/package/index.ts +0 -1
  40. data/package/plugins/rspack.ts +3 -1
  41. data/package/plugins/webpack.ts +5 -3
  42. data/package/rspack/index.ts +3 -3
  43. data/package/rules/file.ts +1 -1
  44. data/package/rules/raw.ts +3 -1
  45. data/package/rules/rspack.ts +0 -2
  46. data/package/rules/sass.ts +0 -2
  47. data/package/rules/webpack.ts +0 -1
  48. data/package/swc/index.ts +0 -2
  49. data/package/types.ts +8 -11
  50. data/package/utils/debug.ts +0 -4
  51. data/package/utils/getStyleRule.ts +17 -9
  52. data/package/utils/helpers.ts +8 -3
  53. data/package/utils/pathValidation.ts +10 -11
  54. data/package/utils/requireOrError.ts +4 -3
  55. data/package/webpackDevServerConfig.ts +4 -4
  56. data/package.json +1 -1
  57. data/test/package/transpiler-defaults.test.js +42 -0
  58. metadata +5 -2
@@ -339,6 +339,31 @@ class Shakapacker::Configuration
339
339
  javascript_transpiler
340
340
  end
341
341
 
342
+ # Returns the CSS Modules export mode configuration
343
+ #
344
+ # Controls how CSS Module class names are exported in JavaScript:
345
+ # - "named" (default): Use named exports with camelCase conversion (v9 behavior)
346
+ # - "default": Use default export with both original and camelCase names (v8 behavior)
347
+ #
348
+ # @return [String] "named" or "default"
349
+ # @raise [ArgumentError] if an invalid value is configured
350
+ def css_modules_export_mode
351
+ @css_modules_export_mode ||= begin
352
+ mode = fetch(:css_modules_export_mode) || "named"
353
+
354
+ # Validate the configuration value
355
+ valid_modes = ["named", "default"]
356
+ unless valid_modes.include?(mode)
357
+ raise ArgumentError,
358
+ "Invalid css_modules_export_mode: '#{mode}'. " \
359
+ "Valid values are: #{valid_modes.map { |m| "'#{m}'" }.join(', ')}. " \
360
+ "See https://github.com/shakacode/shakapacker/blob/main/docs/css-modules-export-mode.md"
361
+ end
362
+
363
+ mode
364
+ end
365
+ end
366
+
342
367
  # Returns the path to the bundler configuration directory
343
368
  #
344
369
  # This is where webpack.config.js or rspack.config.js should be located.
@@ -353,6 +378,25 @@ class Shakapacker::Configuration
353
378
  rspack? ? "config/rspack" : "config/webpack"
354
379
  end
355
380
 
381
+ # Returns the raw configuration data hash
382
+ #
383
+ # Returns the merged configuration from the shakapacker.yml file for the current environment.
384
+ # The hash has symbolized keys loaded from the config file. Individual config values can be
385
+ # accessed through specific accessor methods like {#source_path}, which apply defaults via {#fetch}.
386
+ #
387
+ # The returned hash is frozen to prevent accidental mutations. To access config values,
388
+ # use the provided accessor methods instead of modifying this hash directly.
389
+ #
390
+ # @return [Hash<Symbol, Object>] the raw configuration data with symbolized keys (frozen)
391
+ # @example
392
+ # config.data[:source_path] #=> "app/javascript"
393
+ # config.data[:compile] #=> true
394
+ # @note The hash is frozen to prevent mutations. Use accessor methods for safe config access.
395
+ # @api public
396
+ def data
397
+ @data ||= load.freeze
398
+ end
399
+
356
400
  private
357
401
 
358
402
  def default_javascript_transpiler
@@ -363,6 +407,9 @@ class Shakapacker::Configuration
363
407
  def validate_transpiler_configuration(transpiler)
364
408
  return unless ENV["NODE_ENV"] != "test" # Skip validation in test environment
365
409
 
410
+ # Skip validation if transpiler is set to 'none' (custom webpack config)
411
+ return if transpiler == "none"
412
+
366
413
  # Check if package.json exists
367
414
  package_json_path = root_path.join("package.json")
368
415
  return unless package_json_path.exist?
@@ -495,10 +542,6 @@ class Shakapacker::Configuration
495
542
  [private_full_path.cleanpath.to_s, public_full_path.cleanpath.to_s]
496
543
  end
497
544
 
498
- def data
499
- @data ||= load
500
- end
501
-
502
545
  def load
503
546
  config = begin
504
547
  YAML.load_file(config_path.to_s, aliases: true)
@@ -18,6 +18,8 @@ module Shakapacker
18
18
  exit(0)
19
19
  end
20
20
 
21
+ Shakapacker.ensure_node_env!
22
+
21
23
  # Check for --build flag
22
24
  build_index = argv.index("--build")
23
25
  if build_index
@@ -65,6 +67,8 @@ module Shakapacker
65
67
  end
66
68
 
67
69
  def self.run_with_build_config(argv, build_config)
70
+ Shakapacker.ensure_node_env!
71
+
68
72
  # Apply build config environment variables
69
73
  build_config[:environment].each do |key, value|
70
74
  ENV[key] = value.to_s
@@ -914,7 +914,7 @@ module Shakapacker
914
914
  return unless doctor.config.config_path.exist?
915
915
 
916
916
  puts "\nConfiguration values for '#{doctor.config.env}' environment:"
917
- config_data = doctor.config.send(:data)
917
+ config_data = doctor.config.data
918
918
 
919
919
  if config_data.any?
920
920
  print_config_data(config_data)
@@ -1,4 +1,4 @@
1
1
  module Shakapacker
2
2
  # Change the version in package.json too, please!
3
- VERSION = "9.3.0".freeze
3
+ VERSION = "9.3.1".freeze
4
4
  end
data/package/config.ts CHANGED
@@ -6,12 +6,11 @@ const { ensureTrailingSlash } = require("./utils/helpers")
6
6
  const { railsEnv } = require("./env")
7
7
  const configPath = require("./utils/configPath")
8
8
  const defaultConfigPath = require("./utils/defaultConfigPath")
9
- import { Config, YamlConfig, LegacyConfig } from "./types"
9
+ import { Config, YamlConfig } from "./types"
10
10
  const {
11
11
  isValidYamlConfig,
12
12
  createConfigValidationError,
13
- isPartialConfig,
14
- isValidConfig
13
+ isPartialConfig
15
14
  } = require("./utils/typeGuards")
16
15
  const {
17
16
  isFileNotFoundError,
@@ -309,58 +309,61 @@ QUICK START (for troubleshooting):
309
309
  description:
310
310
  "Generate only server config (fallback when no config file exists)"
311
311
  })
312
- .check((argv) => {
313
- if (argv.webpack && argv.rspack) {
312
+ .check((parsedArgs) => {
313
+ if (parsedArgs.webpack && parsedArgs.rspack) {
314
314
  throw new Error(
315
315
  "--webpack and --rspack are mutually exclusive. Please specify only one."
316
316
  )
317
317
  }
318
- if (argv["client-only"] && argv["server-only"]) {
318
+ if (parsedArgs["client-only"] && parsedArgs["server-only"]) {
319
319
  throw new Error(
320
320
  "--client-only and --server-only are mutually exclusive. Please specify only one."
321
321
  )
322
322
  }
323
- if (argv.output && argv["save-dir"]) {
323
+ if (parsedArgs.output && parsedArgs["save-dir"]) {
324
324
  throw new Error(
325
325
  "--output and --save-dir are mutually exclusive. Use one or the other."
326
326
  )
327
327
  }
328
- if (argv.stdout && argv["save-dir"]) {
328
+ if (parsedArgs.stdout && parsedArgs["save-dir"]) {
329
329
  throw new Error(
330
330
  "--stdout and --save-dir are mutually exclusive. Use one or the other."
331
331
  )
332
332
  }
333
- if (argv.build && argv["all-builds"]) {
333
+ if (parsedArgs.build && parsedArgs["all-builds"]) {
334
334
  throw new Error(
335
335
  "--build and --all-builds are mutually exclusive. Use one or the other."
336
336
  )
337
337
  }
338
- if (argv.validate && argv["validate-build"]) {
338
+ if (parsedArgs.validate && parsedArgs["validate-build"]) {
339
339
  throw new Error(
340
340
  "--validate and --validate-build are mutually exclusive. Use one or the other."
341
341
  )
342
342
  }
343
- if (argv.validate && (argv.build || argv["all-builds"])) {
343
+ if (
344
+ parsedArgs.validate &&
345
+ (parsedArgs.build || parsedArgs["all-builds"])
346
+ ) {
344
347
  throw new Error(
345
348
  "--validate cannot be used with --build or --all-builds."
346
349
  )
347
350
  }
348
- if (argv["all-builds"] && argv.output) {
351
+ if (parsedArgs["all-builds"] && parsedArgs.output) {
349
352
  throw new Error(
350
353
  "--all-builds and --output are mutually exclusive. Use --save-dir instead."
351
354
  )
352
355
  }
353
- if (argv["all-builds"] && argv.stdout) {
356
+ if (parsedArgs["all-builds"] && parsedArgs.stdout) {
354
357
  throw new Error(
355
358
  "--all-builds and --stdout are mutually exclusive. Use --save-dir instead."
356
359
  )
357
360
  }
358
- if (argv.stdout && argv.output) {
361
+ if (parsedArgs.stdout && parsedArgs.output) {
359
362
  throw new Error(
360
363
  "--stdout and --output are mutually exclusive. Use one or the other."
361
364
  )
362
365
  }
363
- if (argv.ssr && !argv.init) {
366
+ if (parsedArgs.ssr && !parsedArgs.init) {
364
367
  throw new Error(
365
368
  "--ssr can only be used with --init. Use: bin/shakapacker-config --init --ssr"
366
369
  )
@@ -539,7 +542,7 @@ end
539
542
  // Make executable
540
543
  try {
541
544
  chmodSync(binStubPath, 0o755)
542
- } catch (e) {
545
+ } catch (_e) {
543
546
  // chmod might fail on some systems, but mode in writeFileSync should handle it
544
547
  }
545
548
  }
@@ -646,6 +649,7 @@ async function runValidateCommand(options: ExportOptions): Promise<number> {
646
649
  "development"
647
650
 
648
651
  // Auto-detect bundler using the build's environment
652
+ // eslint-disable-next-line no-await-in-loop -- Sequential execution required: each build modifies shared global state (env vars, config cache) that must be cleared/restored between iterations
649
653
  const defaultBundler = await autoDetectBundler(
650
654
  buildEnv,
651
655
  appRoot,
@@ -660,6 +664,7 @@ async function runValidateCommand(options: ExportOptions): Promise<number> {
660
664
  )
661
665
 
662
666
  // Validate the build
667
+ // eslint-disable-next-line no-await-in-loop -- Sequential execution required: each build modifies shared global state (env vars, config cache) that must be cleared/restored between iterations
663
668
  const result = await validator.validateBuild(resolvedBuild, appRoot)
664
669
  results.push(result)
665
670
 
@@ -738,6 +743,7 @@ async function runAllBuildsCommand(options: ExportOptions): Promise<number> {
738
743
 
739
744
  // Create a modified options object for this build
740
745
  const buildOptions = { ...resolvedOptions, build: buildName }
746
+ // eslint-disable-next-line no-await-in-loop -- Sequential execution required: each build modifies shared global state (env vars, config cache) that must be cleared/restored between iterations
741
747
  const configs = await loadConfigsForEnv(undefined, buildOptions, appRoot)
742
748
 
743
749
  for (const { config: cfg, metadata } of configs) {
@@ -817,6 +823,7 @@ async function runDoctorMode(
817
823
  // Clear shakapacker config cache between builds
818
824
  shakapackerConfigCache = null
819
825
 
826
+ // eslint-disable-next-line no-await-in-loop -- Sequential execution required: each build modifies shared global state (env vars, config cache) that must be cleared/restored between iterations
820
827
  const configs = await loadConfigsForEnv(
821
828
  undefined,
822
829
  { ...options, build: buildName },
@@ -884,6 +891,7 @@ async function runDoctorMode(
884
891
  process.env.WEBPACK_SERVE = "true"
885
892
  }
886
893
 
894
+ // eslint-disable-next-line no-await-in-loop -- Sequential execution required: each config modifies shared global state (env vars, config cache) that must be cleared/restored between iterations
887
895
  const configs = await loadConfigsForEnv(env, options, appRoot)
888
896
 
889
897
  for (const { config, metadata } of configs) {
@@ -922,7 +930,6 @@ async function runDoctorMode(
922
930
  }
923
931
 
924
932
  const fullPath = resolve(targetDir, filename)
925
- const fileOutput: FileOutput = { filename, content: output, metadata }
926
933
  FileWriter.writeSingleFile(fullPath, output)
927
934
  createdFiles.push(fullPath)
928
935
  }
@@ -1099,19 +1106,17 @@ async function loadConfigsForEnv(
1099
1106
  console.warn(
1100
1107
  `[Config Exporter] Warning: Skipping dangerous environment variable: ${key}`
1101
1108
  )
1102
- continue
1103
- }
1104
- if (!isBuildEnvVar(key)) {
1109
+ } else if (!isBuildEnvVar(key)) {
1105
1110
  console.warn(
1106
1111
  `[Config Exporter] Warning: Skipping non-whitelisted environment variable: ${key}. ` +
1107
1112
  `Allowed variables are: ${BUILD_ENV_VARS.join(", ")}`
1108
1113
  )
1109
- continue
1110
- }
1111
- if (options.verbose) {
1112
- console.log(`[Config Exporter] ${key}=${value}`)
1114
+ } else {
1115
+ if (options.verbose) {
1116
+ console.log(`[Config Exporter] ${key}=${value}`)
1117
+ }
1118
+ process.env[key] = value
1113
1119
  }
1114
- process.env[key] = value
1115
1120
  }
1116
1121
 
1117
1122
  // Determine final env: CLI flag > build config NODE_ENV > default
@@ -1193,7 +1198,7 @@ async function loadConfigsForEnv(
1193
1198
  if (configFile.endsWith(".ts")) {
1194
1199
  try {
1195
1200
  require("ts-node/register/transpile-only")
1196
- } catch (error) {
1201
+ } catch (_error) {
1197
1202
  throw new Error(
1198
1203
  "TypeScript config detected but ts-node is not available. " +
1199
1204
  "Install ts-node as a dev dependency: npm install --save-dev ts-node"
@@ -1630,7 +1635,7 @@ function loadShakapackerConfig(
1630
1635
 
1631
1636
  return result
1632
1637
  }
1633
- } catch (error: unknown) {
1638
+ } catch (_error: unknown) {
1634
1639
  console.warn(
1635
1640
  `[Config Exporter] Error loading shakapacker config, defaulting to webpack`
1636
1641
  )
@@ -1,8 +1,8 @@
1
1
  // These are the raw shakapacker dev server config settings from the YML file with ENV overrides applied.
2
- import { DevServerConfig } from "./types"
2
+ import type { DevServerConfig, Config } from "./types"
3
3
 
4
4
  const { isBoolean } = require("./utils/helpers")
5
- const config = require("./config")
5
+ const config = require("./config") as Config
6
6
 
7
7
  const envFetch = (key: string): string | boolean | undefined => {
8
8
  const value = process.env[key]
data/package/env.ts CHANGED
@@ -51,7 +51,7 @@ try {
51
51
  // File not found, use default configuration
52
52
  try {
53
53
  config = load(readFileSync(defaultConfigPath, "utf8")) as ConfigFile
54
- } catch (defaultError) {
54
+ } catch (_defaultError) {
55
55
  throw new Error(
56
56
  `Failed to load Shakapacker configuration.\n` +
57
57
  `Neither user config (${configPath}) nor default config (${defaultConfigPath}) could be loaded.\n\n` +
@@ -9,26 +9,26 @@
9
9
  import type { RspackPlugin, RspackPluginInstance } from "../types"
10
10
 
11
11
  // Test 1: RspackPlugin should be assignable to RspackPluginInstance
12
- const testPluginToInstance = (plugin: RspackPlugin): RspackPluginInstance =>
12
+ const _testPluginToInstance = (plugin: RspackPlugin): RspackPluginInstance =>
13
13
  plugin
14
14
 
15
15
  // Test 2: RspackPluginInstance should be assignable to RspackPlugin
16
- const testInstanceToPlugin = (instance: RspackPluginInstance): RspackPlugin =>
16
+ const _testInstanceToPlugin = (instance: RspackPluginInstance): RspackPlugin =>
17
17
  instance
18
18
 
19
19
  // Test 3: Array compatibility
20
- const testArrayCompatibility = (
20
+ const _testArrayCompatibility = (
21
21
  plugins: RspackPlugin[]
22
22
  ): RspackPluginInstance[] => plugins
23
- const testArrayCompatibilityReverse = (
23
+ const _testArrayCompatibilityReverse = (
24
24
  instances: RspackPluginInstance[]
25
25
  ): RspackPlugin[] => instances
26
26
 
27
27
  // Test 4: Optional parameter compatibility
28
- const testOptionalParam = (
28
+ const _testOptionalParam = (
29
29
  plugin?: RspackPlugin
30
30
  ): RspackPluginInstance | undefined => plugin
31
- const testOptionalParamReverse = (
31
+ const _testOptionalParamReverse = (
32
32
  instance?: RspackPluginInstance
33
33
  ): RspackPlugin | undefined => instance
34
34
 
@@ -1,13 +1,13 @@
1
- /* eslint global-require: 0 */
2
1
  /* eslint import/no-dynamic-require: 0 */
3
2
 
4
3
  import { Dirent } from "fs"
5
4
  import type { Configuration, Entry } from "webpack"
5
+ import type { Config } from "../types"
6
6
 
7
7
  const { basename, dirname, join, relative, resolve } = require("path")
8
8
  const { existsSync, readdirSync } = require("fs")
9
9
  const extname = require("path-complete-extname")
10
- const config = require("../config")
10
+ const config = require("../config") as Config
11
11
  const { isProduction } = require("../env")
12
12
 
13
13
  const pluginsPath = resolve(
@@ -5,13 +5,12 @@
5
5
 
6
6
  import type {
7
7
  WebpackConfigWithDevServer,
8
- RspackConfigWithDevServer,
9
- ReactRefreshWebpackPlugin,
10
- ReactRefreshRspackPlugin
8
+ RspackConfigWithDevServer
11
9
  } from "./types"
10
+ import type { Config } from "../types"
12
11
 
13
12
  const { merge } = require("webpack-merge")
14
- const config = require("../config")
13
+ const config = require("../config") as Config
15
14
  const baseConfig = require("./base")
16
15
  const webpackDevServerConfig = require("../webpackDevServerConfig")
17
16
  const { runningWebpackDevServer } = require("../env")
@@ -41,7 +40,6 @@ const webpackDevConfig = (): WebpackConfigWithDevServer => {
41
40
  devServerConfig.hot &&
42
41
  moduleExists("@pmmmwh/react-refresh-webpack-plugin")
43
42
  ) {
44
- // eslint-disable-next-line global-require
45
43
  const ReactRefreshWebpackPlugin = require("@pmmmwh/react-refresh-webpack-plugin")
46
44
  webpackConfig.plugins = [
47
45
  ...(webpackConfig.plugins || []),
@@ -74,7 +72,6 @@ const rspackDevConfig = (): RspackConfigWithDevServer => {
74
72
  devServerConfig.hot &&
75
73
  moduleExists("@rspack/plugin-react-refresh")
76
74
  ) {
77
- // eslint-disable-next-line global-require
78
75
  const ReactRefreshPlugin = require("@rspack/plugin-react-refresh")
79
76
  rspackConfig.plugins = [
80
77
  ...(rspackConfig.plugins || []),
@@ -3,7 +3,6 @@
3
3
  * @module environments/production
4
4
  */
5
5
 
6
- /* eslint global-require: 0 */
7
6
  /* eslint import/no-dynamic-require: 0 */
8
7
 
9
8
  import type {
@@ -11,12 +10,13 @@ import type {
11
10
  WebpackPluginInstance
12
11
  } from "webpack"
13
12
  import type { CompressionPluginConstructor } from "./types"
13
+ import type { Config } from "../types"
14
14
 
15
15
  const { resolve } = require("path")
16
16
  const { merge } = require("webpack-merge")
17
17
  const baseConfig = require("./base")
18
18
  const { moduleExists } = require("../utils/helpers")
19
- const config = require("../config")
19
+ const config = require("../config") as Config
20
20
 
21
21
  const optimizationPath = resolve(
22
22
  __dirname,
@@ -4,9 +4,10 @@
4
4
  */
5
5
 
6
6
  import type { Configuration as WebpackConfiguration } from "webpack"
7
+ import type { Config } from "../types"
7
8
 
8
9
  const { merge } = require("webpack-merge")
9
- const config = require("../config")
10
+ const config = require("../config") as Config
10
11
  const baseConfig = require("./base")
11
12
 
12
13
  interface TestConfig {
@@ -1,4 +1,3 @@
1
- /* eslint global-require: 0 */
2
1
  /* eslint import/no-dynamic-require: 0 */
3
2
 
4
3
  import { resolve } from "path"
@@ -21,7 +20,6 @@ const getLoaderExtension = (filename: string): string => {
21
20
  const getCustomConfig = (): Partial<RuleSetRule> => {
22
21
  const path = resolve("config", "esbuild.config.js")
23
22
  if (existsSync(path)) {
24
- // eslint-disable-next-line @typescript-eslint/no-require-imports
25
23
  return require(path)
26
24
  }
27
25
  return {}
data/package/index.d.ts CHANGED
@@ -7,6 +7,7 @@
7
7
  * When adding/modifying exports in index.ts, update this file accordingly.
8
8
  */
9
9
 
10
+ // @ts-expect-error: webpack is an optional peer dependency (using type-only import)
10
11
  import type { Configuration, RuleSetRule } from "webpack"
11
12
  import type { Config, DevServerConfig, Env } from "./types"
12
13
 
@@ -7,6 +7,7 @@
7
7
  * When adding/modifying exports in index.ts, update this file accordingly.
8
8
  */
9
9
 
10
+ // @ts-expect-error: webpack is an optional peer dependency (using type-only import)
10
11
  import type { Configuration, RuleSetRule } from "webpack"
11
12
  import type { Config, DevServerConfig, Env } from "./types"
12
13
 
data/package/index.ts CHANGED
@@ -1,4 +1,3 @@
1
- /* eslint global-require: 0 */
2
1
  /* eslint import/no-dynamic-require: 0 */
3
2
 
4
3
  import * as webpackMerge from "webpack-merge"
@@ -1,8 +1,10 @@
1
+ import type { Config } from "../types"
2
+
1
3
  const { requireOrError } = require("../utils/requireOrError")
2
4
 
3
5
  const { RspackManifestPlugin } = requireOrError("rspack-manifest-plugin")
4
6
  const rspack = requireOrError("@rspack/core")
5
- const config = require("../config")
7
+ const config = require("../config") as Config
6
8
  const { isProduction } = require("../env")
7
9
  const { moduleExists } = require("../utils/helpers")
8
10
 
@@ -1,9 +1,11 @@
1
+ import type { Config } from "../types"
2
+
1
3
  const { requireOrError } = require("../utils/requireOrError")
2
4
  // TODO: Change to `const { WebpackAssetsManifest }` when dropping 'webpack-assets-manifest < 6.0.0' (Node >=20.10.0) support
3
5
  const WebpackAssetsManifest = requireOrError("webpack-assets-manifest")
4
6
  const webpack = requireOrError("webpack")
5
- const config = require("../config")
6
- const { isProduction, isDevelopment } = require("../env")
7
+ const config = require("../config") as Config
8
+ const { isProduction } = require("../env")
7
9
  const { moduleExists } = require("../utils/helpers")
8
10
 
9
11
  const getPlugins = (): unknown[] => {
@@ -15,7 +17,7 @@ const getPlugins = (): unknown[] => {
15
17
  const plugins = [
16
18
  new webpack.EnvironmentPlugin(process.env),
17
19
  new WebpackAssetsManifestConstructor({
18
- merge: isDevelopment,
20
+ merge: true,
19
21
  entrypoints: true,
20
22
  writeToDisk: true,
21
23
  output: config.manifestPath,
@@ -1,4 +1,3 @@
1
- /* eslint global-require: 0 */
2
1
  /* eslint import/no-dynamic-require: 0 */
3
2
 
4
3
  // Mixed require/import syntax:
@@ -7,9 +6,10 @@
7
6
  import { resolve } from "path"
8
7
  import { existsSync } from "fs"
9
8
  import type { RspackConfigWithDevServer } from "../environments/types"
9
+ import type { Config } from "../types"
10
10
 
11
11
  const webpackMerge = require("webpack-merge")
12
- const config = require("../config")
12
+ const config = require("../config") as Config
13
13
  const baseConfig = require("../environments/base")
14
14
  const devServer = require("../dev_server")
15
15
  const env = require("../env")
@@ -36,7 +36,7 @@ const generateRspackConfig = (
36
36
 
37
37
  const { nodeEnv } = env
38
38
  const path = resolve(__dirname, "../environments", `${nodeEnv}.js`)
39
- // eslint-disable-next-line @typescript-eslint/no-require-imports
39
+
40
40
  const environmentConfig = existsSync(path) ? require(path) : baseConfig
41
41
 
42
42
  // Create base rspack config
@@ -1,4 +1,4 @@
1
- import { dirname, sep, normalize } from "path"
1
+ import { dirname, normalize } from "path"
2
2
 
3
3
  const {
4
4
  additional_paths: additionalPaths,
data/package/rules/raw.ts CHANGED
@@ -1,4 +1,6 @@
1
- const config = require("../config")
1
+ import type { Config } from "../types"
2
+
3
+ const config = require("../config") as Config
2
4
 
3
5
  const rspackRawConfig = () => ({
4
6
  resourceQuery: /raw/,
@@ -1,5 +1,3 @@
1
- /* eslint global-require: 0 */
2
-
3
1
  const { moduleExists } = require("../utils/helpers")
4
2
  const { debug, info, warn } = require("../utils/debug")
5
3
 
@@ -1,5 +1,3 @@
1
- /* eslint global-require: 0 */
2
-
3
1
  const { getStyleRule } = require("../utils/getStyleRule")
4
2
  const { canProcess, packageMajorVersion } = require("../utils/helpers")
5
3
  const { additional_paths: extraPaths } = require("../config")
@@ -1,4 +1,3 @@
1
- /* eslint global-require: 0 */
2
1
  /* eslint import/no-dynamic-require: 0 */
3
2
 
4
3
  export = [
data/package/swc/index.ts CHANGED
@@ -1,4 +1,3 @@
1
- /* eslint global-require: 0 */
2
1
  /* eslint import/no-dynamic-require: 0 */
3
2
 
4
3
  import { resolve } from "path"
@@ -18,7 +17,6 @@ const isTypescriptFile = (filename: string): boolean =>
18
17
  const getCustomConfig = (): Partial<RuleSetRule> => {
19
18
  const path = resolve("config", "swc.config.js")
20
19
  if (existsSync(path)) {
21
- // eslint-disable-next-line @typescript-eslint/no-require-imports
22
20
  return require(path)
23
21
  }
24
22
  return {}
data/package/types.ts CHANGED
@@ -15,6 +15,7 @@ export interface Config {
15
15
  source_entry_path: string
16
16
  nested_entries: boolean
17
17
  css_extract_ignore_order_warnings: boolean
18
+ css_modules_export_mode?: "named" | "default"
18
19
  public_root_path: string
19
20
  public_output_path: string
20
21
  private_output_path?: string
@@ -53,8 +54,6 @@ export interface Env {
53
54
  type Header =
54
55
  | Array<{ key: string; value: string }>
55
56
  | Record<string, string | string[]>
56
- type ServerType = "http" | "https" | "spdy"
57
- type WebSocketType = "sockjs" | "ws"
58
57
 
59
58
  /**
60
59
  * This has the same keys and behavior as https://webpack.js.org/configuration/dev-server/ except:
@@ -63,7 +62,7 @@ type WebSocketType = "sockjs" | "ws"
63
62
  * @see {import('webpack-dev-server').Configuration}
64
63
  */
65
64
  export interface DevServerConfig {
66
- allowed_hosts?: "all" | "auto" | string | string[]
65
+ allowed_hosts?: string | string[]
67
66
  bonjour?: boolean | Record<string, unknown> // bonjour.BonjourOptions
68
67
  client?: Record<string, unknown> // Client
69
68
  compress?: boolean
@@ -71,7 +70,7 @@ export interface DevServerConfig {
71
70
  headers?: Header | (() => Header)
72
71
  history_api_fallback?: boolean | Record<string, unknown> // HistoryApiFallbackOptions
73
72
  hmr?: "only" | boolean
74
- host?: "local-ip" | "local-ipv4" | "local-ipv6" | string
73
+ host?: string
75
74
  http2?: boolean
76
75
  https?: boolean | https.ServerOptions
77
76
  ipc?: boolean | string
@@ -85,23 +84,21 @@ export interface DevServerConfig {
85
84
  | string[]
86
85
  | Record<string, unknown>
87
86
  | Record<string, unknown>[]
88
- port?: "auto" | string | number
87
+ port?: string | number
89
88
  proxy?: unknown // ProxyConfigMap | ProxyConfigArray
90
89
  setup_exit_signals?: boolean
91
- static?: boolean | string | unknown // Static | Array<string | Static>
92
- watch_files?: string | string[] | unknown // WatchFiles | Array<WatchFiles | string>
90
+ static?: unknown // Static | Array<string | Static>
91
+ watch_files?: unknown // WatchFiles | Array<WatchFiles | string>
93
92
  web_socket_server?:
94
93
  | string
95
94
  | boolean
96
- | WebSocketType
97
95
  | {
98
- type?: string | boolean | WebSocketType
96
+ type?: string | boolean
99
97
  options?: Record<string, unknown>
100
98
  }
101
99
  server?:
102
100
  | string
103
101
  | boolean
104
- | ServerType
105
- | { type?: string | boolean | ServerType; options?: https.ServerOptions }
102
+ | { type?: string | boolean; options?: https.ServerOptions }
106
103
  [otherWebpackDevServerConfigKey: string]: unknown
107
104
  }