vite_ruby 3.8.3 → 3.9.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +18 -0
- data/exe/vite +3 -3
- data/lib/tasks/vite.rake +35 -35
- data/lib/vite_ruby/build.rb +4 -4
- data/lib/vite_ruby/builder.rb +13 -13
- data/lib/vite_ruby/cli/build.rb +6 -6
- data/lib/vite_ruby/cli/clobber.rb +4 -4
- data/lib/vite_ruby/cli/dev.rb +3 -3
- data/lib/vite_ruby/cli/file_utils.rb +8 -8
- data/lib/vite_ruby/cli/install.rb +26 -26
- data/lib/vite_ruby/cli/ssr.rb +8 -8
- data/lib/vite_ruby/cli/upgrade.rb +4 -4
- data/lib/vite_ruby/cli/upgrade_packages.rb +3 -3
- data/lib/vite_ruby/cli/version.rb +1 -1
- data/lib/vite_ruby/cli/vite.rb +13 -13
- data/lib/vite_ruby/cli.rb +13 -13
- data/lib/vite_ruby/commands.rb +17 -17
- data/lib/vite_ruby/compatibility_check.rb +7 -7
- data/lib/vite_ruby/config.rb +41 -44
- data/lib/vite_ruby/dev_server_proxy.rb +21 -20
- data/lib/vite_ruby/error.rb +1 -1
- data/lib/vite_ruby/io.rb +3 -3
- data/lib/vite_ruby/manifest.rb +24 -22
- data/lib/vite_ruby/missing_entrypoint_error.rb +7 -7
- data/lib/vite_ruby/missing_executable_error.rb +1 -1
- data/lib/vite_ruby/runner.rb +9 -9
- data/lib/vite_ruby/version.rb +3 -3
- data/lib/vite_ruby.rb +26 -26
- metadata +20 -5
data/lib/vite_ruby/cli/vite.rb
CHANGED
@@ -1,34 +1,34 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
class ViteRuby::CLI::Vite < Dry::CLI::Command
|
4
|
-
CURRENT_ENV = ENV[
|
4
|
+
CURRENT_ENV = ENV["RACK_ENV"] || ENV["RAILS_ENV"]
|
5
5
|
|
6
6
|
def self.executable_options
|
7
|
-
option(:mode, default: self::DEFAULT_ENV, values: %w[development production test], aliases: [
|
8
|
-
option(:node_options, desc:
|
9
|
-
option(:inspect, desc:
|
10
|
-
option(:trace_deprecation, desc:
|
7
|
+
option(:mode, default: self::DEFAULT_ENV, values: %w[development production test], aliases: ["m"], desc: "The build mode for Vite")
|
8
|
+
option(:node_options, desc: "Node options for the Vite executable", aliases: ["node-options"])
|
9
|
+
option(:inspect, desc: "Run Vite in a debugging session with node --inspect-brk", aliases: ["inspect-brk"], type: :boolean)
|
10
|
+
option(:trace_deprecation, desc: "Run Vite in debugging mode with node --trace-deprecation", aliases: ["trace-deprecation"], type: :boolean)
|
11
11
|
end
|
12
12
|
|
13
13
|
def self.shared_options
|
14
14
|
executable_options
|
15
|
-
option(:debug, desc:
|
16
|
-
option(:clobber, desc:
|
15
|
+
option(:debug, desc: "Run Vite in verbose mode, printing all debugging output", aliases: ["verbose"], type: :boolean)
|
16
|
+
option(:clobber, desc: "Clear cache and previous builds", type: :boolean, aliases: %w[clean clear])
|
17
17
|
end
|
18
18
|
|
19
19
|
def call(mode:, args: [], clobber: false, node_options: nil, inspect: nil, trace_deprecation: nil, **boolean_opts)
|
20
|
-
ViteRuby.env[
|
20
|
+
ViteRuby.env["VITE_RUBY_MODE"] = mode
|
21
21
|
ViteRuby.commands.clobber if clobber
|
22
22
|
|
23
23
|
node_options = [
|
24
24
|
node_options,
|
25
|
-
(
|
26
|
-
(
|
27
|
-
].compact.join(
|
25
|
+
("--inspect-brk" if inspect),
|
26
|
+
("--trace-deprecation" if trace_deprecation),
|
27
|
+
].compact.join(" ")
|
28
28
|
|
29
|
-
args << %(--node-options="#{
|
29
|
+
args << %(--node-options="#{node_options}") unless node_options.empty?
|
30
30
|
|
31
|
-
boolean_opts.map { |name, value| args << "--#{
|
31
|
+
boolean_opts.map { |name, value| args << "--#{name}" if value }
|
32
32
|
|
33
33
|
yield(args)
|
34
34
|
end
|
data/lib/vite_ruby/cli.rb
CHANGED
@@ -1,30 +1,30 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
3
|
+
require "dry/cli"
|
4
4
|
|
5
5
|
# Public: Command line interface that allows to install the library, and run
|
6
6
|
# simple commands.
|
7
7
|
class ViteRuby::CLI
|
8
8
|
extend Dry::CLI::Registry
|
9
9
|
|
10
|
-
register
|
11
|
-
register
|
12
|
-
register
|
13
|
-
register
|
14
|
-
register
|
15
|
-
register
|
16
|
-
register
|
17
|
-
register
|
10
|
+
register "build", Build, aliases: ["b"]
|
11
|
+
register "clobber", Clobber, aliases: %w[clean clear]
|
12
|
+
register "dev", Dev, aliases: %w[d serve]
|
13
|
+
register "install", Install
|
14
|
+
register "ssr", SSR
|
15
|
+
register "version", Version, aliases: ["v", "-v", "--version", "info"]
|
16
|
+
register "upgrade", Upgrade, aliases: ["update"]
|
17
|
+
register "upgrade_packages", UpgradePackages, aliases: ["update_packages"]
|
18
18
|
|
19
19
|
# Internal: Allows framework-specific variants to extend the CLI.
|
20
|
-
def self.require_framework_libraries(path =
|
20
|
+
def self.require_framework_libraries(path = "cli")
|
21
21
|
ViteRuby.framework_libraries.each do |_framework, library|
|
22
|
-
require [library.name.tr(
|
22
|
+
require [library.name.tr("-", "/").to_s, path].compact.join("/")
|
23
23
|
end
|
24
24
|
rescue LoadError
|
25
|
-
require_framework_libraries
|
25
|
+
require_framework_libraries "installation" unless path == "installation"
|
26
26
|
end
|
27
27
|
end
|
28
28
|
|
29
29
|
# NOTE: This allows framework-specific variants to extend the CLI.
|
30
|
-
ViteRuby::CLI.require_framework_libraries(
|
30
|
+
ViteRuby::CLI.require_framework_libraries("cli")
|
data/lib/vite_ruby/commands.rb
CHANGED
@@ -9,7 +9,7 @@ class ViteRuby::Commands
|
|
9
9
|
|
10
10
|
# Public: Defaults to production, and exits if the build fails.
|
11
11
|
def build_from_task(*args)
|
12
|
-
with_node_env(ENV.fetch(
|
12
|
+
with_node_env(ENV.fetch("NODE_ENV", "production")) {
|
13
13
|
ensure_log_goes_to_stdout {
|
14
14
|
build(*args) || exit!
|
15
15
|
}
|
@@ -25,12 +25,12 @@ class ViteRuby::Commands
|
|
25
25
|
def clobber
|
26
26
|
dirs = [config.build_output_dir, config.ssr_output_dir, config.build_cache_dir, config.vite_cache_dir]
|
27
27
|
dirs.each { |dir| dir.rmtree if dir.exist? }
|
28
|
-
$stdout.puts "Removed vite cache and output dirs:\n\t#{
|
28
|
+
$stdout.puts "Removed vite cache and output dirs:\n\t#{dirs.join("\n\t")}"
|
29
29
|
end
|
30
30
|
|
31
31
|
# Internal: Installs the binstub for the CLI in the appropriate path.
|
32
32
|
def install_binstubs
|
33
|
-
`bundle binstub vite_ruby --path #{
|
33
|
+
`bundle binstub vite_ruby --path #{config.root.join("bin")}`
|
34
34
|
`bundle config --delete bin`
|
35
35
|
end
|
36
36
|
|
@@ -46,7 +46,7 @@ class ViteRuby::Commands
|
|
46
46
|
|
47
47
|
# Internal: Verifies if ViteRuby is properly installed.
|
48
48
|
def verify_install
|
49
|
-
unless File.exist?(config.root.join(
|
49
|
+
unless File.exist?(config.root.join("bin/vite"))
|
50
50
|
warn <<~WARN
|
51
51
|
|
52
52
|
vite binstub not found.
|
@@ -59,7 +59,7 @@ class ViteRuby::Commands
|
|
59
59
|
unless config_path.exist?
|
60
60
|
warn <<~WARN
|
61
61
|
|
62
|
-
Configuration #{
|
62
|
+
Configuration #{config_path} file for vite-plugin-ruby not found.
|
63
63
|
Make sure `bundle exec vite install` has run successfully before running dependent tasks.
|
64
64
|
WARN
|
65
65
|
exit!
|
@@ -69,23 +69,23 @@ class ViteRuby::Commands
|
|
69
69
|
# Internal: Prints information about ViteRuby's environment.
|
70
70
|
def print_info
|
71
71
|
config.within_root do
|
72
|
-
$stdout.puts "bin/vite present?: #{
|
72
|
+
$stdout.puts "bin/vite present?: #{File.exist? "bin/vite"}"
|
73
73
|
|
74
|
-
$stdout.puts "vite_ruby: #{
|
74
|
+
$stdout.puts "vite_ruby: #{ViteRuby::VERSION}"
|
75
75
|
ViteRuby.framework_libraries.each do |framework, library|
|
76
|
-
$stdout.puts "#{
|
77
|
-
$stdout.puts "#{
|
76
|
+
$stdout.puts "#{library.name}: #{library.version}"
|
77
|
+
$stdout.puts "#{framework}: #{Gem.loaded_specs[framework]&.version}"
|
78
78
|
end
|
79
79
|
|
80
|
-
$stdout.puts "ruby: #{
|
81
|
-
$stdout.puts "node: #{
|
80
|
+
$stdout.puts "ruby: #{`ruby --version`}"
|
81
|
+
$stdout.puts "node: #{`node --version`}"
|
82
82
|
|
83
83
|
pkg = config.package_manager
|
84
|
-
$stdout.puts "#{
|
84
|
+
$stdout.puts "#{pkg}: #{`#{pkg} --version` rescue nil}"
|
85
85
|
|
86
86
|
$stdout.puts "\n"
|
87
87
|
packages = `npm ls vite vite-plugin-ruby`
|
88
|
-
packages_msg = packages.include?(
|
88
|
+
packages_msg = packages.include?("vite@") ? "installed packages:\n#{packages}" : "❌ Check that vite and vite-plugin-ruby have been added as development dependencies and installed."
|
89
89
|
$stdout.puts packages_msg
|
90
90
|
|
91
91
|
ViteRuby::CompatibilityCheck.verify_plugin_version(config.root)
|
@@ -99,18 +99,18 @@ private
|
|
99
99
|
def_delegators :@vite_ruby, :config, :builder, :manifest, :logger, :logger=
|
100
100
|
|
101
101
|
def with_node_env(env)
|
102
|
-
original = ENV[
|
103
|
-
ENV[
|
102
|
+
original = ENV["NODE_ENV"]
|
103
|
+
ENV["NODE_ENV"] = env
|
104
104
|
yield
|
105
105
|
ensure
|
106
|
-
ENV[
|
106
|
+
ENV["NODE_ENV"] = original
|
107
107
|
end
|
108
108
|
|
109
109
|
def ensure_log_goes_to_stdout
|
110
110
|
old_logger, original_sync = logger, $stdout.sync
|
111
111
|
|
112
112
|
$stdout.sync = true
|
113
|
-
self.logger = Logger.new($stdout, formatter: proc { |_, _, progname, msg| progname ==
|
113
|
+
self.logger = Logger.new($stdout, formatter: proc { |_, _, progname, msg| (progname == "vite") ? msg : "#{msg}\n" })
|
114
114
|
yield
|
115
115
|
ensure
|
116
116
|
self.logger, $stdout.sync = old_logger, original_sync
|
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
3
|
+
require "json"
|
4
4
|
|
5
5
|
# Internal: Verifies that the installed vite-plugin-ruby version is compatible
|
6
6
|
# with the current version of vite_ruby.
|
@@ -11,9 +11,9 @@ module ViteRuby::CompatibilityCheck
|
|
11
11
|
class << self
|
12
12
|
# Public: Attempt to verify that the vite-plugin-ruby version is compatible.
|
13
13
|
def verify_plugin_version(root)
|
14
|
-
package = JSON.parse(root.join(
|
15
|
-
requirement = package.dig(
|
16
|
-
|
14
|
+
package = JSON.parse(root.join("package.json").read) rescue {}
|
15
|
+
requirement = package.dig("devDependencies", "vite-plugin-ruby") ||
|
16
|
+
package.dig("dependencies", "vite-plugin-ruby")
|
17
17
|
|
18
18
|
raise_unless_satisfied(requirement, ViteRuby::DEFAULT_PLUGIN_VERSION)
|
19
19
|
end
|
@@ -22,7 +22,7 @@ module ViteRuby::CompatibilityCheck
|
|
22
22
|
def raise_unless_satisfied(npm_req, ruby_req)
|
23
23
|
unless compatible_plugin?(npm_req, ruby_req)
|
24
24
|
raise ArgumentError, <<~ERROR
|
25
|
-
vite-plugin-ruby@#{
|
25
|
+
vite-plugin-ruby@#{npm_req} might not be compatible with vite_ruby-#{ViteRuby::VERSION}
|
26
26
|
|
27
27
|
You may disable this check if needed: https://vite-ruby.netlify.app/config/#skipcompatibilitycheck
|
28
28
|
|
@@ -37,12 +37,12 @@ module ViteRuby::CompatibilityCheck
|
|
37
37
|
# requirement.
|
38
38
|
def compatible_plugin?(npm_req, ruby_req)
|
39
39
|
npm_req, ruby_req = [npm_req, ruby_req]
|
40
|
-
.map { |req| Gem::Requirement.new(req.sub(
|
40
|
+
.map { |req| Gem::Requirement.new(req.sub("^", "~>")) }
|
41
41
|
|
42
42
|
current_version = npm_req.requirements.first.second
|
43
43
|
|
44
44
|
ruby_req.satisfied_by?(current_version)
|
45
|
-
rescue
|
45
|
+
rescue
|
46
46
|
true
|
47
47
|
end
|
48
48
|
end
|
data/lib/vite_ruby/config.rb
CHANGED
@@ -1,35 +1,31 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
3
|
+
require "json"
|
4
4
|
|
5
5
|
# Public: Allows to resolve configuration sourced from `config/vite.json` and
|
6
6
|
# environment variables, combining them with the default options.
|
7
7
|
class ViteRuby::Config
|
8
8
|
def origin
|
9
|
-
"#{
|
9
|
+
"#{protocol}://#{host_with_port}"
|
10
10
|
end
|
11
11
|
|
12
12
|
def protocol
|
13
|
-
https ?
|
13
|
+
https ? "https" : "http"
|
14
14
|
end
|
15
15
|
|
16
16
|
def host_with_port
|
17
|
-
"#{
|
17
|
+
"#{host}:#{port}"
|
18
18
|
end
|
19
19
|
|
20
20
|
# Internal: Path to the manifest files generated by Vite and vite-plugin-ruby.
|
21
21
|
def known_manifest_paths
|
22
22
|
[
|
23
23
|
# NOTE: Generated by Vite when `manifest: true`, which vite-plugin-ruby enables.
|
24
|
-
|
24
|
+
build_output_dir.join(".vite/manifest.json"),
|
25
|
+
|
25
26
|
# NOTE: Path where vite-plugin-ruby outputs the assets manifest file.
|
26
|
-
|
27
|
-
]
|
28
|
-
[
|
29
|
-
build_output_dir.join(".vite/#{ path }"), # Vite 5 onwards
|
30
|
-
build_output_dir.join(path), # Vite 4 and below
|
31
|
-
]
|
32
|
-
}
|
27
|
+
build_output_dir.join(".vite/manifest-assets.json"),
|
28
|
+
]
|
33
29
|
end
|
34
30
|
|
35
31
|
# Internal: Path to the manifest files generated by Vite and vite-plugin-ruby.
|
@@ -49,7 +45,7 @@ class ViteRuby::Config
|
|
49
45
|
|
50
46
|
# Internal: The directory where Vite stores its processing cache.
|
51
47
|
def vite_cache_dir
|
52
|
-
root.join(
|
48
|
+
root.join("node_modules/.vite")
|
53
49
|
end
|
54
50
|
|
55
51
|
# Public: The directory that Vite uses as root.
|
@@ -59,7 +55,7 @@ class ViteRuby::Config
|
|
59
55
|
|
60
56
|
# Public: Loads an optional config/vite.rb file that can modify ViteRuby.env
|
61
57
|
def load_ruby_config
|
62
|
-
rb_config_path = File.expand_path(config_path.sub(/.json$/,
|
58
|
+
rb_config_path = File.expand_path(config_path.sub(/.json$/, ".rb"), root)
|
63
59
|
load rb_config_path if File.exist?(rb_config_path)
|
64
60
|
end
|
65
61
|
|
@@ -67,7 +63,7 @@ class ViteRuby::Config
|
|
67
63
|
def to_env(env_vars = ViteRuby.env)
|
68
64
|
CONFIGURABLE_WITH_ENV.each_with_object({}) do |option, env|
|
69
65
|
unless (value = @config[option]).nil?
|
70
|
-
env["#{
|
66
|
+
env["#{ViteRuby::ENV_PREFIX}_#{option.upcase}"] = value.to_s
|
71
67
|
end
|
72
68
|
end.merge(env_vars)
|
73
69
|
end
|
@@ -76,10 +72,10 @@ class ViteRuby::Config
|
|
76
72
|
def watched_paths
|
77
73
|
[
|
78
74
|
*(watch_additional_paths + additional_entrypoints).reject { |dir|
|
79
|
-
dir.start_with?(
|
75
|
+
dir.start_with?("~/") || dir.start_with?(source_code_dir)
|
80
76
|
},
|
81
|
-
"#{
|
82
|
-
config_path.sub(/.json$/,
|
77
|
+
"#{source_code_dir}/**/*",
|
78
|
+
config_path.sub(/.json$/, ".{rb,json}"),
|
83
79
|
*DEFAULT_WATCHED_PATHS,
|
84
80
|
].freeze
|
85
81
|
end
|
@@ -94,27 +90,28 @@ private
|
|
94
90
|
# Internal: Coerces all the configuration values, in case they were passed
|
95
91
|
# as environment variables which are always strings.
|
96
92
|
def coerce_values(config)
|
97
|
-
config[
|
98
|
-
config[
|
99
|
-
config[
|
100
|
-
config[
|
101
|
-
config[
|
102
|
-
coerce_booleans(config,
|
103
|
-
config[
|
93
|
+
config["mode"] = config["mode"].to_s
|
94
|
+
config["port"] = config["port"].to_i
|
95
|
+
config["root"] = root = Pathname.new(config["root"])
|
96
|
+
config["build_cache_dir"] = root.join(config["build_cache_dir"])
|
97
|
+
config["ssr_output_dir"] = root.join(config["ssr_output_dir"])
|
98
|
+
coerce_booleans(config, "auto_build", "hide_build_console_output", "https", "skip_compatibility_check", "skip_proxy")
|
99
|
+
config["package_manager"] ||= detect_package_manager(root)
|
104
100
|
end
|
105
101
|
|
106
102
|
# Internal: Coerces configuration options to boolean.
|
107
103
|
def coerce_booleans(config, *names)
|
108
|
-
|
104
|
+
truthy = [true, "true"]
|
105
|
+
names.each { |name| config[name] = truthy.include?(config[name]) }
|
109
106
|
end
|
110
107
|
|
111
108
|
def detect_package_manager(root)
|
112
|
-
return
|
113
|
-
return
|
114
|
-
return
|
115
|
-
return
|
109
|
+
return "npm" if root.join("package-lock.json").exist?
|
110
|
+
return "pnpm" if root.join("pnpm-lock.yaml").exist?
|
111
|
+
return "bun" if root.join("bun.lockb").exist?
|
112
|
+
return "yarn" if root.join("yarn.lock").exist?
|
116
113
|
|
117
|
-
|
114
|
+
"npm"
|
118
115
|
end
|
119
116
|
|
120
117
|
def initialize(attrs)
|
@@ -128,8 +125,8 @@ private
|
|
128
125
|
# Public: Returns the project configuration for Vite.
|
129
126
|
def resolve_config(**attrs)
|
130
127
|
config = config_defaults.merge(attrs.transform_keys(&:to_s))
|
131
|
-
file_path = File.join(config[
|
132
|
-
file_config = config_from_file(file_path, mode: config[
|
128
|
+
file_path = File.join(config["root"], config["config_path"])
|
129
|
+
file_config = config_from_file(file_path, mode: config["mode"])
|
133
130
|
new DEFAULT_CONFIG.merge(file_config).merge(config_from_env).merge(config)
|
134
131
|
end
|
135
132
|
|
@@ -137,20 +134,20 @@ private
|
|
137
134
|
|
138
135
|
# Internal: Converts camelCase to snake_case.
|
139
136
|
SNAKE_CASE = ->(camel_cased_word) {
|
140
|
-
camel_cased_word.to_s.gsub(
|
137
|
+
camel_cased_word.to_s.gsub("::", "/")
|
141
138
|
.gsub(/([A-Z]+)([A-Z][a-z])/, '\1_\2')
|
142
139
|
.gsub(/([a-z\d])([A-Z])/, '\1_\2')
|
143
|
-
.tr(
|
140
|
+
.tr("-", "_")
|
144
141
|
.downcase
|
145
142
|
}
|
146
143
|
|
147
144
|
# Internal: Default values for a Ruby application.
|
148
|
-
def config_defaults(asset_host: nil, mode: ENV.fetch(
|
145
|
+
def config_defaults(asset_host: nil, mode: ENV.fetch("RACK_ENV", "development"), root: Dir.pwd)
|
149
146
|
{
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
147
|
+
"asset_host" => option_from_env("asset_host") || asset_host,
|
148
|
+
"config_path" => option_from_env("config_path") || DEFAULT_CONFIG.fetch("config_path"),
|
149
|
+
"mode" => option_from_env("mode") || mode,
|
150
|
+
"root" => option_from_env("root") || root,
|
154
151
|
}.select { |_, value| value }
|
155
152
|
end
|
156
153
|
|
@@ -165,7 +162,7 @@ private
|
|
165
162
|
|
166
163
|
# Internal: Retrieves a configuration option from environment variables.
|
167
164
|
def option_from_env(name)
|
168
|
-
ViteRuby.env["#{
|
165
|
+
ViteRuby.env["#{ViteRuby::ENV_PREFIX}_#{name.upcase}"]
|
169
166
|
end
|
170
167
|
|
171
168
|
# Internal: Extracts the configuration options provided as env vars.
|
@@ -180,16 +177,16 @@ private
|
|
180
177
|
# Internal: Loads the configuration options provided in a JSON file.
|
181
178
|
def config_from_file(path, mode:)
|
182
179
|
multi_env_config = load_json(path)
|
183
|
-
multi_env_config.fetch(
|
180
|
+
multi_env_config.fetch("all", {})
|
184
181
|
.merge(multi_env_config.fetch(mode, {}))
|
185
182
|
rescue Errno::ENOENT => error
|
186
|
-
$stderr << "Check that your vite.json configuration file is available in the load path:\n\n\t#{
|
183
|
+
$stderr << "Check that your vite.json configuration file is available in the load path:\n\n\t#{error.message}\n\n"
|
187
184
|
{}
|
188
185
|
end
|
189
186
|
end
|
190
187
|
|
191
188
|
# Internal: Shared configuration with the Vite plugin for Ruby.
|
192
|
-
DEFAULT_CONFIG = load_json("#{
|
189
|
+
DEFAULT_CONFIG = load_json("#{__dir__}/../../default.vite.json").freeze
|
193
190
|
|
194
191
|
# Internal: Configuration options that can not be provided as env vars.
|
195
192
|
NOT_CONFIGURABLE_WITH_ENV = %w[additional_entrypoints watch_additional_paths].freeze
|
@@ -1,15 +1,15 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
3
|
+
require "rack/proxy"
|
4
4
|
|
5
5
|
# Public: Allows to relay asset requests to the Vite development server.
|
6
6
|
class ViteRuby::DevServerProxy < Rack::Proxy
|
7
7
|
HOST_WITH_PORT_REGEX = %r{^(.+?)(:\d+)/}
|
8
|
-
VITE_DEPENDENCY_PREFIX =
|
8
|
+
VITE_DEPENDENCY_PREFIX = "/@"
|
9
9
|
|
10
10
|
def initialize(app = nil, options = {})
|
11
11
|
@vite_ruby = options.delete(:vite_ruby) || ViteRuby.instance
|
12
|
-
options[:streaming] = false if config.mode ==
|
12
|
+
options[:streaming] = false if config.mode == "test" && !options.key?(:streaming)
|
13
13
|
super
|
14
14
|
end
|
15
15
|
|
@@ -17,7 +17,7 @@ class ViteRuby::DevServerProxy < Rack::Proxy
|
|
17
17
|
def perform_request(env)
|
18
18
|
if vite_should_handle?(env) && dev_server_running?
|
19
19
|
forward_to_vite_dev_server(env)
|
20
|
-
super
|
20
|
+
super
|
21
21
|
else
|
22
22
|
@app.call(env)
|
23
23
|
end
|
@@ -30,39 +30,40 @@ private
|
|
30
30
|
def_delegators :@vite_ruby, :config, :dev_server_running?
|
31
31
|
|
32
32
|
def rewrite_uri_for_vite(env)
|
33
|
-
uri = env.fetch(
|
34
|
-
env[
|
33
|
+
uri = env.fetch("REQUEST_URI") { [env["PATH_INFO"], env["QUERY_STRING"]].reject { |str| str.to_s.strip.empty? }.join("?") }
|
34
|
+
env["PATH_INFO"], env["QUERY_STRING"] = (env["REQUEST_URI"] = normalize_uri(uri)).split("?")
|
35
35
|
end
|
36
36
|
|
37
37
|
def normalize_uri(uri)
|
38
38
|
uri
|
39
|
-
.sub(HOST_WITH_PORT_REGEX,
|
40
|
-
.sub(
|
39
|
+
.sub(HOST_WITH_PORT_REGEX, "/") # Hanami adds the host and port.
|
40
|
+
.sub(".ts.js", ".ts") # Hanami's javascript helper always adds the extension.
|
41
41
|
.sub(/\.(sass|scss|styl|stylus|less|pcss|postcss)\.css$/, '.\1') # Rails' stylesheet_link_tag always adds the extension.
|
42
42
|
end
|
43
43
|
|
44
44
|
def forward_to_vite_dev_server(env)
|
45
45
|
rewrite_uri_for_vite(env)
|
46
|
-
env[
|
47
|
-
env[
|
48
|
-
env[
|
49
|
-
env[
|
50
|
-
env[
|
51
|
-
env[
|
52
|
-
env[
|
46
|
+
env["QUERY_STRING"] ||= ""
|
47
|
+
env["HTTP_HOST"] = env["HTTP_X_FORWARDED_HOST"] = config.host
|
48
|
+
env["HTTP_X_FORWARDED_SERVER"] = config.host_with_port
|
49
|
+
env["HTTP_PORT"] = env["HTTP_X_FORWARDED_PORT"] = config.port.to_s
|
50
|
+
env["HTTP_X_FORWARDED_PROTO"] = env["HTTP_X_FORWARDED_SCHEME"] = config.protocol
|
51
|
+
env["HTTPS"] = env["HTTP_X_FORWARDED_SSL"] = "off" unless config.https
|
52
|
+
env["SCRIPT_NAME"] = ""
|
53
53
|
end
|
54
54
|
|
55
55
|
def vite_should_handle?(env)
|
56
|
-
path = normalize_uri(env[
|
56
|
+
path = normalize_uri(env["PATH_INFO"])
|
57
57
|
return true if path.start_with?(vite_url_prefix) # Vite asset
|
58
|
-
|
58
|
+
|
59
|
+
true if file_in_vite_root?(path) # Fallback if Vite can serve the file
|
59
60
|
end
|
60
61
|
|
61
62
|
# NOTE: When using an empty 'public_output_dir', we need to rely on a
|
62
63
|
# filesystem check to check whether Vite should serve the request.
|
63
64
|
def file_in_vite_root?(path)
|
64
|
-
path.include?(
|
65
|
-
config.vite_root_dir.join(path.start_with?(
|
65
|
+
path.include?(".") && # Check for extension, avoid filesystem if possible.
|
66
|
+
config.vite_root_dir.join(path.start_with?("/") ? path[1..] : path).file?
|
66
67
|
end
|
67
68
|
|
68
69
|
# NOTE: Vite is configured to use 'public_output_dir' as the base, which can
|
@@ -70,6 +71,6 @@ private
|
|
70
71
|
#
|
71
72
|
# If the path starts with that prefix, it will be redirected to Vite.
|
72
73
|
def vite_url_prefix
|
73
|
-
@vite_url_prefix ||= config.public_output_dir.empty? ? VITE_DEPENDENCY_PREFIX : "/#{
|
74
|
+
@vite_url_prefix ||= config.public_output_dir.empty? ? VITE_DEPENDENCY_PREFIX : "/#{config.public_output_dir}/"
|
74
75
|
end
|
75
76
|
end
|
data/lib/vite_ruby/error.rb
CHANGED
@@ -3,7 +3,7 @@
|
|
3
3
|
# Internal: Provides common functionality for errors.
|
4
4
|
class ViteRuby::Error < StandardError
|
5
5
|
def message
|
6
|
-
super.sub(
|
6
|
+
super.sub(":troubleshooting:", <<~MSG)
|
7
7
|
Visit the Troubleshooting guide for more information:
|
8
8
|
https://vite-ruby.netlify.app/guide/troubleshooting.html#troubleshooting
|
9
9
|
MSG
|
data/lib/vite_ruby/io.rb
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
3
|
+
require "open3"
|
4
4
|
|
5
5
|
# Public: Builds on top of Ruby I/O open3 providing a friendlier experience.
|
6
6
|
module ViteRuby::IO
|
7
7
|
class << self
|
8
8
|
# Internal: A modified version of capture3 that can continuosly print stdout.
|
9
9
|
# NOTE: Streaming output provides a better UX when running bin/vite build.
|
10
|
-
def capture(*cmd, with_output: $stdout.method(:puts), stdin_data:
|
10
|
+
def capture(*cmd, with_output: $stdout.method(:puts), stdin_data: "", **opts)
|
11
11
|
return Open3.capture3(*cmd, **opts) unless with_output
|
12
12
|
|
13
13
|
Open3.popen3(*cmd, **opts) { |stdin, stdout, stderr, wait_threads|
|
@@ -21,7 +21,7 @@ module ViteRuby::IO
|
|
21
21
|
|
22
22
|
# Internal: Reads and yield every line in the stream. Returns the full content.
|
23
23
|
def read_lines(io)
|
24
|
-
buffer = +
|
24
|
+
buffer = +""
|
25
25
|
while line = io.gets
|
26
26
|
buffer << line
|
27
27
|
yield line
|