shakapacker 8.4.0 → 9.0.0.beta.2
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/.github/STATUS.md +1 -0
- data/.github/workflows/claude-code-review.yml +54 -0
- data/.github/workflows/claude.yml +50 -0
- data/.github/workflows/dummy.yml +1 -1
- data/.github/workflows/generator.yml +4 -14
- data/.github/workflows/node.yml +1 -1
- data/.rubocop.yml +1 -0
- data/CHANGELOG.md +8 -2
- data/Gemfile.lock +3 -3
- data/README.md +2 -2
- data/Rakefile +18 -1
- data/docs/css-modules-export-mode.md +288 -0
- data/docs/peer-dependencies.md +40 -0
- data/docs/rspack.md +190 -0
- data/docs/rspack_migration_guide.md +202 -0
- data/docs/troubleshooting.md +5 -0
- data/docs/using_esbuild_loader.md +3 -3
- data/docs/using_swc_loader.md +5 -3
- data/lib/install/bin/shakapacker +3 -5
- data/lib/install/config/rspack/rspack.config.js +6 -0
- data/lib/install/config/shakapacker.yml +6 -2
- data/lib/install/package.json +30 -0
- data/lib/install/template.rb +12 -2
- data/lib/shakapacker/configuration.rb +45 -0
- data/lib/shakapacker/dev_server_runner.rb +25 -5
- data/lib/shakapacker/manifest.rb +4 -2
- data/lib/shakapacker/rspack_runner.rb +19 -0
- data/lib/shakapacker/runner.rb +144 -4
- data/lib/shakapacker/utils/manager.rb +2 -0
- data/lib/shakapacker/version.rb +1 -1
- data/lib/shakapacker/version_checker.rb +1 -1
- data/lib/shakapacker/webpack_runner.rb +4 -42
- data/lib/tasks/shakapacker/install.rake +6 -2
- data/package/config.js +24 -0
- data/package/environments/base.js +20 -65
- data/package/environments/development.js +60 -5
- data/package/environments/production.js +29 -51
- data/package/environments/test.js +17 -1
- data/package/index.d.ts +62 -20
- data/package/index.js +4 -2
- data/package/optimization/rspack.js +29 -0
- data/package/optimization/webpack.js +49 -0
- data/package/plugins/rspack.js +88 -0
- data/package/plugins/webpack.js +62 -0
- data/package/rspack/index.js +57 -0
- data/package/rules/babel.js +2 -2
- data/package/rules/css.js +1 -1
- data/package/rules/esbuild.js +2 -2
- data/package/rules/file.js +11 -5
- data/package/rules/less.js +1 -1
- data/package/rules/raw.js +12 -2
- data/package/rules/rspack.js +162 -0
- data/package/rules/sass.js +6 -2
- data/package/rules/stylus.js +1 -1
- data/package/rules/swc.js +2 -2
- data/package/utils/debug.js +49 -0
- data/package/utils/getStyleRule.js +16 -3
- data/package/utils/requireOrError.js +15 -0
- data/package/utils/validateDependencies.js +61 -0
- data/package/webpackDevServerConfig.js +2 -0
- data/package.json +19 -31
- data/test/package/environments/base.test.js +1 -1
- data/test/package/rules/esbuild.test.js +1 -1
- data/test/package/rules/swc.test.js +1 -1
- data/test/package/rules/{index.test.js → webpack.test.js} +1 -1
- data/yarn.lock +2136 -726
- metadata +26 -11
- /data/package/rules/{index.js → webpack.js} +0 -0
@@ -0,0 +1,19 @@
|
|
1
|
+
require "shellwords"
|
2
|
+
|
3
|
+
require_relative "runner"
|
4
|
+
|
5
|
+
module Shakapacker
|
6
|
+
class RspackRunner < Shakapacker::Runner
|
7
|
+
def self.run(argv)
|
8
|
+
$stdout.sync = true
|
9
|
+
ENV["NODE_ENV"] ||= (ENV["RAILS_ENV"] == "production") ? "production" : "development"
|
10
|
+
new(argv).run
|
11
|
+
end
|
12
|
+
|
13
|
+
private
|
14
|
+
|
15
|
+
def build_cmd
|
16
|
+
package_json.manager.native_exec_command("rspack")
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
data/lib/shakapacker/runner.rb
CHANGED
@@ -1,14 +1,60 @@
|
|
1
1
|
require_relative "utils/misc"
|
2
2
|
require_relative "utils/manager"
|
3
|
+
require_relative "configuration"
|
3
4
|
|
4
5
|
require "package_json"
|
6
|
+
require "pathname"
|
5
7
|
|
6
8
|
module Shakapacker
|
7
9
|
class Runner
|
10
|
+
attr_reader :config
|
11
|
+
|
12
|
+
# Common commands that don't work with --config option
|
13
|
+
BASE_COMMANDS = [
|
14
|
+
"help",
|
15
|
+
"h",
|
16
|
+
"--help",
|
17
|
+
"-h",
|
18
|
+
"version",
|
19
|
+
"v",
|
20
|
+
"--version",
|
21
|
+
"-v",
|
22
|
+
"info",
|
23
|
+
"i"
|
24
|
+
].freeze
|
8
25
|
def self.run(argv)
|
9
26
|
$stdout.sync = true
|
10
27
|
ENV["NODE_ENV"] ||= (ENV["RAILS_ENV"] == "production") ? "production" : "development"
|
11
|
-
|
28
|
+
|
29
|
+
# Create a single runner instance to avoid loading configuration twice.
|
30
|
+
# We extend it with the appropriate build command based on the bundler type.
|
31
|
+
runner = new(argv)
|
32
|
+
|
33
|
+
if runner.config.rspack?
|
34
|
+
require_relative "rspack_runner"
|
35
|
+
# Extend the runner instance with rspack-specific methods
|
36
|
+
# This avoids creating a new RspackRunner which would reload the configuration
|
37
|
+
runner.extend(Module.new do
|
38
|
+
def build_cmd
|
39
|
+
package_json.manager.native_exec_command("rspack")
|
40
|
+
end
|
41
|
+
|
42
|
+
def assets_bundler_commands
|
43
|
+
BASE_COMMANDS + %w[build watch]
|
44
|
+
end
|
45
|
+
end)
|
46
|
+
runner.run
|
47
|
+
else
|
48
|
+
require_relative "webpack_runner"
|
49
|
+
# Extend the runner instance with webpack-specific methods
|
50
|
+
# This avoids creating a new WebpackRunner which would reload the configuration
|
51
|
+
runner.extend(Module.new do
|
52
|
+
def build_cmd
|
53
|
+
package_json.manager.native_exec_command("webpack")
|
54
|
+
end
|
55
|
+
end)
|
56
|
+
runner.run
|
57
|
+
end
|
12
58
|
end
|
13
59
|
|
14
60
|
def initialize(argv)
|
@@ -16,7 +62,12 @@ module Shakapacker
|
|
16
62
|
|
17
63
|
@app_path = File.expand_path(".", Dir.pwd)
|
18
64
|
@shakapacker_config = ENV["SHAKAPACKER_CONFIG"] || File.join(@app_path, "config/shakapacker.yml")
|
19
|
-
@
|
65
|
+
@config = Configuration.new(
|
66
|
+
root_path: Pathname.new(@app_path),
|
67
|
+
config_path: Pathname.new(@shakapacker_config),
|
68
|
+
env: ENV["RAILS_ENV"] || ENV["NODE_ENV"] || "development"
|
69
|
+
)
|
70
|
+
@webpack_config = find_assets_bundler_config
|
20
71
|
|
21
72
|
Shakapacker::Utils::Manager.error_unless_package_manager_is_obvious!
|
22
73
|
end
|
@@ -25,16 +76,105 @@ module Shakapacker
|
|
25
76
|
@package_json ||= PackageJson.read(@app_path)
|
26
77
|
end
|
27
78
|
|
79
|
+
def run
|
80
|
+
puts "[Shakapacker] Preparing environment for assets bundler execution..."
|
81
|
+
env = Shakapacker::Compiler.env
|
82
|
+
env["SHAKAPACKER_CONFIG"] = @shakapacker_config
|
83
|
+
env["NODE_OPTIONS"] = ENV["NODE_OPTIONS"] || ""
|
84
|
+
|
85
|
+
cmd = build_cmd
|
86
|
+
puts "[Shakapacker] Base command: #{cmd.join(" ")}"
|
87
|
+
|
88
|
+
if @argv.delete("--debug-shakapacker")
|
89
|
+
puts "[Shakapacker] Debug mode enabled (--debug-shakapacker)"
|
90
|
+
env["NODE_OPTIONS"] = "#{env["NODE_OPTIONS"]} --inspect-brk"
|
91
|
+
end
|
92
|
+
|
93
|
+
if @argv.delete "--trace-deprecation"
|
94
|
+
puts "[Shakapacker] Trace deprecation enabled (--trace-deprecation)"
|
95
|
+
env["NODE_OPTIONS"] = "#{env["NODE_OPTIONS"]} --trace-deprecation"
|
96
|
+
end
|
97
|
+
|
98
|
+
if @argv.delete "--no-deprecation"
|
99
|
+
puts "[Shakapacker] Deprecation warnings disabled (--no-deprecation)"
|
100
|
+
env["NODE_OPTIONS"] = "#{env["NODE_OPTIONS"]} --no-deprecation"
|
101
|
+
end
|
102
|
+
|
103
|
+
# Commands are not compatible with --config option.
|
104
|
+
if (@argv & assets_bundler_commands).empty?
|
105
|
+
puts "[Shakapacker] Adding config file: #{@webpack_config}"
|
106
|
+
cmd += ["--config", @webpack_config]
|
107
|
+
else
|
108
|
+
puts "[Shakapacker] Skipping config file (running assets bundler command: #{(@argv & assets_bundler_commands).join(", ")})"
|
109
|
+
end
|
110
|
+
|
111
|
+
cmd += @argv
|
112
|
+
puts "[Shakapacker] Final command: #{cmd.join(" ")}"
|
113
|
+
puts "[Shakapacker] Working directory: #{@app_path}"
|
114
|
+
|
115
|
+
Dir.chdir(@app_path) do
|
116
|
+
Kernel.exec env, *cmd
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
protected
|
121
|
+
|
122
|
+
def assets_bundler_commands
|
123
|
+
BASE_COMMANDS
|
124
|
+
end
|
125
|
+
|
28
126
|
private
|
127
|
+
def find_assets_bundler_config
|
128
|
+
if @config.rspack?
|
129
|
+
find_rspack_config_with_fallback
|
130
|
+
else
|
131
|
+
find_webpack_config
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
def find_rspack_config_with_fallback
|
136
|
+
# First try rspack-specific paths
|
137
|
+
rspack_paths = %w[ts js].map do |ext|
|
138
|
+
File.join(@app_path, "config/rspack/rspack.config.#{ext}")
|
139
|
+
end
|
140
|
+
|
141
|
+
puts "[Shakapacker] Looking for Rspack config in: #{rspack_paths.join(", ")}"
|
142
|
+
rspack_path = rspack_paths.find { |f| File.exist?(f) }
|
143
|
+
if rspack_path
|
144
|
+
puts "[Shakapacker] Found Rspack config: #{rspack_path}"
|
145
|
+
return rspack_path
|
146
|
+
end
|
147
|
+
|
148
|
+
# Fallback to webpack config with deprecation warning
|
149
|
+
webpack_paths = %w[ts js].map do |ext|
|
150
|
+
File.join(@app_path, "config/webpack/webpack.config.#{ext}")
|
151
|
+
end
|
152
|
+
|
153
|
+
puts "[Shakapacker] Rspack config not found, checking for webpack config fallback..."
|
154
|
+
webpack_path = webpack_paths.find { |f| File.exist?(f) }
|
155
|
+
if webpack_path
|
156
|
+
$stderr.puts "⚠️ DEPRECATION WARNING: Using webpack config file for Rspack assets bundler."
|
157
|
+
$stderr.puts " Please create config/rspack/rspack.config.js and migrate your configuration."
|
158
|
+
$stderr.puts " Using: #{webpack_path}"
|
159
|
+
return webpack_path
|
160
|
+
end
|
161
|
+
|
162
|
+
# No config found
|
163
|
+
$stderr.puts "[Shakapacker] ERROR: rspack config #{rspack_paths.last} not found, please run 'bundle exec rails shakapacker:install' to install Shakapacker with default configs or create the missing config file."
|
164
|
+
exit(1)
|
165
|
+
end
|
166
|
+
|
29
167
|
def find_webpack_config
|
30
168
|
possible_paths = %w[ts js].map do |ext|
|
31
169
|
File.join(@app_path, "config/webpack/webpack.config.#{ext}")
|
32
170
|
end
|
171
|
+
puts "[Shakapacker] Looking for Webpack config in: #{possible_paths.join(", ")}"
|
33
172
|
path = possible_paths.find { |f| File.exist?(f) }
|
34
173
|
unless path
|
35
|
-
$stderr.puts "webpack config #{possible_paths.last} not found, please run 'bundle exec rails shakapacker:install' to install Shakapacker with default configs or add the missing config file for your custom environment."
|
36
|
-
exit
|
174
|
+
$stderr.puts "[Shakapacker] ERROR: webpack config #{possible_paths.last} not found, please run 'bundle exec rails shakapacker:install' to install Shakapacker with default configs or add the missing config file for your custom environment."
|
175
|
+
exit(1)
|
37
176
|
end
|
177
|
+
puts "[Shakapacker] Found Webpack config: #{path}"
|
38
178
|
path
|
39
179
|
end
|
40
180
|
end
|
data/lib/shakapacker/version.rb
CHANGED
@@ -4,48 +4,10 @@ require_relative "runner"
|
|
4
4
|
|
5
5
|
module Shakapacker
|
6
6
|
class WebpackRunner < Shakapacker::Runner
|
7
|
-
|
8
|
-
|
9
|
-
"
|
10
|
-
|
11
|
-
"-h",
|
12
|
-
"version",
|
13
|
-
"v",
|
14
|
-
"--version",
|
15
|
-
"-v",
|
16
|
-
"info",
|
17
|
-
"i"
|
18
|
-
].freeze
|
19
|
-
|
20
|
-
def run
|
21
|
-
env = Shakapacker::Compiler.env
|
22
|
-
env["SHAKAPACKER_CONFIG"] = @shakapacker_config
|
23
|
-
env["NODE_OPTIONS"] = ENV["NODE_OPTIONS"] || ""
|
24
|
-
|
25
|
-
cmd = build_cmd
|
26
|
-
|
27
|
-
if @argv.delete("--debug-shakapacker")
|
28
|
-
env["NODE_OPTIONS"] = "#{env["NODE_OPTIONS"]} --inspect-brk"
|
29
|
-
end
|
30
|
-
|
31
|
-
if @argv.delete "--trace-deprecation"
|
32
|
-
env["NODE_OPTIONS"] = "#{env["NODE_OPTIONS"]} --trace-deprecation"
|
33
|
-
end
|
34
|
-
|
35
|
-
if @argv.delete "--no-deprecation"
|
36
|
-
env["NODE_OPTIONS"] = "#{env["NODE_OPTIONS"]} --no-deprecation"
|
37
|
-
end
|
38
|
-
|
39
|
-
# Webpack commands are not compatible with --config option.
|
40
|
-
if (@argv & WEBPACK_COMMANDS).empty?
|
41
|
-
cmd += ["--config", @webpack_config]
|
42
|
-
end
|
43
|
-
|
44
|
-
cmd += @argv
|
45
|
-
|
46
|
-
Dir.chdir(@app_path) do
|
47
|
-
Kernel.exec env, *cmd
|
48
|
-
end
|
7
|
+
def self.run(argv)
|
8
|
+
$stdout.sync = true
|
9
|
+
ENV["NODE_ENV"] ||= (ENV["RAILS_ENV"] == "production") ? "production" : "development"
|
10
|
+
new(argv).run
|
49
11
|
end
|
50
12
|
|
51
13
|
private
|
@@ -2,10 +2,14 @@ install_template_path = File.expand_path("../../install/template.rb", __dir__).f
|
|
2
2
|
bin_path = ENV["BUNDLE_BIN"] || Rails.root.join("bin")
|
3
3
|
|
4
4
|
namespace :shakapacker do
|
5
|
-
desc "Install Shakapacker in this application"
|
6
|
-
task install: [:check_node] do |task|
|
5
|
+
desc "Install Shakapacker in this application (use ASSETS_BUNDLER=rspack for Rspack)"
|
6
|
+
task :install, [:bundler] => [:check_node] do |task, args|
|
7
7
|
Shakapacker::Configuration.installing = true
|
8
8
|
|
9
|
+
if args[:bundler] == "rspack" || ENV["ASSETS_BUNDLER"] == "rspack"
|
10
|
+
ENV["SHAKAPACKER_ASSETS_BUNDLER"] = "rspack"
|
11
|
+
end
|
12
|
+
|
9
13
|
prefix = task.name.split(/#|shakapacker:install/).first
|
10
14
|
|
11
15
|
if Rails::VERSION::MAJOR >= 5
|
data/package/config.js
CHANGED
@@ -53,4 +53,28 @@ if (config.manifest_path) {
|
|
53
53
|
// Ensure no duplicate hash functions exist in the returned config object
|
54
54
|
config.integrity.hash_functions = [...new Set(config.integrity.hash_functions)]
|
55
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
|
+
|
56
80
|
module.exports = config
|
@@ -1,16 +1,30 @@
|
|
1
1
|
/* eslint global-require: 0 */
|
2
2
|
/* eslint import/no-dynamic-require: 0 */
|
3
3
|
|
4
|
-
const { existsSync, readdirSync } = require("fs")
|
5
4
|
const { basename, dirname, join, relative, resolve } = require("path")
|
5
|
+
const { existsSync, readdirSync } = require("fs")
|
6
6
|
const extname = require("path-complete-extname")
|
7
|
-
// TODO: Change to `const { WebpackAssetsManifest }` when dropping 'webpack-assets-manifest < 6.0.0' (Node >=20.10.0) support
|
8
|
-
const WebpackAssetsManifest = require("webpack-assets-manifest")
|
9
|
-
const webpack = require("webpack")
|
10
|
-
const rules = require("../rules")
|
11
7
|
const config = require("../config")
|
12
8
|
const { isProduction } = require("../env")
|
13
|
-
|
9
|
+
|
10
|
+
const pluginsPath = resolve(
|
11
|
+
__dirname,
|
12
|
+
"..",
|
13
|
+
"plugins",
|
14
|
+
`${config.assets_bundler}.js`
|
15
|
+
)
|
16
|
+
const { getPlugins } = require(pluginsPath)
|
17
|
+
const rulesPath = resolve(
|
18
|
+
__dirname,
|
19
|
+
"..",
|
20
|
+
"rules",
|
21
|
+
`${config.assets_bundler}.js`
|
22
|
+
)
|
23
|
+
const rules = require(rulesPath)
|
24
|
+
|
25
|
+
// Don't use contentHash except for production for performance
|
26
|
+
// https://webpack.js.org/guides/build-performance/#avoid-production-specific-tooling
|
27
|
+
const hash = isProduction || config.useContentHash ? "-[contenthash]" : ""
|
14
28
|
|
15
29
|
const getFilesInDirectory = (dir, includeNested) => {
|
16
30
|
if (!existsSync(dir)) {
|
@@ -73,63 +87,6 @@ const getModulePaths = () => {
|
|
73
87
|
return result
|
74
88
|
}
|
75
89
|
|
76
|
-
// TODO: Remove WebpackAssetsManifestConstructor workaround when dropping 'webpack-assets-manifest < 6.0.0' (Node >=20.10.0) support
|
77
|
-
const WebpackAssetsManifestConstructor =
|
78
|
-
"WebpackAssetsManifest" in WebpackAssetsManifest
|
79
|
-
? WebpackAssetsManifest.WebpackAssetsManifest
|
80
|
-
: WebpackAssetsManifest
|
81
|
-
const getPlugins = () => {
|
82
|
-
const plugins = [
|
83
|
-
new webpack.EnvironmentPlugin(process.env),
|
84
|
-
new WebpackAssetsManifestConstructor({
|
85
|
-
entrypoints: true,
|
86
|
-
writeToDisk: true,
|
87
|
-
output: config.manifestPath,
|
88
|
-
entrypointsUseAssets: true,
|
89
|
-
publicPath: config.publicPathWithoutCDN,
|
90
|
-
integrity: config.integrity.enabled,
|
91
|
-
integrityHashes: config.integrity.hash_functions
|
92
|
-
})
|
93
|
-
]
|
94
|
-
|
95
|
-
if (moduleExists("css-loader") && moduleExists("mini-css-extract-plugin")) {
|
96
|
-
const hash = isProduction || config.useContentHash ? "-[contenthash:8]" : ""
|
97
|
-
const MiniCssExtractPlugin = require("mini-css-extract-plugin")
|
98
|
-
plugins.push(
|
99
|
-
new MiniCssExtractPlugin({
|
100
|
-
filename: `css/[name]${hash}.css`,
|
101
|
-
chunkFilename: `css/[id]${hash}.css`,
|
102
|
-
// For projects where css ordering has been mitigated through consistent use of scoping or naming conventions,
|
103
|
-
// the css order warnings can be disabled by setting the ignoreOrder flag.
|
104
|
-
// Read: https://stackoverflow.com/questions/51971857/mini-css-extract-plugin-warning-in-chunk-chunkname-mini-css-extract-plugin-con
|
105
|
-
ignoreOrder: config.css_extract_ignore_order_warnings
|
106
|
-
})
|
107
|
-
)
|
108
|
-
}
|
109
|
-
|
110
|
-
if (
|
111
|
-
moduleExists("webpack-subresource-integrity") &&
|
112
|
-
config.integrity.enabled
|
113
|
-
) {
|
114
|
-
const {
|
115
|
-
SubresourceIntegrityPlugin
|
116
|
-
} = require("webpack-subresource-integrity")
|
117
|
-
|
118
|
-
plugins.push(
|
119
|
-
new SubresourceIntegrityPlugin({
|
120
|
-
hashFuncNames: config.integrity.hash_functions,
|
121
|
-
enabled: isProduction
|
122
|
-
})
|
123
|
-
)
|
124
|
-
}
|
125
|
-
|
126
|
-
return plugins
|
127
|
-
}
|
128
|
-
|
129
|
-
// Don't use contentHash except for production for performance
|
130
|
-
// https://webpack.js.org/guides/build-performance/#avoid-production-specific-tooling
|
131
|
-
const hash = isProduction || config.useContentHash ? "-[contenthash]" : ""
|
132
|
-
|
133
90
|
module.exports = {
|
134
91
|
mode: "production",
|
135
92
|
output: {
|
@@ -160,12 +117,10 @@ module.exports = {
|
|
160
117
|
|
161
118
|
optimization: {
|
162
119
|
splitChunks: { chunks: "all" },
|
163
|
-
|
164
120
|
runtimeChunk: "single"
|
165
121
|
},
|
166
122
|
|
167
123
|
module: {
|
168
|
-
strictExportPresence: true,
|
169
124
|
rules
|
170
125
|
}
|
171
126
|
}
|
@@ -1,13 +1,68 @@
|
|
1
1
|
const { merge } = require("webpack-merge")
|
2
|
-
|
2
|
+
const config = require("../config")
|
3
3
|
const baseConfig = require("./base")
|
4
4
|
const webpackDevServerConfig = require("../webpackDevServerConfig")
|
5
5
|
const { runningWebpackDevServer } = require("../env")
|
6
|
+
const { moduleExists } = require("../utils/helpers")
|
6
7
|
|
7
|
-
const
|
8
|
+
const baseDevConfig = {
|
8
9
|
mode: "development",
|
9
|
-
devtool: "cheap-module-source-map"
|
10
|
-
|
10
|
+
devtool: "cheap-module-source-map"
|
11
|
+
}
|
12
|
+
|
13
|
+
const webpackDevConfig = () => {
|
14
|
+
const webpackConfig = {
|
15
|
+
...baseDevConfig,
|
16
|
+
...(runningWebpackDevServer && { devServer: webpackDevServerConfig() })
|
17
|
+
}
|
18
|
+
|
19
|
+
const devServerConfig = webpackDevServerConfig()
|
20
|
+
if (
|
21
|
+
runningWebpackDevServer &&
|
22
|
+
devServerConfig.hot &&
|
23
|
+
moduleExists("@pmmmwh/react-refresh-webpack-plugin")
|
24
|
+
) {
|
25
|
+
// eslint-disable-next-line global-require
|
26
|
+
const ReactRefreshWebpackPlugin = require("@pmmmwh/react-refresh-webpack-plugin")
|
27
|
+
webpackConfig.plugins = [
|
28
|
+
...(webpackConfig.plugins || []),
|
29
|
+
new ReactRefreshWebpackPlugin()
|
30
|
+
]
|
31
|
+
}
|
32
|
+
|
33
|
+
return webpackConfig
|
11
34
|
}
|
12
35
|
|
13
|
-
|
36
|
+
const rspackDevConfig = () => {
|
37
|
+
const devServerConfig = webpackDevServerConfig()
|
38
|
+
const rspackConfig = {
|
39
|
+
...baseDevConfig,
|
40
|
+
devServer: {
|
41
|
+
...devServerConfig,
|
42
|
+
devMiddleware: {
|
43
|
+
...devServerConfig.devMiddleware,
|
44
|
+
writeToDisk: (filePath) => !filePath.includes(".hot-update.")
|
45
|
+
}
|
46
|
+
}
|
47
|
+
}
|
48
|
+
|
49
|
+
if (
|
50
|
+
runningWebpackDevServer &&
|
51
|
+
devServerConfig.hot &&
|
52
|
+
moduleExists("@rspack/plugin-react-refresh")
|
53
|
+
) {
|
54
|
+
// eslint-disable-next-line global-require
|
55
|
+
const ReactRefreshPlugin = require("@rspack/plugin-react-refresh")
|
56
|
+
rspackConfig.plugins = [
|
57
|
+
...(rspackConfig.plugins || []),
|
58
|
+
new ReactRefreshPlugin()
|
59
|
+
]
|
60
|
+
}
|
61
|
+
|
62
|
+
return rspackConfig
|
63
|
+
}
|
64
|
+
|
65
|
+
const bundlerConfig =
|
66
|
+
config.assets_bundler === "rspack" ? rspackDevConfig() : webpackDevConfig()
|
67
|
+
|
68
|
+
module.exports = merge(baseConfig, bundlerConfig)
|
@@ -1,47 +1,50 @@
|
|
1
1
|
/* eslint global-require: 0 */
|
2
2
|
/* eslint import/no-dynamic-require: 0 */
|
3
3
|
|
4
|
+
const { resolve } = require("path")
|
4
5
|
const { merge } = require("webpack-merge")
|
5
|
-
const CompressionPlugin = require("compression-webpack-plugin")
|
6
|
-
const TerserPlugin = require("terser-webpack-plugin")
|
7
6
|
const baseConfig = require("./base")
|
8
7
|
const { moduleExists } = require("../utils/helpers")
|
9
8
|
const config = require("../config")
|
10
9
|
|
10
|
+
const optimizationPath = resolve(
|
11
|
+
__dirname,
|
12
|
+
"..",
|
13
|
+
"optimization",
|
14
|
+
`${config.assets_bundler}.js`
|
15
|
+
)
|
16
|
+
const { getOptimization } = require(optimizationPath)
|
17
|
+
|
18
|
+
let CompressionPlugin = null
|
19
|
+
if (moduleExists("compression-webpack-plugin")) {
|
20
|
+
// eslint-disable-next-line global-require
|
21
|
+
CompressionPlugin = require("compression-webpack-plugin")
|
22
|
+
}
|
23
|
+
|
11
24
|
const getPlugins = () => {
|
12
25
|
const plugins = []
|
13
26
|
|
14
|
-
|
15
|
-
new CompressionPlugin({
|
16
|
-
filename: "[path][base].gz[query]",
|
17
|
-
algorithm: "gzip",
|
18
|
-
test: /\.(js|css|html|json|ico|svg|eot|otf|ttf|map)$/
|
19
|
-
})
|
20
|
-
)
|
21
|
-
|
22
|
-
if ("brotli" in process.versions) {
|
27
|
+
if (CompressionPlugin) {
|
23
28
|
plugins.push(
|
24
29
|
new CompressionPlugin({
|
25
|
-
filename: "[path][base].
|
26
|
-
algorithm: "
|
30
|
+
filename: "[path][base].gz[query]",
|
31
|
+
algorithm: "gzip",
|
27
32
|
test: /\.(js|css|html|json|ico|svg|eot|otf|ttf|map)$/
|
28
33
|
})
|
29
34
|
)
|
30
|
-
}
|
31
35
|
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
return new CssMinimizerPlugin()
|
36
|
+
if ("brotli" in process.versions) {
|
37
|
+
plugins.push(
|
38
|
+
new CompressionPlugin({
|
39
|
+
filename: "[path][base].br[query]",
|
40
|
+
algorithm: "brotliCompress",
|
41
|
+
test: /\.(js|css|html|json|ico|svg|eot|otf|ttf|map)$/
|
42
|
+
})
|
43
|
+
)
|
44
|
+
}
|
42
45
|
}
|
43
46
|
|
44
|
-
return
|
47
|
+
return plugins
|
45
48
|
}
|
46
49
|
|
47
50
|
const productionConfig = {
|
@@ -49,32 +52,7 @@ const productionConfig = {
|
|
49
52
|
stats: "normal",
|
50
53
|
bail: true,
|
51
54
|
plugins: getPlugins(),
|
52
|
-
optimization:
|
53
|
-
minimizer: [
|
54
|
-
tryCssMinimizer(),
|
55
|
-
new TerserPlugin({
|
56
|
-
parallel: Number.parseInt(process.env.SHAKAPACKER_PARALLEL, 10) || true,
|
57
|
-
terserOptions: {
|
58
|
-
parse: {
|
59
|
-
// Let terser parse ecma 8 code but always output
|
60
|
-
// ES5 compliant code for older browsers
|
61
|
-
ecma: 8
|
62
|
-
},
|
63
|
-
compress: {
|
64
|
-
ecma: 5,
|
65
|
-
warnings: false,
|
66
|
-
comparisons: false
|
67
|
-
},
|
68
|
-
mangle: { safari10: true },
|
69
|
-
output: {
|
70
|
-
ecma: 5,
|
71
|
-
comments: false,
|
72
|
-
ascii_only: true
|
73
|
-
}
|
74
|
-
}
|
75
|
-
})
|
76
|
-
].filter(Boolean)
|
77
|
-
}
|
55
|
+
optimization: getOptimization()
|
78
56
|
}
|
79
57
|
|
80
58
|
if (config.useContentHash === false) {
|
@@ -1,3 +1,19 @@
|
|
1
|
+
const { merge } = require("webpack-merge")
|
2
|
+
const config = require("../config")
|
1
3
|
const baseConfig = require("./base")
|
2
4
|
|
3
|
-
|
5
|
+
const rspackTestConfig = () => ({
|
6
|
+
mode: "development",
|
7
|
+
devtool: "cheap-module-source-map",
|
8
|
+
// Disable file watching in test mode
|
9
|
+
watchOptions: {
|
10
|
+
ignored: /node_modules/
|
11
|
+
}
|
12
|
+
})
|
13
|
+
|
14
|
+
const webpackTestConfig = () => ({})
|
15
|
+
|
16
|
+
const bundlerConfig =
|
17
|
+
config.assets_bundler === "rspack" ? rspackTestConfig() : webpackTestConfig()
|
18
|
+
|
19
|
+
module.exports = merge(baseConfig, bundlerConfig)
|