Own the interpretation of an application's build output - #687
Draft
tricknotes wants to merge 9 commits into
Draft
tricknotes wants to merge 9 commits into
tricknotes wants to merge 9 commits into
Conversation
The asset helpers read a built application to work out what it boots from: where its assets live, how `index.html` refers to them, and whether the application is Vite-based. This gem runs the build, so it already knows all of it — it resolves the same paths and carries a Vite check of its own. Move that knowledge here, behind an API add-ons can render: * `EmberCli::App#vite?` * `EmberCli::App#startup_tags` * `EmberCli::App#javascript_assets` and `#stylesheet_assets` `startup_tags` chooses between the development server and the build directory itself, so callers no longer feature-detect the development server. With the knowledge here, this gem no longer needs to depend on the helpers, and the helpers can depend on it instead. Bundler refuses to resolve a dependency that points both ways, so drop it. The feature spec that exercised the helpers from here goes with it; the helpers cover that path in their own suite. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The asset helpers no longer arrive with this gem, so an application that renders them has to ask for them. Say so where an upgrading application looks, and correct the README, which still claimed this gem injects the assets itself. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Rendering a layout that calls a missing helper fails with `ActionView::Template::Error`, raised from the `NoMethodError` behind it. Nothing else fails, so say that too. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
tricknotes
force-pushed
the
claude/intelligent-goodall-foai0r
branch
from
September 17, 2026 17:23
256bb7f to
2e5c502
Compare
A built `index.html` may point at assets the build does not produce, such as a stylesheet served by a font service or a script served by a CDN. They have no file to resolve against, and an inline `<script>` names no asset at all, so resolving every reference by its basename fails on both. Emit a URL that resolves outside the build as it is, and skip a tag that carries no URL. `prepend` mounts the build output onto a path or another host, so the readers take it and join it only onto the assets that point into the build, the way `startup_tags` already remaps a Vite build. This carries the behaviour the asset helpers gained in tricknotes/ember-cli-rails-assets#43 into the code that now interprets the build, and `StartupTags` shares the predicate that decides it. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
`ember build` writes what an addon ships in a subdirectory of `assets` into that subdirectory, and `index.html` refers to it by that path. Listing the `assets` directory one level deep represented such a file by the subdirectory that holds it, and matching a reference by its file name alone resolved it to whichever file happened to share that name. Represent every file by its path within `assets`, and resolve a reference by the longest trailing path the document and the build output agree on. A reference that carries the `assets` directory, or the application's `rootURL`, still resolves. This carries what the asset helpers gained in tricknotes/ember-cli-rails-assets#45 into the code that now interprets the build. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
What stays is the matching rule the code cannot show on its own, the URLs the `REMOTE` pattern covers, and why a prefix applies to root-relative URLs only. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
tricknotes
force-pushed
the
claude/intelligent-goodall-foai0r
branch
from
September 18, 2026 01:58
aa76d07 to
844d7a4
Compare
The document wrapped at a column, so a sentence ran across lines and two sentences shared one. Give each sentence a line of its own instead, whatever its length. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The scenario that rendered the asset helpers in a page went with the dependency on them, but it was also the only test that booted an application from tags embedded into a page of its own, and the only one doing so for a Vite build. Bring it back without the helpers: the page reads the tags from `EmberCli::App#startup_tags`, or `#javascript_assets` and `#stylesheet_assets` for a classic build, the readers add-ons render. That keeps the reader contract tested across the whole build and package manager matrix here, where changes to it are made. The page moves to `/embed`: mounting at `/embedded` names its redirect route `embedded`, which clashes with the route it names. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
`EmberCli::App` gained `startup_tags`, `javascript_assets` and `stylesheet_assets` only for code that embeds an application into a page of its own. Those readers now live on `EmberCli::Embedding`, which wraps an application, so `EmberCli::App` keeps only `vite?` on top of what it already had. `EmberCli::Embedding#startup_tags?` answers whether the application boots from startup tags, whether Vite's development server or a Vite build serves it, so callers no longer combine `dev_server?` and `vite?` themselves. `AssetMap`, `StartupTags` and `Url` move under the new class as private constants, leaving one class and four methods to keep compatible. Their specs now go through `EmberCli::Embedding`. `PathSet#assets` and `#index_html` go away too, as the build directory is reachable from `EmberCli::App#dist_path`. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
tricknotes
force-pushed
the
claude/intelligent-goodall-foai0r
branch
from
September 26, 2026 07:41
bceb883 to
dff93f5
Compare
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.
Why
The asset helpers in
ember-cli-rails-assetsread a built application to work out what it boots from:where its assets live, how
index.htmlrefers to them, which namepackage.jsongives it, and whether the build is Vite-based.This gem runs the build, so it already knows all of that.
The two ended up answering the same question in different ways — this gem detects a Vite build from the configuration file at the application's root, while the helpers looked for a module script in the generated
index.html.The dependency also pointed both ways: this gem depended on the helpers, while the helpers called
EmberCli::Appwithout declaring that they needed it, and worked around older releases withrespond_to?(:dev_server?).What
Move the interpretation of a build's output here, behind
EmberCli::Embedding, the API for embedding an application into a page of its own.It wraps an application (
EmberCli::Embedding.new(EmberCli["frontend"])) and reports:#startup_tags?— whether the application boots from startup tags, as it does when Vite's development server or a Vite build serves it#startup_tags(prepend:)— those tags, read from the development server or the build directory, whichever serves the application#javascript_assets(prepend:)and#stylesheet_assets(prepend:)— the assets a classic build boots from, withprependjoined onto the ones that point into the buildEmberCli::Appgains only#vite?, as which build system an application uses is not specific to embedding it.The classes behind
EmberCli::Embeddingare private constants of it, so they can change without breaking anyone:AssetMapresolves the references in a classic build'sindex.htmlagainst the filesember buildwrote, replacing the helpers'AssetMap,DirectoryAssetMapandLookupStartupTagsextracts the boot tags of a Vite build and joins a prefix onto their root-relative URLsUrlrecognizes a URL that resolves outside the build, which both of the above leave aloneBecause
EmberCli::Embeddingchooses between the development server and the build directory itself, callers no longer feature-detect the development server.Because the readers take
prepend, callers no longer decide which URLs it applies to.It reads the build through what
EmberCli::Appalready exposes, such as#dist_path, so nothing else is added toEmberCli::ApporEmberCli::PathSet.The behaviour the helpers gained in tricknotes/ember-cli-rails-assets#43 and #45 comes along:
an asset the build does not produce (a CDN, a font service) is reported as the document refers to it, a tag carrying no URL is skipped, and a reference resolves by the longest trailing path it shares with the build output, so an addon's nested asset resolves to the file it names.
With this knowledge here, the dependency on
ember-cli-rails-assetsis dropped, and the helpers declare a dependency on this gem instead.Bundler refuses to resolve a dependency that points both ways, so this direction has to be the one that survives.
nokogirimoves here for the same reason.The feature scenario that rendered the helpers in a page of its own now embeds the tags from
EmberCli::Embeddinginstead, without the helpers.It was the only test booting an application from tags embedded into a page, and the only one doing so for a Vite build, so it keeps the contract covered across the whole build and package manager matrix here, where changes to it are made.
Its page moves from
/asset-helpersto/embed: mounting at/embeddedwould name its redirect routeembedded, clashing with the route it names.Compatibility
An application that renders
include_ember_script_tagsorinclude_ember_stylesheet_tagsnow needsgem "ember-cli-rails-assets"in its ownGemfile, where it used to arrive as a dependency of this gem.render_ember_appandmount_ember_appare unaffected.UPGRADING.mdcarries that, and the constants the helpers no longer expose, under a heading for1.0.0.The README no longer claims this gem injects the assets itself.
The version is left to the release commit, as
RELEASING.mdasks.Testing
spec/libpasses, including theEmberCli::Embeddingspec, which covers the classes behind it through its public methods and checks that they stay private<meta>tag, the stylesheet andmodulepreloadlinks, and the module script of a Vite build fromEmberCli::Embedding; booting it in a browser is left to CI, as the local Chrome and ChromeDriver disagree on their version