Skip to content

Build a Vite application with vite build - #681

Merged
tricknotes merged 1 commit into
mainfrom
build-with-vite
Sep 11, 2026
Merged

Build a Vite application with vite build#681
tricknotes merged 1 commit into
mainfrom
build-with-vite

Conversation

@tricknotes

@tricknotes tricknotes commented Sep 11, 2026

Copy link
Copy Markdown
Owner

Command#build drove every build through ember build. In a Vite-based project that command is on its way out. Its own help text says so:

Vestigial command in Vite-based projects. Use the build script from package.json instead.

It now declares only --environment, --suppress-sizes and --output-path, and refuses --watch and --watcher rather than forwarding them (lib/commands/build.js). The blueprint's own script is "build": "vite build" (ember-app-blueprint).

So build a Vite application with vite build. Command#build picks the command from the blueprint, and the two builders sit side by side so what each one needs stays visible.

The flags

Was Is Why
--environment --mode Same value, from the same build_environment
--output-path --outDir The directory Rails serves the application from
--emptyOutDir Required to keep the behaviour we have: the output directory lies outside the Ember application, and Vite leaves stale files there unless asked
--silent --logLevel error Quiets the progress output while leaving errors visible

--emptyOutDir is not an improvement, it is parity. Dropping a STALE.txt into the output directory and rebuilding:

Command STALE.txt
ember build --output-path removed
vite build --outDir --emptyOutDir removed
vite build --outDir left behind

Why not run the build script through a package manager

The gem has to pass --outDir, and forwarding flags to a package.json script is not portable. Measured against the same application, with the command each package manager actually ran:

Command Ran Result
npm run build -- <flags> vite build --outDir … --mode … --emptyOutDir builds where asked
npm run build <flags> vite build /tmp/out development exits 1 — npm eats the flags and passes the values positionally
pnpm build <flags> vite build --outDir … --mode … --emptyOutDir builds where asked
pnpm run build -- <flags> vite build -- --outDir … --mode … exits 0 and writes to dist — the separator reaches the script

npm needs --, pnpm must not have it, and the pnpm failure is silent. Calling vite directly avoids the whole question, and keeps the DependencyError that PathSet#vite raises when the executable is missing.

Verification

Against the sandbox application (ember-cli 7.2.0, vite 8.2.2):

  • rake ember:compile exits 0, running
    …/node_modules/.bin/vite build --mode 'development' --outDir '…/tmp/ember-cli/apps/frontend' --emptyOutDir
  • The output is byte-for-byte the same set of files as ember build --environment development --output-path produced — diff of the two file listings, with content hashes normalised, is empty
  • The Embroider compat prebuild still runs (Built project successfully. Stored in ".../tmp/compat-prebuild")
  • A production build (--mode production) writes index.html plus every asset it references

Tests

  • bin/rspec spec/lib/ember_cli/command_spec.rb — 14 examples, 0 failures, including three for the Vite build
  • bin/rspec spec/lib — 2 failures, both (app_spec.rb:192, app_spec.rb:200) failing identically on main; they need node_modules installed to find the ember binary

ember test is untouched: it is not vestigial in a Vite project and still works, so rake ember:test keeps running it. The blueprint has begun moving that to testem ci directly, which is worth its own look later.

🤖 Generated with Claude Code

`Command#build` drove every build through `ember build`. In a Vite-based
project that command is on its way out: `ember build --help` there describes
itself as a "Vestigial command in Vite-based projects. Use the `build` script
from package.json instead", and has dropped every option but `--environment`,
`--suppress-sizes` and `--output-path`. It refuses `--watch` and `--watcher`
rather than forwarding them.

Build such an application with `vite build` instead, which is what the
blueprint's own `build` script runs. `Command#build` picks the command from
the blueprint, and the two builders sit side by side so that what each
blueprint needs stays visible.

The flags follow from what the gem needs of a build:

* `--mode` carries what `--environment` carried, from the same
  `build_environment`
* `--outDir` carries what `--output-path` carried, the directory Rails
  serves the application from
* `--emptyOutDir` keeps the directory cleared between builds. It lies
  outside the Ember application, where Vite leaves stale files in place
  unless asked
* `--logLevel error` stands in for `--silent`, quieting the progress output
  while leaving errors visible

Running `vite build` directly rather than the `build` script through a
package manager is deliberate: the gem has to pass `--outDir`, and forwarding
flags to a script is not portable — npm needs `--` before them, while pnpm
passes that `--` on to the script, where the flags arrive as literal
arguments and the build silently writes to `dist` instead.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@tricknotes
tricknotes marked this pull request as ready for review September 11, 2026 17:23
@tricknotes
tricknotes merged commit 27f15ee into main Sep 11, 2026
16 checks passed
@tricknotes
tricknotes deleted the build-with-vite branch September 11, 2026 17:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants