Skip to content
Merged
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
30 changes: 30 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -153,3 +153,33 @@ jobs:
- name: Fail if the checked-in package fixture was stale
working-directory: .
run: git diff --exit-code -- Test-UI/bundle

solid-2-consumer:
name: solid 2 consumer (rspack links it)
runs-on: ubicloud-standard-2
steps:
- uses: actions/checkout@v4

- uses: oven-sh/setup-bun@v1
with:
bun-version: latest

# The package is developed against an installed Solid 1.9, so every other
# job type-checks and runs the 2.0 sources against the wrong major. This
# one installs Solid 2 for real and asks a bundler to link the 2.0 entry.
#
# It exists because the bug it guards is a *link* error, invisible to a
# runtime check: the conditional it came from picked the correct arm when
# executed and still could not be bundled, because a bundler resolves
# both arms against the installed Solid. Verified by reintroducing that
# conditional, which fails this job with the original message:
#
# ESModulesLinkingError: export 'splitProps' (imported as 'solid') was
# not found in 'solid-js'
- name: Build the package
working-directory: packages/solid-layouts
run: bun install && bun run build

- name: Bundle a Solid 2 consumer through rspack
working-directory: fixtures/solid-2-consumer
run: bun install && bun run bundle
50 changes: 50 additions & 0 deletions SOLID-2-PLAN.md
Original file line number Diff line number Diff line change
Expand Up @@ -167,3 +167,53 @@ The 11 `@solid-primitives/*` packages `@pathscale/ui` depends on peer-pin
which change signature. They break at runtime, not at install, and no work here
fixes that. Either upstream ships Solid 2 releases, or the four or five we
actually use get vendored.

## Correction, 2026-08-18: runtime detection cannot be bundled

The table above records three differences as "told apart at runtime from the
module object itself, so they needed no fork at all". For `splitProps`/`omit`
that was wrong, and it was wrong in a way no test in this repository could
see.

`"omit" in solid ? solid.omit(...) : solid.splitProps(...)` picks the correct
arm every time it executes. It still cannot be linked: a bundler resolves
*both* arms against the installed `solid-js`, so when a consumer bundles
against Solid 2 the 1.9 arm's `splitProps` is a missing export and the build
fails before any of it runs.

ESModulesLinkingError: export 'splitProps' (imported as 'solid') was not
found in 'solid-js'

It reached a consumer as a build that would not start, and every job here was
green at the time, because all of them run this package against the installed
Solid 1.9 and none of them asked a bundler to link the 2.0 entry.

**The rule this yields:** a difference between majors belongs in `renderer.ts`,
which the build already swaps, not in a runtime conditional. Only the arm that
exists is then compiled. Runtime detection is fine for a value that varies
within one major, and never for one that varies between them.

**The guard:** `fixtures/solid-2-consumer` installs `solid-js@2.0.0-rc.0` and
`@solidjs/web@2.0.0-rc.0`, imports the package's `solid-2` entry, and bundles
it with Rspack, which is the linker that produced the original failure. The
`solid-2-consumer` CI job runs it. Reintroducing the conditional fails that job
with the message above, which was checked rather than assumed.

**What it does not cover.** The fixture imports the entry and calls into it; it
writes no JSX, so it exercises the Solid 2 *runtime* and not the Solid 2
*compiler*. Those are separate choices: a consumer must also point its JSX
transform at Solid 2 (`babel-preset-solid@2`, whose `moduleName` defaults to
`@solidjs/web`), and a build that gets the runtime right and the transform
wrong emits `solid-js/web` imports, a subpath 2.0 removed. Covering that means
a second fixture that compiles a component, and it is not covered here.

Two traps found while writing the fixture, both worth knowing before touching
it:

- Aliasing `solid-layouts` to the package root does not work. An alias replaces
the whole specifier, so the `/solid-2` subpath export is never consulted; the
alias has to name the built entry.
- Solid must be aliased to the *fixture's* copy. Otherwise the bundler walks up
to `packages/solid-layouts/node_modules` and links `@solidjs/web` 2.0 against
Solid 1.9, which fails on a dozen unrelated exports and says nothing about
the code under test.
2 changes: 2 additions & 0 deletions fixtures/solid-2-consumer/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
dist/
node_modules/
Loading
Loading