diff --git a/.changeset/pre.json b/.changeset/pre.json index df81b3f..96f5758 100644 --- a/.changeset/pre.json +++ b/.changeset/pre.json @@ -52,12 +52,14 @@ "fetchable-start-handler", "fix-runnable-environment-check", "fix-ssr-stream-abort-crash", + "fix-vitest-workspace-environment", "handler-edge-commit-fold", "honor-host-noexternal-patterns", "host-integration-extension-points", "http-bridge-h2-tls-abort", "id-hash-second-segment", "inject-deployment-secret", + "jest-dom-resolve-from-project-root", "jest-dom-v7-next", "lazy-entry-eliminated-importers", "lazy-entry-rolldown-reclassify", @@ -79,6 +81,7 @@ "reject-prefixed-server-env-keys", "remove-client-manifest-virtual", "response-head-middleware-preview", + "ride-solid-rc-9", "root-relative-filter-globs", "sc-bootstrap-before-hydration-data", "scoped-server-function-dce", @@ -98,7 +101,9 @@ "ssr-inline-solid-consumers", "start-css-filter", "start-env-typed", + "start-instrument-early-server-import", "start-mode-terminology", + "start-node-entry", "start-render-mode", "start-setup-hook", "support-tsrx-vite", diff --git a/CHANGELOG.md b/CHANGELOG.md index cda5d47..52cd38b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,24 @@ # Changelog +## 3.0.0-next.44 + +### Minor Changes + +- 22858a3: `start.node`: the build emits a ready-to-run Node server. With `start: { node: true }` the ssr build writes `dist/server/node.js` beside `server.js` — `node dist/server/node.js` (env `PORT`, default 3000, and `HOST`) serves the client build statically (files under `build.assetsDir` as `Cache-Control: public, max-age=31536000, immutable`, everything else `public, max-age=0, must-revalidate` with `Last-Modified`; a reasonable MIME table, `HEAD`, dot-segment paths and `..` traversal refused) and hands every other request to `handleRequest` with the raw Node request as `nativeEvent`, so `getRequestEvent().nativeEvent` answers the same as under `vite dev` and `vite preview`. The node<->web bridge is the plugin's own `src/http.ts` — the code the dev and preview middlewares already run (HTTP/2 pseudo-headers, `https:` on TLS sockets, client disconnects as the request's `AbortSignal`, HEAD short-circuit, `set-cookie` split, backpressure that also settles on close) — shipped as a separate build artifact of the package (`dist/node-entry.mjs`) that the plugin reads at build time and emits under a small generated header carrying the emit-time constants (client dir relative to the server dir, `assetsDir`, `base`, the mode). The file is ESM with no dependency beyond `node:*` and `./server.js`, listens only when run directly, and exports `listener` (the `(req, res)` function, mountable into `http.createServer`, Express, Fastify), `createListener({ static?, event? })` — `static: false` leaves files and the client-mode `index.html` fallback to a framework such as `express.static` or a CDN and keeps only the bridge; `event: (req) => fields` merges extra request-event fields over `{ nativeEvent: req }` — and `serve({ port?, host?, static?, event? })`. + + Why: the fullstack templates shipped a hand-written `server.js` whose bulk was this generic Node bridge, copied into every scaffold and baked into the CLI, so bridge fixes never reached users — and it looked custom-made. Node is the one mainstream runtime without a fetch-shaped server API (Workers, Deno, Bun, Netlify, Nitro consume the server bundle's `{ fetch }` directly), so the gap is Node-only and belongs in the build output. It is a `start.*` option, not `ssr.*` (`ssr` stays boolean-only), and applies to both start modes: SSR mode renders pages; client mode with `serverFunctions` (which keeps `dist/server`) serves the static client with an `index.html` history fallback for HTML navigations plus the endpoint. `node.js` is an emitted asset, never a second build input — `server.js` and its `handleRequest` / `{ fetch }` contracts are unchanged, and nothing changes without the option. Where no server bundle exists (client mode without `serverFunctions`, or `start.external`) the build warns and emits nothing. Compression/proxy stance unchanged: plain HTTP, put a reverse proxy or CDN in front. Follow-ups this unlocks: the templates drop `server.js` and point their `start` script at `node dist/server/node.js`; create-solid drops its baked `SERVER_JS` constant. + +### Patch Changes + +- 7fa5aa3: Avoid overriding environments configured in Vitest workspaces and projects with the `jsdom` default (forward-port of #323 by @carloitaben, fixes #205). A root config that defines `test.projects` (or the pre-Vitest-4 `test.workspace`) runs no tests itself, so it no longer gets `test.environment: 'jsdom'` injected — which made Vitest probe for (and prompt to install) jsdom at startup even when every project runs under node or in browser mode. Each project keeps controlling its own environment. +- d30f051: Only inject the `@testing-library/jest-dom` Vitest setup file when the package resolves from the project root (forward-port of #364 by @brenelz, fixes #231). Previously the check ran from the plugin's own location, so with pnpm a transitive jest-dom (for example via Storybook) made Vitest fail with `Failed to load url .../@testing-library/jest-dom/vitest`. The probe now walks `node_modules` up from the Vite root the way Vitest resolves bare `setupFiles` — deliberately ignoring `NODE_PATH`, which pnpm's bin shims (`pnpm vitest`) point at the hoisted virtual store where every transitive dependency is reachable. +- 2e79544: Require solid-js / @solidjs/web 2.0.0-rc.9 (peer floor) and compile with @solidjs/compiler / @solidjs/babel-plugin rc.9 — runtime and compiler move in lockstep. The rc.9 compilers emit output only the rc.9 runtime understands, so this floor is a hard requirement, not policy: native elements with several spread sources compile to the runtimes' array form (`spread(el, [a, b], …)` on the client, `ssrElement(tag, [a, b], …)` on the server — no `mergeProps()` proxy, no memo, no hydration id; #3418/#3419/#3423) which only rc.9's `@solidjs/web` accepts; delegated event handlers move off Solid 1's `$$` element key onto `_$$` in both compiled output and the runtime's document delegate, so an rc.8 runtime would never fire an rc.9-compiled `onClick` (and vice versa); and under `componentNames` — which the plugin already turns on for its dev and observe postures — SSR output keeps `createComponent(Comp, props, "Comp")` so the server runtime's observe/dev tier labels the owner and a server finding's `ownerPath` reads `` like the client's. Nothing in the plugin itself had to change for rc.9: the new `observe` / `development` export conditions on `@solidjs/web`'s server-functions and frames client entries (and `observe` on every server entry) are picked up by the condition lists the plugin already installs, and the new `solid-js/internal` subpath is covered by the existing `solid-js` inlining. +- 256c25d: `start.instrument`: a server-only module the plugin runs to completion before anything else in the server graph loads — the app, the middleware, `@solidjs/web`, every dependency. The seam for instrumentation that must patch the runtime before the modules it patches are loaded (an APM's OpenTelemetry setup, a profiler, a `module.register` hook), honored on every surface: `vite dev`, `vite build`, `vite preview`, and a host consuming the handler entry. Replaces the per-host `node --import instrument.mjs` dance. + + Import order cannot do this in ESM — static imports are hoisted and evaluated in dependency order — so the generated handler entry becomes `await import(instrument); await import(handler)`, with the handler's surface (`handleRequest`, the `fetch` default) re-declared by name. The module may be async and needs no exports; the server build must keep code splitting on (the default). + + Also: the `componentNames` note in the compiler options no longer calls the labels DOM-only — the SSR generate emits them too from the compilers that carry solidjs/solid#3441 (2.0.0-rc.9), and the start-ssr suite gains an `observe` mode that asserts an `observe: true` production build resolves the observe artifacts and carries component labels (the SSR half asserted once the workspace rides an rc that emits them). + ## 3.0.0-next.43 ### Patch Changes diff --git a/package.json b/package.json index 1ae262c..d5b4aba 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@solidjs/vite-plugin", - "version": "3.0.0-next.43", + "version": "3.0.0-next.44", "description": "solid-js integration plugin for Vite", "type": "module", "engines": {