Serve Vite-based Ember apps from development server - #653
Merged
Conversation
tricknotes
marked this pull request as draft
August 31, 2026 12:21
This was referenced Sep 2, 2026
tricknotes
pushed a commit
to tricknotes/ember-cli-rails-assets
that referenced
this pull request
Sep 2, 2026
`include_ember_script_tags` always read the output of `ember build`, so a Vite-based application served by ember-cli-rails's development server (tricknotes/ember-cli-rails#653) could not use the asset helpers without opting out of the server — and with it, out of fast reloads. When the application is served by the development server (feature-detected, so older ember-cli-rails releases keep their behavior), read `index.html` from the server instead of a build directory and emit the startup tags with root-relative URLs rewritten to absolute URLs on the server, the same way ember-cli-rails serves the document itself. Nothing is built, so a change to the application is picked up by reloading the page. The extraction shared with the build-directory path now also leaves protocol-relative (`//`) URLs alone, and `include_ember_stylesheet_tags` raises its Vite guidance for development-server applications too (their `dist` may not exist, so the Vite detection alone would miss them). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01HazNguGSW6gmmb3LwttuUW
tricknotes
force-pushed
the
claude/vite-dev-server-hmr-y3xm8i
branch
from
September 3, 2026 16:06
640ce15 to
ccd16e5
Compare
tricknotes
pushed a commit
to tricknotes/ember-cli-rails-assets
that referenced
this pull request
Sep 3, 2026
`include_ember_script_tags` always read the output of `ember build`, so a Vite-based application served by ember-cli-rails's development server (tricknotes/ember-cli-rails#653) could not use the asset helpers without opting out of the server — and with it, out of fast reloads. When the application is served by the development server (feature-detected, so older ember-cli-rails releases keep their behavior), read `index.html` from the server instead of a build directory and emit the startup tags with root-relative URLs rewritten to absolute URLs on the server, the same way ember-cli-rails serves the document itself. Nothing is built, so a change to the application is picked up by reloading the page. The extraction shared with the build-directory path now also leaves protocol-relative (`//`) URLs alone, and `include_ember_stylesheet_tags` raises its Vite guidance for development-server applications too (their `dist` may not exist, so the Vite detection alone would miss them). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
tricknotes
marked this pull request as ready for review
September 3, 2026 18:00
Vite-based Ember applications (`ember-cli >= 6.8`) were built once, synchronously, on the first request in `development`, so picking up a change meant restarting Rails. The classic (Broccoli-based) build avoids that with `ember build --watch` and `ember-cli-rails-addon`, neither of which is available to the Vite-based build. Serve those applications from Vite's own development server instead -- the one the blueprint's `npm start` script runs. `EmberCli::DevServer` starts it on the first request, waits for it to accept connections, and signals its process group when Rails exits. If something is already listening on the configured address, it is used as-is, so a fixed `port` lets several Rails workers, or a hand-started `npm start`, share one server. `EmberCli::Deploy::DevServer` reads `index.html` over HTTP and rewrites its root-relative `src` and `href` attributes to absolute URLs on the development server. Loading `@vite/client` from there is what makes the Vite client open its HMR WebSocket against the development server directly, so Rails never proxies the socket. Assets the application references relatively are still requested from Rails, and `EmberCli::DevServerProxy` forwards them to the development server so they resolve the same way they do when served out of `dist`. The strategy is chosen by default only for Vite-based applications in `development`, and is configured -- or disabled -- with the `dev_server` option. `test` and `production` continue to be served from the output of `ember build`, and the classic build is untouched. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
A cold development server transforms the application's modules on the first load, which can take longer than Capybara's default 2-second wait on a busy CI runner, failing the examples with an empty page body. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The 30-second wait still failed on busy CI runners: a cold development server runs the embroider prebuild and transforms every module on the first load before the application can render anything. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The examples fail intermittently on CI with an empty page body even after a 60-second wait, so the failure is not slowness. Capture the browser console and the document a failing example saw, so that the next occurrence explains why the application did not boot. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The dev-server examples failed intermittently with a page that stayed blank for the whole Capybara wait. The browser-state dump showed why: the development server was serving the test-environment config — autoboot: false, rootElement #ember-testing — so Ember loaded but never rendered. The server shared spec/dummy/my-app with the ember build and ember test runs that other examples perform, and their test-environment prebuild and cache output leaked into the running server depending on example order. Give the server its own copy of the app, made by bin/setup_ember, so the two can no longer interfere. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
CI pipes the output through rake, which block-buffers it: a slow or hung job then shows nothing past the seed line, hiding where it stopped. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
bin/setup_ember already installs the applications' dependencies (and copies the installed app for the development server), so the rake ember:install that followed only re-ran npm install and npm prune for every registered app. Each of those calls is a no-op that still talks to the registry, and a slow registry then multiplied into jobs hitting the CI runtime cap. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
ember test occasionally hangs on CI when testem fails to attach to its browser, and the silent hang then eats the whole job's runtime cap. Fail the example after five minutes with a clear error instead — the healthy run takes about half a minute. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
tricknotes
force-pushed
the
claude/vite-dev-server-hmr-y3xm8i
branch
from
September 4, 2026 08:08
c1f47c1 to
5ba5dd3
Compare
Merged
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Add support for serving Vite-based Ember applications (generated with
ember-cli >= 6.8) from Vite's own development server in development mode, enabling hot module reloading without restarting Rails.Key Changes
New
DevServerclass (lib/ember_cli/dev_server.rb): Manages the Vite development server lifecycle for a single Ember applicationget,head,options_request) to fetch assets and HTML from the serverNew
DevServerProxyRack middleware (lib/ember_cli/dev_server_proxy.rb): Proxies requests to the development serverNew
Deploy::DevServerstrategy (lib/ember_cli/deploy/dev_server.rb): Serves applications from the development serverindex.htmlto absolute URLs pointing at the development serverEnhanced
Appclass (lib/ember_cli/app.rb):dev_server?method to detect when an app should use the development serverdev_serverproperty to lazily initialize theDevServerDeploy::DevServerstrategy by default for Vite-based apps in developmentdev_serverconfiguration option to customize host, port, and timeoutEnhanced
Shellclass (lib/ember_cli/shell.rb):start_dev_servermethod to spawn the Vite development server in a separate process groupdev_server_running?method to check server statusEnhanced
Commandclass (lib/ember_cli/command.rb): Addsdev_servermethod to construct the Vite CLI commandEnhanced
PathSetclass (lib/ember_cli/path_set.rb): Addsviteproperty to locate the Vite executableComprehensive test coverage: Includes unit tests for all new classes and integration tests verifying the full request flow
Notable Implementation Details
index.htmlare rewritten to absolute URLs so the browser loads Vite's HMR client directly from the development server, not through Railsnpm startworkflows