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
|
@@ -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
|
data/lib/shakapacker/doctor.rb
CHANGED
|
@@ -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.
|
|
917
|
+
config_data = doctor.config.data
|
|
918
918
|
|
|
919
919
|
if config_data.any?
|
|
920
920
|
print_config_data(config_data)
|
data/lib/shakapacker/version.rb
CHANGED
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
|
|
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((
|
|
313
|
-
if (
|
|
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 (
|
|
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 (
|
|
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 (
|
|
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 (
|
|
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 (
|
|
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 (
|
|
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 (
|
|
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 (
|
|
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 (
|
|
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 (
|
|
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 (
|
|
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
|
-
|
|
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
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
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 (
|
|
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 (
|
|
1638
|
+
} catch (_error: unknown) {
|
|
1634
1639
|
console.warn(
|
|
1635
1640
|
`[Config Exporter] Error loading shakapacker config, defaulting to webpack`
|
|
1636
1641
|
)
|
data/package/dev_server.ts
CHANGED
|
@@ -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 (
|
|
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
|
|
12
|
+
const _testPluginToInstance = (plugin: RspackPlugin): RspackPluginInstance =>
|
|
13
13
|
plugin
|
|
14
14
|
|
|
15
15
|
// Test 2: RspackPluginInstance should be assignable to RspackPlugin
|
|
16
|
-
const
|
|
16
|
+
const _testInstanceToPlugin = (instance: RspackPluginInstance): RspackPlugin =>
|
|
17
17
|
instance
|
|
18
18
|
|
|
19
19
|
// Test 3: Array compatibility
|
|
20
|
-
const
|
|
20
|
+
const _testArrayCompatibility = (
|
|
21
21
|
plugins: RspackPlugin[]
|
|
22
22
|
): RspackPluginInstance[] => plugins
|
|
23
|
-
const
|
|
23
|
+
const _testArrayCompatibilityReverse = (
|
|
24
24
|
instances: RspackPluginInstance[]
|
|
25
25
|
): RspackPlugin[] => instances
|
|
26
26
|
|
|
27
27
|
// Test 4: Optional parameter compatibility
|
|
28
|
-
const
|
|
28
|
+
const _testOptionalParam = (
|
|
29
29
|
plugin?: RspackPlugin
|
|
30
30
|
): RspackPluginInstance | undefined => plugin
|
|
31
|
-
const
|
|
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 {
|
data/package/esbuild/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"
|
|
@@ -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
|
|
data/package/index.d.ts.template
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
|
|
data/package/index.ts
CHANGED
data/package/plugins/rspack.ts
CHANGED
|
@@ -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
|
|
data/package/plugins/webpack.ts
CHANGED
|
@@ -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
|
|
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:
|
|
20
|
+
merge: true,
|
|
19
21
|
entrypoints: true,
|
|
20
22
|
writeToDisk: true,
|
|
21
23
|
output: config.manifestPath,
|
data/package/rspack/index.ts
CHANGED
|
@@ -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
|
-
|
|
39
|
+
|
|
40
40
|
const environmentConfig = existsSync(path) ? require(path) : baseConfig
|
|
41
41
|
|
|
42
42
|
// Create base rspack config
|
data/package/rules/file.ts
CHANGED
data/package/rules/raw.ts
CHANGED
data/package/rules/rspack.ts
CHANGED
data/package/rules/sass.ts
CHANGED
data/package/rules/webpack.ts
CHANGED
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?:
|
|
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?:
|
|
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?:
|
|
87
|
+
port?: string | number
|
|
89
88
|
proxy?: unknown // ProxyConfigMap | ProxyConfigArray
|
|
90
89
|
setup_exit_signals?: boolean
|
|
91
|
-
static?:
|
|
92
|
-
watch_files?:
|
|
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
|
|
96
|
+
type?: string | boolean
|
|
99
97
|
options?: Record<string, unknown>
|
|
100
98
|
}
|
|
101
99
|
server?:
|
|
102
100
|
| string
|
|
103
101
|
| boolean
|
|
104
|
-
|
|
|
105
|
-
| { type?: string | boolean | ServerType; options?: https.ServerOptions }
|
|
102
|
+
| { type?: string | boolean; options?: https.ServerOptions }
|
|
106
103
|
[otherWebpackDevServerConfigKey: string]: unknown
|
|
107
104
|
}
|