shakapacker 8.4.0 → 9.0.0.beta.0
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/dummy.yml +1 -1
- data/.github/workflows/generator.yml +4 -14
- data/.github/workflows/node.yml +1 -1
- data/CHANGELOG.md +4 -2
- data/Gemfile.lock +3 -3
- data/README.md +2 -2
- data/docs/css-modules-export-mode.md +288 -0
- data/docs/peer-dependencies.md +40 -0
- data/docs/rspack.md +190 -0
- data/docs/troubleshooting.md +5 -0
- data/lib/install/bin/shakapacker +14 -2
- data/lib/install/bin/shakapacker-rspack +13 -0
- data/lib/install/config/rspack/rspack.config.js +6 -0
- data/lib/install/config/shakapacker.yml +3 -0
- data/lib/install/package.json +30 -0
- data/lib/install/template.rb +12 -2
- data/lib/shakapacker/configuration.rb +12 -0
- data/lib/shakapacker/dev_server_runner.rb +17 -7
- data/lib/shakapacker/manifest.rb +3 -2
- data/lib/shakapacker/rspack_runner.rb +57 -0
- data/lib/shakapacker/runner.rb +48 -2
- data/lib/shakapacker/version.rb +1 -1
- data/package/environments/base.js +10 -65
- data/package/environments/development.js +18 -3
- data/package/environments/production.js +24 -51
- data/package/environments/test.js +15 -1
- data/package/index.d.ts +14 -0
- data/package/index.js +4 -2
- data/package/optimization/rspack.js +25 -0
- data/package/optimization/webpack.js +49 -0
- data/package/plugins/rspack.js +104 -0
- data/package/plugins/webpack.js +62 -0
- data/package/rules/css.js +1 -1
- data/package/rules/file.js +11 -5
- data/package/rules/less.js +1 -1
- data/package/rules/raw.js +11 -1
- data/package/rules/rspack.js +96 -0
- data/package/rules/sass.js +6 -2
- data/package/rules/stylus.js +1 -1
- data/package/utils/getStyleRule.js +16 -3
- data/package/utils/requireOrError.js +15 -0
- data/package.json +19 -31
- data/test/package/environments/base.test.js +1 -1
- data/test/package/rules/{index.test.js → webpack.test.js} +1 -1
- data/yarn.lock +2136 -726
- metadata +21 -11
- /data/package/rules/{index.js → webpack.js} +0 -0
@@ -0,0 +1,13 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
ENV["RAILS_ENV"] ||= "development"
|
4
|
+
ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile", __FILE__)
|
5
|
+
|
6
|
+
require "bundler/setup"
|
7
|
+
require "shakapacker"
|
8
|
+
require "shakapacker/rspack_runner"
|
9
|
+
|
10
|
+
APP_ROOT = File.expand_path("..", __dir__)
|
11
|
+
Dir.chdir(APP_ROOT) do
|
12
|
+
Shakapacker::RspackRunner.run(ARGV)
|
13
|
+
end
|
@@ -39,6 +39,9 @@ default: &default
|
|
39
39
|
# Select loader to use, available options are 'babel' (default), 'swc' or 'esbuild'
|
40
40
|
webpack_loader: 'babel'
|
41
41
|
|
42
|
+
# Select bundler to use, available options are 'webpack' (default) or 'rspack'
|
43
|
+
bundler: 'webpack'
|
44
|
+
|
42
45
|
# Raises an error if there is a mismatch in the shakapacker gem and npm package being used
|
43
46
|
ensure_consistent_versioning: true
|
44
47
|
|
@@ -0,0 +1,30 @@
|
|
1
|
+
{
|
2
|
+
"rspack": {
|
3
|
+
"@rspack/cli": "^1.0.0",
|
4
|
+
"@rspack/core": "^1.0.0",
|
5
|
+
"rspack-manifest-plugin": "^5.0.0"
|
6
|
+
},
|
7
|
+
"webpack": {
|
8
|
+
"mini-css-extract-plugin": "^2.0.0",
|
9
|
+
"terser-webpack-plugin": "^5.3.1",
|
10
|
+
"webpack": "^5.76.0",
|
11
|
+
"webpack-assets-manifest": "^5.0.6 || ^6.0.0",
|
12
|
+
"webpack-cli": "^4.9.2 || ^5.0.0 || ^6.0.0",
|
13
|
+
"webpack-dev-server": "^4.15.2 || ^5.2.2",
|
14
|
+
"webpack-merge": "^5.8.0 || ^6.0.0",
|
15
|
+
"webpack-subresource-integrity": "^5.1.0"
|
16
|
+
},
|
17
|
+
"common": {
|
18
|
+
"compression-webpack-plugin": "^9.0.0 || ^10.0.0|| ^11.0.0",
|
19
|
+
"css-loader": "^6.0.0 || ^7.0.0",
|
20
|
+
"sass-loader": "^13.0.0 || ^14.0.0 || ^15.0.0 || ^16.0.0",
|
21
|
+
"style-loader": "^3.0.0 || ^4.0.0"
|
22
|
+
},
|
23
|
+
"babel": {
|
24
|
+
"@babel/core": "^7.17.9",
|
25
|
+
"@babel/plugin-transform-runtime": "^7.17.0",
|
26
|
+
"@babel/preset-env": "^7.16.11",
|
27
|
+
"@babel/runtime": "^7.17.9",
|
28
|
+
"babel-loader": "^8.2.4 || ^9.0.0 || ^10.0.0"
|
29
|
+
}
|
30
|
+
}
|
data/lib/install/template.rb
CHANGED
@@ -8,7 +8,6 @@ require "package_json"
|
|
8
8
|
force_option = ENV["FORCE"] ? { force: true } : {}
|
9
9
|
|
10
10
|
copy_file "#{__dir__}/config/shakapacker.yml", "config/shakapacker.yml", force_option
|
11
|
-
remove_file "#{__dir__}/package.json" if force_option[:force]
|
12
11
|
|
13
12
|
say "Copying webpack core config"
|
14
13
|
directory "#{__dir__}/config/webpack", "config/webpack", force_option
|
@@ -112,7 +111,15 @@ rescue PackageJson::Error
|
|
112
111
|
end
|
113
112
|
|
114
113
|
def fetch_peer_dependencies
|
115
|
-
PackageJson.read("#{__dir__}
|
114
|
+
PackageJson.read("#{__dir__}").fetch(ENV["SHAKAPACKER_BUNDLER"] || "webpack")
|
115
|
+
end
|
116
|
+
|
117
|
+
def fetch_common_dependencies
|
118
|
+
ENV["SKIP_COMMON_LOADERS"] ? {} : PackageJson.read("#{__dir__}").fetch("common")
|
119
|
+
end
|
120
|
+
|
121
|
+
def fetch_babel_dependencies
|
122
|
+
ENV["USE_BABEL_PACKAGES"] ? PackageJson.read("#{__dir__}").fetch("babel") : {}
|
116
123
|
end
|
117
124
|
|
118
125
|
Dir.chdir(Rails.root) do
|
@@ -130,6 +137,9 @@ Dir.chdir(Rails.root) do
|
|
130
137
|
end
|
131
138
|
|
132
139
|
peers = fetch_peer_dependencies
|
140
|
+
peers = peers.merge(fetch_common_dependencies)
|
141
|
+
peers = peers.merge(fetch_babel_dependencies)
|
142
|
+
|
133
143
|
dev_dependency_packages = ["webpack-dev-server"]
|
134
144
|
|
135
145
|
dependencies_to_add = []
|
@@ -88,6 +88,18 @@ class Shakapacker::Configuration
|
|
88
88
|
fetch(:compiler_strategy)
|
89
89
|
end
|
90
90
|
|
91
|
+
def bundler
|
92
|
+
fetch(:bundler) || "webpack"
|
93
|
+
end
|
94
|
+
|
95
|
+
def rspack?
|
96
|
+
bundler == "rspack"
|
97
|
+
end
|
98
|
+
|
99
|
+
def webpack?
|
100
|
+
bundler == "webpack"
|
101
|
+
end
|
102
|
+
|
91
103
|
def fetch(key)
|
92
104
|
data.fetch(key, defaults[key])
|
93
105
|
end
|
@@ -75,12 +75,20 @@ module Shakapacker
|
|
75
75
|
env["NODE_OPTIONS"] = "#{env["NODE_OPTIONS"]} --inspect-brk --trace-warnings"
|
76
76
|
end
|
77
77
|
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
78
|
+
# Add bundler-specific flags and config
|
79
|
+
bundler = get_bundler_type
|
80
|
+
if bundler == "webpack"
|
81
|
+
cmd += ["--config", @webpack_config]
|
82
|
+
cmd += ["--progress", "--color"] if @pretty
|
83
|
+
# Default behavior of webpack-dev-server is @hot = true
|
84
|
+
cmd += ["--hot", "only"] if @hot == "only"
|
85
|
+
cmd += ["--no-hot"] if !@hot
|
86
|
+
elsif bundler == "rspack"
|
87
|
+
# Only add config for rspack if it's not a rspack-specific command
|
88
|
+
cmd += ["--config", @webpack_config]
|
89
|
+
# Rspack supports --hot but not --no-hot or --progress/--color
|
90
|
+
cmd += ["--hot"] if @hot && @hot != false
|
91
|
+
end
|
84
92
|
|
85
93
|
cmd += @argv
|
86
94
|
|
@@ -90,7 +98,9 @@ module Shakapacker
|
|
90
98
|
end
|
91
99
|
|
92
100
|
def build_cmd
|
93
|
-
|
101
|
+
bundler = get_bundler_type
|
102
|
+
command = bundler == "rspack" ? "rspack" : "webpack"
|
103
|
+
package_json.manager.native_exec_command(command, ["serve"])
|
94
104
|
end
|
95
105
|
end
|
96
106
|
end
|
data/lib/shakapacker/manifest.rb
CHANGED
@@ -114,9 +114,10 @@ Shakapacker can't find #{bundle_name} in #{config.manifest_path}. Possible cause
|
|
114
114
|
2. Your app has code with a non-standard extension (like a `.jsx` file) but the extension is not in the `extensions` config in `config/shakapacker.yml`
|
115
115
|
3. You have set compile: false (see `config/shakapacker.yml`) for this environment
|
116
116
|
(unless you are using the `bin/shakapacker -w` or the `bin/shakapacker-dev-server`, in which case maybe you aren't running the dev server in the background?)
|
117
|
-
4. webpack has not yet FINISHED running to reflect updates.
|
117
|
+
4. Your bundler (webpack/rspack) has not yet FINISHED running to reflect updates.
|
118
118
|
5. You have misconfigured Shakapacker's `config/shakapacker.yml` file.
|
119
|
-
6. Your
|
119
|
+
6. Your bundler configuration is not creating a manifest with the expected structure.
|
120
|
+
7. There's a mismatch between your bundler choice (webpack vs rspack) and the manifest format.
|
120
121
|
|
121
122
|
Your manifest contains:
|
122
123
|
#{JSON.pretty_generate(@data)}
|
@@ -0,0 +1,57 @@
|
|
1
|
+
require "shellwords"
|
2
|
+
|
3
|
+
require_relative "runner"
|
4
|
+
|
5
|
+
module Shakapacker
|
6
|
+
class RspackRunner < Shakapacker::Runner
|
7
|
+
RSPACK_COMMANDS = [
|
8
|
+
"help",
|
9
|
+
"h",
|
10
|
+
"--help",
|
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
|
+
# Rspack commands are not compatible with --config option.
|
40
|
+
if (@argv & RSPACK_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
|
49
|
+
end
|
50
|
+
|
51
|
+
private
|
52
|
+
|
53
|
+
def build_cmd
|
54
|
+
package_json.manager.native_exec_command("rspack")
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
data/lib/shakapacker/runner.rb
CHANGED
@@ -1,7 +1,9 @@
|
|
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
|
@@ -16,7 +18,12 @@ module Shakapacker
|
|
16
18
|
|
17
19
|
@app_path = File.expand_path(".", Dir.pwd)
|
18
20
|
@shakapacker_config = ENV["SHAKAPACKER_CONFIG"] || File.join(@app_path, "config/shakapacker.yml")
|
19
|
-
@
|
21
|
+
@config = Configuration.new(
|
22
|
+
root_path: Pathname.new(@app_path),
|
23
|
+
config_path: Pathname.new(@shakapacker_config),
|
24
|
+
env: ENV["RAILS_ENV"] || ENV["NODE_ENV"] || "development"
|
25
|
+
)
|
26
|
+
@webpack_config = find_bundler_config
|
20
27
|
|
21
28
|
Shakapacker::Utils::Manager.error_unless_package_manager_is_obvious!
|
22
29
|
end
|
@@ -26,6 +33,45 @@ module Shakapacker
|
|
26
33
|
end
|
27
34
|
|
28
35
|
private
|
36
|
+
def find_bundler_config
|
37
|
+
if @config.rspack?
|
38
|
+
find_rspack_config_with_fallback
|
39
|
+
else
|
40
|
+
find_webpack_config
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
def get_bundler_type
|
45
|
+
@config.bundler
|
46
|
+
end
|
47
|
+
|
48
|
+
def find_rspack_config_with_fallback
|
49
|
+
# First try rspack-specific paths
|
50
|
+
rspack_paths = %w[ts js].map do |ext|
|
51
|
+
File.join(@app_path, "config/rspack/rspack.config.#{ext}")
|
52
|
+
end
|
53
|
+
|
54
|
+
rspack_path = rspack_paths.find { |f| File.exist?(f) }
|
55
|
+
return rspack_path if rspack_path
|
56
|
+
|
57
|
+
# Fallback to webpack config with deprecation warning
|
58
|
+
webpack_paths = %w[ts js].map do |ext|
|
59
|
+
File.join(@app_path, "config/webpack/webpack.config.#{ext}")
|
60
|
+
end
|
61
|
+
|
62
|
+
webpack_path = webpack_paths.find { |f| File.exist?(f) }
|
63
|
+
if webpack_path
|
64
|
+
$stderr.puts "⚠️ DEPRECATION WARNING: Using webpack config file for Rspack bundler."
|
65
|
+
$stderr.puts " Please create config/rspack/rspack.config.js and migrate your configuration."
|
66
|
+
$stderr.puts " Using: #{webpack_path}"
|
67
|
+
return webpack_path
|
68
|
+
end
|
69
|
+
|
70
|
+
# No config found
|
71
|
+
$stderr.puts "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."
|
72
|
+
exit(1)
|
73
|
+
end
|
74
|
+
|
29
75
|
def find_webpack_config
|
30
76
|
possible_paths = %w[ts js].map do |ext|
|
31
77
|
File.join(@app_path, "config/webpack/webpack.config.#{ext}")
|
@@ -33,7 +79,7 @@ module Shakapacker
|
|
33
79
|
path = possible_paths.find { |f| File.exist?(f) }
|
34
80
|
unless path
|
35
81
|
$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
|
82
|
+
exit(1)
|
37
83
|
end
|
38
84
|
path
|
39
85
|
end
|
data/lib/shakapacker/version.rb
CHANGED
@@ -1,16 +1,20 @@
|
|
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(__dirname, "..", "plugins", `${config.bundler}.js`)
|
11
|
+
const { getPlugins } = require(pluginsPath)
|
12
|
+
const rulesPath = resolve(__dirname, "..", "rules", `${config.bundler}.js`)
|
13
|
+
const rules = require(rulesPath)
|
14
|
+
|
15
|
+
// Don't use contentHash except for production for performance
|
16
|
+
// https://webpack.js.org/guides/build-performance/#avoid-production-specific-tooling
|
17
|
+
const hash = isProduction || config.useContentHash ? "-[contenthash]" : ""
|
14
18
|
|
15
19
|
const getFilesInDirectory = (dir, includeNested) => {
|
16
20
|
if (!existsSync(dir)) {
|
@@ -73,63 +77,6 @@ const getModulePaths = () => {
|
|
73
77
|
return result
|
74
78
|
}
|
75
79
|
|
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
80
|
module.exports = {
|
134
81
|
mode: "production",
|
135
82
|
output: {
|
@@ -160,12 +107,10 @@ module.exports = {
|
|
160
107
|
|
161
108
|
optimization: {
|
162
109
|
splitChunks: { chunks: "all" },
|
163
|
-
|
164
110
|
runtimeChunk: "single"
|
165
111
|
},
|
166
112
|
|
167
113
|
module: {
|
168
|
-
strictExportPresence: true,
|
169
114
|
rules
|
170
115
|
}
|
171
116
|
}
|
@@ -1,13 +1,28 @@
|
|
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
6
|
|
7
|
-
const
|
7
|
+
const webpackDevConfig = {
|
8
8
|
mode: "development",
|
9
9
|
devtool: "cheap-module-source-map",
|
10
10
|
...(runningWebpackDevServer && { devServer: webpackDevServerConfig() })
|
11
11
|
}
|
12
12
|
|
13
|
-
|
13
|
+
const rspackDevConfig = {
|
14
|
+
mode: "development",
|
15
|
+
devtool: "cheap-module-source-map",
|
16
|
+
// Force writing assets to disk in development for Rails compatibility
|
17
|
+
devServer: {
|
18
|
+
...webpackDevServerConfig(),
|
19
|
+
devMiddleware: {
|
20
|
+
writeToDisk: true
|
21
|
+
}
|
22
|
+
}
|
23
|
+
}
|
24
|
+
|
25
|
+
const bundlerConfig =
|
26
|
+
config.bundler === "rspack" ? rspackDevConfig : webpackDevConfig
|
27
|
+
|
28
|
+
module.exports = merge(baseConfig, bundlerConfig)
|
@@ -2,46 +2,44 @@
|
|
2
2
|
/* eslint import/no-dynamic-require: 0 */
|
3
3
|
|
4
4
|
const { merge } = require("webpack-merge")
|
5
|
-
const
|
6
|
-
const TerserPlugin = require("terser-webpack-plugin")
|
5
|
+
const { resolve } = require("path")
|
7
6
|
const baseConfig = require("./base")
|
8
7
|
const { moduleExists } = require("../utils/helpers")
|
9
8
|
const config = require("../config")
|
10
9
|
|
10
|
+
const path = resolve(__dirname, "..", "optimization", `${config.bundler}.js`)
|
11
|
+
const { getOptimization } = require(path)
|
12
|
+
|
13
|
+
let CompressionPlugin = null
|
14
|
+
if (moduleExists("compression-webpack-plugin")) {
|
15
|
+
// eslint-disable-next-line global-require
|
16
|
+
CompressionPlugin = require("compression-webpack-plugin")
|
17
|
+
}
|
18
|
+
|
11
19
|
const getPlugins = () => {
|
12
20
|
const plugins = []
|
13
21
|
|
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) {
|
22
|
+
if (CompressionPlugin) {
|
23
23
|
plugins.push(
|
24
24
|
new CompressionPlugin({
|
25
|
-
filename: "[path][base].
|
26
|
-
algorithm: "
|
25
|
+
filename: "[path][base].gz[query]",
|
26
|
+
algorithm: "gzip",
|
27
27
|
test: /\.(js|css|html|json|ico|svg|eot|otf|ttf|map)$/
|
28
28
|
})
|
29
29
|
)
|
30
|
-
}
|
31
30
|
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
return new CssMinimizerPlugin()
|
31
|
+
if ("brotli" in process.versions) {
|
32
|
+
plugins.push(
|
33
|
+
new CompressionPlugin({
|
34
|
+
filename: "[path][base].br[query]",
|
35
|
+
algorithm: "brotliCompress",
|
36
|
+
test: /\.(js|css|html|json|ico|svg|eot|otf|ttf|map)$/
|
37
|
+
})
|
38
|
+
)
|
39
|
+
}
|
42
40
|
}
|
43
41
|
|
44
|
-
return
|
42
|
+
return plugins
|
45
43
|
}
|
46
44
|
|
47
45
|
const productionConfig = {
|
@@ -49,32 +47,7 @@ const productionConfig = {
|
|
49
47
|
stats: "normal",
|
50
48
|
bail: true,
|
51
49
|
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
|
-
}
|
50
|
+
optimization: getOptimization()
|
78
51
|
}
|
79
52
|
|
80
53
|
if (config.useContentHash === false) {
|
@@ -1,3 +1,17 @@
|
|
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 bundlerConfig =
|
15
|
+
config.bundler === "rspack" ? rspackTestConfig : baseConfig
|
16
|
+
|
17
|
+
module.exports = merge(baseConfig, bundlerConfig)
|
data/package/index.d.ts
CHANGED
@@ -81,6 +81,20 @@ declare module 'shakapacker' {
|
|
81
81
|
export * from 'webpack-merge'
|
82
82
|
}
|
83
83
|
|
84
|
+
declare module 'shakapacker/rspack' {
|
85
|
+
import type { RspackOptions, RuleSetRule } from '@rspack/core'
|
86
|
+
|
87
|
+
export const config: Config
|
88
|
+
export function generateRspackConfig(extraConfig?: RspackOptions): RspackOptions
|
89
|
+
export const baseConfig: RspackOptions
|
90
|
+
export const env: Env
|
91
|
+
export const rules: RuleSetRule[]
|
92
|
+
export function moduleExists(packageName: string): boolean
|
93
|
+
export function canProcess<T = unknown>(rule: string, fn: (modulePath: string) => T): T | null
|
94
|
+
export const inliningCss: boolean
|
95
|
+
export * from 'webpack-merge'
|
96
|
+
}
|
97
|
+
|
84
98
|
declare module 'shakapacker/package/babel/preset.js' {
|
85
99
|
import { ConfigAPI, PluginItem, TransformOptions } from '@babel/core'
|
86
100
|
|
data/package/index.js
CHANGED
@@ -4,9 +4,11 @@
|
|
4
4
|
const webpackMerge = require("webpack-merge")
|
5
5
|
const { resolve } = require("path")
|
6
6
|
const { existsSync } = require("fs")
|
7
|
-
const baseConfig = require("./environments/base")
|
8
|
-
const rules = require("./rules")
|
9
7
|
const config = require("./config")
|
8
|
+
const baseConfig = require("./environments/base")
|
9
|
+
|
10
|
+
const rulesPath = resolve(__dirname, "rules", `${config.bundler}.js`)
|
11
|
+
const rules = require(rulesPath)
|
10
12
|
const devServer = require("./dev_server")
|
11
13
|
const env = require("./env")
|
12
14
|
const { moduleExists, canProcess } = require("./utils/helpers")
|
@@ -0,0 +1,25 @@
|
|
1
|
+
const { requireOrError } = require("../utils/requireOrError")
|
2
|
+
|
3
|
+
const { rspack } = requireOrError("@rspack/core")
|
4
|
+
|
5
|
+
const getOptimization = () => {
|
6
|
+
// Use Rspack's built-in minification instead of terser-webpack-plugin
|
7
|
+
const result = { minimize: true }
|
8
|
+
try {
|
9
|
+
result.minimizer = [
|
10
|
+
new rspack.SwcJsMinimizerRspackPlugin(),
|
11
|
+
new rspack.LightningCssMinimizerRspackPlugin()
|
12
|
+
]
|
13
|
+
} catch (error) {
|
14
|
+
// eslint-disable-next-line no-console
|
15
|
+
console.warn(
|
16
|
+
"[SHAKAPACKER]: Warning: Could not configure Rspack minimizers:",
|
17
|
+
error.message
|
18
|
+
)
|
19
|
+
}
|
20
|
+
return result
|
21
|
+
}
|
22
|
+
|
23
|
+
module.exports = {
|
24
|
+
getOptimization
|
25
|
+
}
|