Skip to content

Commit e70ff22

Browse files
refactor(ui): rename VITE_APP_EXTENSIONS to VITE_EXAMPLE_EXTENSION
The name promised a list of extensions to install and delivered a boolean switch for the bundled example — the only value it ever matched was the literal "example", and no other value could do anything, because an extension has to be imported to exist in the bundle at all. `VITE_EXAMPLE_EXTENSION=true` says what it does. Which extensions are installed stays the array in `activeExtensions.ts`, and there is no environment variable for it. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Signed-off-by: Nicholas Bucher <behappy54321@gmail.com>
1 parent a3f7b6d commit e70ff22

6 files changed

Lines changed: 28 additions & 16 deletions

File tree

ui/docs/app-extensions.md

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ entry; nothing else in the application changes.
1818

1919
Nothing is installed by default, including the bundled example. To see the example
2020
running without editing the file, start the dev server with
21-
`VITE_APP_EXTENSIONS=example yarn dev`.
21+
`VITE_EXAMPLE_EXTENSION=true yarn dev`.
2222

2323
---
2424

@@ -81,7 +81,7 @@ installed, so a default build renders only what this project itself provides.
8181
Switch it on with:
8282

8383
```bash
84-
VITE_APP_EXTENSIONS=example yarn dev
84+
VITE_EXAMPLE_EXTENSION=true yarn dev
8585
```
8686

8787
Read that directory alongside this document — it exercises every extension point
@@ -524,10 +524,10 @@ two consequences of it are worth knowing:
524524

525525
### The two build-time exceptions
526526

527-
`VITE_API_MODE` and `VITE_APP_EXTENSIONS` are the only variables in this UI that
527+
`VITE_API_MODE` and `VITE_EXAMPLE_EXTENSION` are the only variables in this UI that
528528
carry a `VITE_` prefix, and neither is a deployment setting:
529529

530-
| | `VITE_API_MODE`, `VITE_APP_EXTENSIONS` | `EXTENSION_*` |
530+
| | `VITE_API_MODE`, `VITE_EXAMPLE_EXTENSION` | `EXTENSION_*` |
531531
|---|---|---|
532532
| Read with | `import.meta.env` | `readEnv` |
533533
| Fixed when | the bundle is built | the container starts |
@@ -540,9 +540,11 @@ read at runtime, so an extension setting never takes it — prefixed, the variab
540540
would no longer match the `EXTENSION_` prefix the init script and the dev server
541541
select on, and `readEnv` would quietly return the fallback.
542542

543-
`VITE_APP_EXTENSIONS` is also not a way to install an extension. It only appends the
544-
bundled example, for the e2e suite and for a look at it running. Installing is the
545-
array.
543+
`VITE_EXAMPLE_EXTENSION=true` is a switch for the bundled example and nothing else.
544+
It cannot name an extension — an extension has to be *imported* to exist in the
545+
bundle at all, which is the same reason installing one is an edit to
546+
`activeExtensions.ts` rather than a setting. There is no environment variable that
547+
lists the installed extensions; the array is that list.
546548

547549
---
548550

ui/playwright.config.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -42,13 +42,13 @@ const MOCK_BACKEND = { VITE_API_MODE: "mock" };
4242
* stated in one place — and so a branch that installs an extension changes a
4343
* value instead of restructuring the `projects`/`webServer` blocks.
4444
*
45-
* `VITE_APP_EXTENSIONS` is pinned on the bare server for the same reason
45+
* `VITE_EXAMPLE_EXTENSION` is pinned on the bare server for the same reason
4646
* `VITE_API_MODE` is: an inherited value must not be able to decide what a run
4747
* measures. Left unpinned, the bare project measures whatever the shell happened
4848
* to export.
4949
*/
50-
const BARE_APP = { ...MOCK_BACKEND, VITE_APP_EXTENSIONS: "none" };
51-
const EXAMPLE_APP = { ...MOCK_BACKEND, VITE_APP_EXTENSIONS: "example" };
50+
const BARE_APP = { ...MOCK_BACKEND, VITE_EXAMPLE_EXTENSION: "false" };
51+
const EXAMPLE_APP = { ...MOCK_BACKEND, VITE_EXAMPLE_EXTENSION: "true" };
5252

5353
/**
5454
* The third mode: one app, wired to a real backend.

ui/playwright/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ Which extensions a build installs is decided at build time, so "installed" and
7979
| Project | Server | Specs |
8080
|---|---|---|
8181
| `chromium` | bare — no extension, on `UI_LOOP_PORT` | everything not matching `*.withExtension.spec.ts` |
82-
| `chromium-with-extension` | `VITE_APP_EXTENSIONS=example`, on `UI_LOOP_PORT + 50` | `*.withExtension.spec.ts` |
82+
| `chromium-with-extension` | `VITE_EXAMPLE_EXTENSION=true`, on `UI_LOOP_PORT + 50` | `*.withExtension.spec.ts` |
8383

8484
A spec opts into the extension-installed app by being named `*.withExtension.spec.ts`.
8585

ui/playwright/globalSetup.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ export default async function globalSetup(config: FullConfig): Promise<void> {
5353
`${baseUrl} was expected to serve the app with the example extension ` +
5454
`installed (project "${project.name}"), but no extension points are ` +
5555
`mounted. The server on that port came up without ` +
56-
`VITE_APP_EXTENSIONS=example.`,
56+
`VITE_EXAMPLE_EXTENSION=true.`,
5757
);
5858
}
5959
if (!wantsExtension && slots > 0) {

ui/src/appExtensions/activeExtensions.ts

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,14 @@ import { exampleAppExtension } from "./example/exampleExtension";
1414
* the later entry wins. So list the extension whose opinion should prevail last.
1515
*
1616
* The worked example is not installed by default: it is documentation you can run,
17-
* not a feature of the application. `VITE_APP_EXTENSIONS=example` appends it, which
17+
* not a feature of the application. `VITE_EXAMPLE_EXTENSION=true` appends it, which
1818
* is how the framework's own extension-point specs get an installed extension to
1919
* assert against, and how anyone can see it running without editing this file.
20+
*
21+
* That switch is for the bundled example and nothing else — it names no extension
22+
* and cannot. An extension has to be imported to be in the bundle at all, which is
23+
* the same reason installing one is an edit here rather than a setting.
2024
*/
2125
export const activeAppExtensions: readonly AppExtensionConfig[] = [
22-
...(import.meta.env.VITE_APP_EXTENSIONS === "example"
23-
? [exampleAppExtension]
24-
: []),
26+
...(import.meta.env.VITE_EXAMPLE_EXTENSION === "true" ? [exampleAppExtension] : []),
2527
];

ui/src/vite-env.d.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,14 @@ interface ImportMetaEnv {
55
readonly VITE_API_MODE?: "mock" | "live";
66
/** Base URL of the real API, used when VITE_API_MODE is "live". */
77
readonly VITE_API_BASE_URL?: string;
8+
/**
9+
* `"true"` installs the bundled Example App Extension.
10+
*
11+
* A switch for that one config, not a list of extensions to install: an
12+
* extension has to be imported to be in the bundle at all, so which ones are
13+
* installed is the array in `appExtensions/activeExtensions.ts`.
14+
*/
15+
readonly VITE_EXAMPLE_EXTENSION?: "true" | "false";
816
}
917

1018
interface ImportMeta {

0 commit comments

Comments
 (0)