Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,5 @@
"type": "git",
"url": "https://github.com/ElMassimo/vite_ruby"
},
"homepage": "https://github.com/ElMassimo/vite_ruby",
"packageManager": "pnpm@10.32.1"
"homepage": "https://github.com/ElMassimo/vite_ruby"
}
81 changes: 81 additions & 0 deletions test/helper_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,11 @@ def with_dev_server_running(&block)
refresh_config(mode: "development")
super
end

def with_skip_proxy_dev_server_running(&block)
refresh_config(mode: "development", skip_proxy: true)
ViteRuby.instance.stub(:dev_server_running?, true, &block)
end
end

class LegacyHelperTest < HelperTestCase
Expand Down Expand Up @@ -190,6 +195,82 @@ def test_vite_image_tag
}
end

# skipProxy tests: validate that all tag helpers emit absolute URLs pointing
# directly to the Vite dev server when skipProxy is enabled.

def test_vite_client_tag_with_skip_proxy
assert_nil vite_client_tag
with_skip_proxy_dev_server_running {
origin = ViteRuby.config.origin
assert_equal %(<script src="#{origin}/vite-dev/@vite/client" crossorigin="anonymous" type="module"></script>), vite_client_tag
}
end

def test_vite_asset_path_with_skip_proxy
with_skip_proxy_dev_server_running {
origin = ViteRuby.config.origin
assert_equal "#{origin}/vite-dev/entrypoints/main.ts", vite_asset_path("main.ts")
assert_equal "#{origin}/vite-dev/entrypoints/app.css", vite_asset_path("app.css")
assert_equal "#{origin}/vite-dev/images/logo.png", vite_asset_path("images/logo.png")
}
end

def test_vite_javascript_tag_with_skip_proxy
with_skip_proxy_dev_server_running {
origin = ViteRuby.config.origin
assert_equal %(<script src="#{origin}/vite-dev/entrypoints/main.ts" crossorigin="" type="module"></script>),
vite_typescript_tag("main")

assert_equal %(<script src="#{origin}/vite-dev/entrypoints/frameworks/vue.js" crossorigin="" type="module"></script>),
vite_javascript_tag("entrypoints/frameworks/vue")
}
end

def test_vite_stylesheet_tag_with_skip_proxy
with_skip_proxy_dev_server_running {
origin = ViteRuby.config.origin
assert_similar link(href: "#{origin}/vite-dev/entrypoints/app.css"), vite_stylesheet_tag("app")
assert_equal vite_stylesheet_tag("app"), vite_stylesheet_tag("app.css")

if Rails::VERSION::MAJOR >= 7
assert_similar link(href: "#{origin}/vite-dev/entrypoints/sassy.scss"), vite_stylesheet_tag("sassy.scss")
else
# Rails 6 appends .css to non-.css extensions. Without the proxy to
# normalize .scss.css → .scss, Vite cannot serve this URL.
assert_similar link(href: "#{origin}/vite-dev/entrypoints/sassy.scss.css"), vite_stylesheet_tag("sassy.scss")
end
}
end

def test_vite_image_tag_with_skip_proxy
with_skip_proxy_dev_server_running {
origin = ViteRuby.config.origin
assert_equal %(<img alt="Logo" src="#{origin}/vite-dev/images/logo.png" />),
vite_image_tag("images/logo.png", alt: "Logo")

assert_equal %(<img srcset="#{origin}/vite-dev/images/logo-2x.png 2x" alt="Logo" src="#{origin}/vite-dev/images/logo.png" />),
vite_image_tag("images/logo.png", srcset: {"images/logo-2x.png" => "2x"}, alt: "Logo")
}
end

def test_vite_react_refresh_tag_with_skip_proxy
with_skip_proxy_dev_server_running {
origin = ViteRuby.config.origin
assert_equal <<~HTML.chomp, vite_react_refresh_tag(nonce: nil)
<script type="module">
//<![CDATA[
import RefreshRuntime from '#{origin}/vite-dev/@react-refresh'
RefreshRuntime.injectIntoGlobalHook(window)
window.$RefreshReg$ = () => {}
window.$RefreshSig$ = () => (type) => type
window.__vite_plugin_react_preamble_installed__ = true

//]]>
</script>
HTML
}
end

def test_vite_picture_tag
if Rails.gem_version >= Gem::Version.new("7.1.0")
assert_equal <<~HTML.gsub(/\n\s*/, ""), vite_picture_tag("images/logo.svg", "images/logo.png", class: "test", image: {alt: "Logo"})
Expand Down
67 changes: 67 additions & 0 deletions test/manifest_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,73 @@ def test_vite_client_src
}
end

# NOTE: skipProxy (experimental since v3.2.12) causes asset URLs to point
# directly to the Vite dev server. Known caveats:
#
# 1. CORS: Browser makes cross-origin requests to Vite. Vite sets permissive
# CORS headers by default, but custom middleware may interfere.
# 2. Rails 6 .scss.css: Without the proxy to normalize .scss.css → .scss,
# Rails 6's stylesheet_link_tag produces URLs Vite can't serve.
# 3. Cookies: Asset requests to a different origin won't carry same-origin
# cookies. Usually not an issue since assets don't require auth.
# 4. SSL: Both Rails and Vite need valid certs when using HTTPS.
# 5. Docker/VM: "localhost:3036" from the browser may not reach Vite inside
# a container. Must configure host to a reachable address.
# 6. vite_asset_url may produce double-origin URLs since path_for already
# returns an absolute URL when skipProxy is enabled.

def test_lookup_success_with_skip_proxy_and_dev_server_running
refresh_config(mode: "development", skip_proxy: true)
with_dev_server_running {
origin = ViteRuby.config.origin # "https://localhost:3535"

entry = {"file" => "#{origin}/vite-dev/entrypoints/application.js"}
assert_equal entry, lookup!("application.js", type: :javascript)
assert_equal entry, lookup!("entrypoints/application.js")

assert_equal "#{origin}/vite-dev/entrypoints/application.ts",
path_for("application", type: :typescript)

assert_equal "#{origin}/vite-dev/entrypoints/styles.css",
path_for("styles", type: :stylesheet)

assert_equal "#{origin}/vite-dev/image/logo.png",
path_for("image/logo.png")

assert_equal "#{origin}/vite-dev/logo.png",
path_for("~/logo.png")

assert_equal "#{origin}/vite-dev/@fs#{ViteRuby.config.root}/app/assets/theme.css",
path_for("/app/assets/theme", type: :stylesheet)
}
end

def test_vite_client_src_with_skip_proxy
refresh_config(mode: "development", skip_proxy: true)

assert_nil vite_client_src

with_dev_server_running {
assert_equal "#{ViteRuby.config.origin}/vite-dev/@vite/client", vite_client_src
}

# Origin from skip_proxy takes precedence over asset_host
refresh_config(asset_host: "http://example.com", mode: "development", skip_proxy: true)

with_dev_server_running {
assert_equal "#{ViteRuby.config.origin}/vite-dev/@vite/client", vite_client_src
}
end

def test_skip_proxy_has_no_effect_without_dev_server
refresh_config(skip_proxy: true)

# Production paths are unchanged — skipProxy only matters when dev server runs
assert_equal prefixed("main.9dcad042.js"), path_for("main", type: :typescript)
assert_equal prefixed("app.517bf154.css"), path_for("app", type: :stylesheet)
assert_equal prefixed("logo.f42fb7ea.png"), path_for("images/logo.png")
end

def test_lookup_nil
assert_nil lookup("foo.js")
end
Expand Down