@scaffold-ui-kit/preview 0.0.0-stage → 2.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +1868 -2
- package/application/host/bootstrap.ts +43 -0
- package/application/host/main.ts +31 -0
- package/application/host/shell-host.ts +47 -0
- package/application/index.html +12 -0
- package/application/lib/base-url.ts +15 -0
- package/application/lib/no-code-block.ts +7 -0
- package/application/lib/no-setup.ts +3 -0
- package/application/lib/no-views.ts +6 -0
- package/application/preview/code/code.html +12 -0
- package/application/preview/code/main.ts +89 -0
- package/application/preview/globals.ts +254 -0
- package/application/preview/html/main.ts +93 -0
- package/application/preview/html/preview.html +12 -0
- package/application/preview/react/main.tsx +146 -0
- package/application/preview/react/preview.html +12 -0
- package/application/preview/svelte/Preview.svelte +104 -0
- package/application/preview/svelte/main.ts +13 -0
- package/application/preview/svelte/preview.html +12 -0
- package/application/preview/svelte/story-props.ts +172 -0
- package/application/preview/view/main.ts +124 -0
- package/application/preview/view/view.html +12 -0
- package/application/preview/vue/main.ts +145 -0
- package/application/preview/vue/preview.html +12 -0
- package/application/shells/charcell/components/Application/index.css +37 -0
- package/application/shells/charcell/components/Application/index.tsx +65 -0
- package/application/shells/charcell/components/Bar/index.css +68 -0
- package/application/shells/charcell/components/Bar/index.tsx +60 -0
- package/application/shells/charcell/components/CodePane/index.css +60 -0
- package/application/shells/charcell/components/CodePane/index.tsx +113 -0
- package/application/shells/charcell/components/ComponentStage/index.css +26 -0
- package/application/shells/charcell/components/ComponentStage/index.tsx +110 -0
- package/application/shells/charcell/components/Control/index.css +20 -0
- package/application/shells/charcell/components/Control/index.tsx +118 -0
- package/application/shells/charcell/components/CopyLink/index.tsx +35 -0
- package/application/shells/charcell/components/Description/index.css +6 -0
- package/application/shells/charcell/components/Description/index.tsx +24 -0
- package/application/shells/charcell/components/EditorAddDialog/index.css +9 -0
- package/application/shells/charcell/components/EditorAddDialog/index.tsx +158 -0
- package/application/shells/charcell/components/EditorPanel/index.css +48 -0
- package/application/shells/charcell/components/EditorPanel/index.tsx +496 -0
- package/application/shells/charcell/components/EventsRow/index.css +42 -0
- package/application/shells/charcell/components/EventsRow/index.tsx +68 -0
- package/application/shells/charcell/components/HeadingRow/index.css +11 -0
- package/application/shells/charcell/components/HeadingRow/index.tsx +16 -0
- package/application/shells/charcell/components/Hint/index.css +16 -0
- package/application/shells/charcell/components/Hint/index.tsx +81 -0
- package/application/shells/charcell/components/HtmlWarnings/index.tsx +45 -0
- package/application/shells/charcell/components/KeyHints/index.css +27 -0
- package/application/shells/charcell/components/KeyHints/index.tsx +106 -0
- package/application/shells/charcell/components/KitCodeBlock/index.css +55 -0
- package/application/shells/charcell/components/KitCodeBlock/index.tsx +18 -0
- package/application/shells/charcell/components/Markdown/index.tsx +16 -0
- package/application/shells/charcell/components/Navigation/index.css +13 -0
- package/application/shells/charcell/components/Navigation/index.tsx +98 -0
- package/application/shells/charcell/components/NavigationSplit/index.css +16 -0
- package/application/shells/charcell/components/NavigationSplit/index.tsx +82 -0
- package/application/shells/charcell/components/OptionControls/index.tsx +93 -0
- package/application/shells/charcell/components/PaneStatus/index.css +7 -0
- package/application/shells/charcell/components/PaneStatus/index.tsx +47 -0
- package/application/shells/charcell/components/PaneWidth/index.tsx +45 -0
- package/application/shells/charcell/components/PreviewGrid/index.css +39 -0
- package/application/shells/charcell/components/PreviewGrid/index.tsx +344 -0
- package/application/shells/charcell/components/PreviewPane/index.css +127 -0
- package/application/shells/charcell/components/PreviewPane/index.tsx +182 -0
- package/application/shells/charcell/components/PromptBar/index.tsx +133 -0
- package/application/shells/charcell/components/ScenarioRow/index.css +36 -0
- package/application/shells/charcell/components/ScenarioRow/index.tsx +71 -0
- package/application/shells/charcell/components/Select/index.tsx +48 -0
- package/application/shells/charcell/components/SlotOutlet/index.css +7 -0
- package/application/shells/charcell/components/SlotOutlet/index.tsx +25 -0
- package/application/shells/charcell/components/StageBar/index.css +7 -0
- package/application/shells/charcell/components/StageBar/index.tsx +109 -0
- package/application/shells/charcell/components/StageSplit/index.css +11 -0
- package/application/shells/charcell/components/StageSplit/index.tsx +99 -0
- package/application/shells/charcell/components/StatusBar/index.tsx +30 -0
- package/application/shells/charcell/components/ViewControls/index.css +15 -0
- package/application/shells/charcell/components/ViewControls/index.tsx +58 -0
- package/application/shells/charcell/components/ViewHeading/index.css +13 -0
- package/application/shells/charcell/components/ViewHeading/index.tsx +8 -0
- package/application/shells/charcell/components/ViewStage/index.css +9 -0
- package/application/shells/charcell/components/ViewStage/index.tsx +25 -0
- package/application/shells/charcell/components/WrapToggle/index.tsx +27 -0
- package/application/shells/charcell/configuration.ts +45 -0
- package/application/shells/charcell/controller-context.ts +27 -0
- package/application/shells/charcell/fit-labels.ts +42 -0
- package/application/shells/charcell/html-warnings.ts +18 -0
- package/application/shells/charcell/index.tsx +82 -0
- package/application/shells/charcell/page-loading.html +57 -0
- package/application/shells/charcell/placement.ts +24 -0
- package/application/shells/charcell/shell-options.ts +23 -0
- package/application/shells/charcell/shell.css +37 -0
- package/application/shells/charcell/shell.tsx +25 -0
- package/application/shells/charcell/split-reset.ts +47 -0
- package/application/shells/charcell/stacked-rows.ts +117 -0
- package/application/shells/charcell/stage-toggles.ts +93 -0
- package/application/types/manifest.d.ts +6 -0
- package/application/types/preview-configuration.d.ts +10 -0
- package/application/types/preview-shell.d.ts +7 -0
- package/application/types/react-registry.d.ts +15 -0
- package/application/types/vue-registry.d.ts +6 -0
- package/dist/build.d.ts +24 -0
- package/dist/build.js +34 -0
- package/dist/check.d.ts +48 -0
- package/dist/check.js +781 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +88 -0
- package/dist/context.d.ts +179 -0
- package/dist/context.js +783 -0
- package/dist/controller/catalog.d.ts +339 -0
- package/dist/controller/catalog.js +367 -0
- package/dist/controller/create-preview-controller.d.ts +532 -0
- package/dist/controller/create-preview-controller.js +1707 -0
- package/dist/controller/editor-tree.d.ts +161 -0
- package/dist/controller/editor-tree.js +373 -0
- package/dist/controller/html-source.d.ts +62 -0
- package/dist/controller/html-source.js +61 -0
- package/dist/controller/index.d.ts +9 -0
- package/dist/controller/index.js +12 -0
- package/dist/controller/persistence.d.ts +191 -0
- package/dist/controller/persistence.js +315 -0
- package/dist/controller/regeneration.d.ts +30 -0
- package/dist/controller/regeneration.js +27 -0
- package/dist/controller/source.d.ts +80 -0
- package/dist/controller/source.js +236 -0
- package/dist/controller/store.d.ts +27 -0
- package/dist/controller/store.js +40 -0
- package/dist/declarations/application/shells/charcell/components/Application/index.d.ts +2 -0
- package/dist/declarations/application/shells/charcell/components/Bar/index.d.ts +11 -0
- package/dist/declarations/application/shells/charcell/components/CodePane/index.d.ts +5 -0
- package/dist/declarations/application/shells/charcell/components/ComponentStage/index.d.ts +2 -0
- package/dist/declarations/application/shells/charcell/components/Control/index.d.ts +9 -0
- package/dist/declarations/application/shells/charcell/components/CopyLink/index.d.ts +1 -0
- package/dist/declarations/application/shells/charcell/components/Description/index.d.ts +5 -0
- package/dist/declarations/application/shells/charcell/components/EditorAddDialog/index.d.ts +6 -0
- package/dist/declarations/application/shells/charcell/components/EditorPanel/index.d.ts +2 -0
- package/dist/declarations/application/shells/charcell/components/EventsRow/index.d.ts +4 -0
- package/dist/declarations/application/shells/charcell/components/HeadingRow/index.d.ts +6 -0
- package/dist/declarations/application/shells/charcell/components/Hint/index.d.ts +11 -0
- package/dist/declarations/application/shells/charcell/components/HtmlWarnings/index.d.ts +5 -0
- package/dist/declarations/application/shells/charcell/components/KeyHints/index.d.ts +2 -0
- package/dist/declarations/application/shells/charcell/components/KitCodeBlock/index.d.ts +5 -0
- package/dist/declarations/application/shells/charcell/components/Markdown/index.d.ts +3 -0
- package/dist/declarations/application/shells/charcell/components/Navigation/index.d.ts +8 -0
- package/dist/declarations/application/shells/charcell/components/NavigationSplit/index.d.ts +7 -0
- package/dist/declarations/application/shells/charcell/components/OptionControls/index.d.ts +7 -0
- package/dist/declarations/application/shells/charcell/components/PaneStatus/index.d.ts +2 -0
- package/dist/declarations/application/shells/charcell/components/PaneWidth/index.d.ts +4 -0
- package/dist/declarations/application/shells/charcell/components/PreviewGrid/index.d.ts +7 -0
- package/dist/declarations/application/shells/charcell/components/PreviewPane/index.d.ts +9 -0
- package/dist/declarations/application/shells/charcell/components/PromptBar/index.d.ts +1 -0
- package/dist/declarations/application/shells/charcell/components/ScenarioRow/index.d.ts +2 -0
- package/dist/declarations/application/shells/charcell/components/Select/index.d.ts +16 -0
- package/dist/declarations/application/shells/charcell/components/SlotOutlet/index.d.ts +5 -0
- package/dist/declarations/application/shells/charcell/components/StageBar/index.d.ts +2 -0
- package/dist/declarations/application/shells/charcell/components/StageSplit/index.d.ts +17 -0
- package/dist/declarations/application/shells/charcell/components/StatusBar/index.d.ts +1 -0
- package/dist/declarations/application/shells/charcell/components/ViewControls/index.d.ts +9 -0
- package/dist/declarations/application/shells/charcell/components/ViewHeading/index.d.ts +4 -0
- package/dist/declarations/application/shells/charcell/components/ViewStage/index.d.ts +4 -0
- package/dist/declarations/application/shells/charcell/components/WrapToggle/index.d.ts +1 -0
- package/dist/declarations/application/shells/charcell/configuration.d.ts +31 -0
- package/dist/declarations/application/shells/charcell/controller-context.d.ts +9 -0
- package/dist/declarations/application/shells/charcell/fit-labels.d.ts +18 -0
- package/dist/declarations/application/shells/charcell/html-warnings.d.ts +5 -0
- package/dist/declarations/application/shells/charcell/index.d.ts +39 -0
- package/dist/declarations/application/shells/charcell/placement.d.ts +7 -0
- package/dist/declarations/application/shells/charcell/shell-options.d.ts +15 -0
- package/dist/declarations/application/shells/charcell/shell.d.ts +9 -0
- package/dist/declarations/application/shells/charcell/split-reset.d.ts +30 -0
- package/dist/declarations/application/shells/charcell/stacked-rows.d.ts +58 -0
- package/dist/declarations/application/shells/charcell/stage-toggles.d.ts +28 -0
- package/dist/declarations/src/controller/catalog.d.ts +339 -0
- package/dist/declarations/src/controller/create-preview-controller.d.ts +532 -0
- package/dist/declarations/src/controller/editor-tree.d.ts +161 -0
- package/dist/declarations/src/controller/html-source.d.ts +62 -0
- package/dist/declarations/src/controller/index.d.ts +9 -0
- package/dist/declarations/src/controller/persistence.d.ts +191 -0
- package/dist/declarations/src/controller/regeneration.d.ts +30 -0
- package/dist/declarations/src/controller/source.d.ts +80 -0
- package/dist/declarations/src/controller/store.d.ts +27 -0
- package/dist/declarations/src/emit/common.d.ts +103 -0
- package/dist/declarations/src/emit/manifest.d.ts +138 -0
- package/dist/declarations/src/emit/source.d.ts +87 -0
- package/dist/declarations/src/lib/jsx-roots.d.ts +22 -0
- package/dist/declarations/src/lib/module-of-source.d.ts +18 -0
- package/dist/declarations/src/lib/naming.d.ts +29 -0
- package/dist/declarations/src/lib/react-spelling.d.ts +68 -0
- package/dist/declarations/src/lib/scenario-story.d.ts +41 -0
- package/dist/declarations/src/lib/slot-fill.d.ts +15 -0
- package/dist/declarations/src/lib/types.d.ts +741 -0
- package/dist/declarations/src/options.d.ts +224 -0
- package/dist/declarations/src/protocol.d.ts +541 -0
- package/dist/declarations/src/react-view.d.ts +22 -0
- package/dist/declarations/src/react.d.ts +17 -0
- package/dist/declarations/src/shell.d.ts +99 -0
- package/dist/declarations/src/views.d.ts +152 -0
- package/dist/development-server.d.ts +121 -0
- package/dist/development-server.js +331 -0
- package/dist/emit/common.d.ts +103 -0
- package/dist/emit/common.js +170 -0
- package/dist/emit/html-source.d.ts +46 -0
- package/dist/emit/html-source.js +322 -0
- package/dist/emit/manifest.d.ts +138 -0
- package/dist/emit/manifest.js +74 -0
- package/dist/emit/react.d.ts +16 -0
- package/dist/emit/react.js +210 -0
- package/dist/emit/scratch.d.ts +40 -0
- package/dist/emit/scratch.js +116 -0
- package/dist/emit/source.d.ts +87 -0
- package/dist/emit/source.js +789 -0
- package/dist/emit/svelte.d.ts +9 -0
- package/dist/emit/svelte.js +177 -0
- package/dist/emit/vue.d.ts +2 -0
- package/dist/emit/vue.js +152 -0
- package/dist/enumerate.d.ts +2 -0
- package/dist/enumerate.js +162 -0
- package/dist/generate.d.ts +43 -0
- package/dist/generate.js +302 -0
- package/dist/html-stylesheet.d.ts +43 -0
- package/dist/html-stylesheet.js +145 -0
- package/dist/index.d.ts +18 -0
- package/dist/index.js +21 -0
- package/dist/landing.d.ts +16 -0
- package/dist/landing.js +45 -0
- package/dist/lib/exported-types.d.ts +42 -0
- package/dist/lib/exported-types.js +86 -0
- package/dist/lib/html-attributes.d.ts +2 -0
- package/dist/lib/html-attributes.js +111 -0
- package/dist/lib/html-warnings.d.ts +19 -0
- package/dist/lib/html-warnings.js +79 -0
- package/dist/lib/jsx-roots.d.ts +22 -0
- package/dist/lib/jsx-roots.js +243 -0
- package/dist/lib/module-of-source.d.ts +18 -0
- package/dist/lib/module-of-source.js +24 -0
- package/dist/lib/naming.d.ts +29 -0
- package/dist/lib/naming.js +56 -0
- package/dist/lib/parse-type.d.ts +32 -0
- package/dist/lib/parse-type.js +103 -0
- package/dist/lib/react-spelling.d.ts +68 -0
- package/dist/lib/react-spelling.js +197 -0
- package/dist/lib/scenario-story.d.ts +41 -0
- package/dist/lib/scenario-story.js +84 -0
- package/dist/lib/slot-fill.d.ts +15 -0
- package/dist/lib/slot-fill.js +92 -0
- package/dist/lib/template-files.d.ts +14 -0
- package/dist/lib/template-files.js +25 -0
- package/dist/lib/types.d.ts +741 -0
- package/dist/lib/types.js +13 -0
- package/dist/lib/void-elements.d.ts +7 -0
- package/dist/lib/void-elements.js +13 -0
- package/dist/load.d.ts +37 -0
- package/dist/load.js +82 -0
- package/dist/model.d.ts +44 -0
- package/dist/model.js +464 -0
- package/dist/options.d.ts +224 -0
- package/dist/options.js +223 -0
- package/dist/prop-types.d.ts +26 -0
- package/dist/prop-types.js +102 -0
- package/dist/props-from.d.ts +84 -0
- package/dist/props-from.js +510 -0
- package/dist/protocol.d.ts +541 -0
- package/dist/protocol.js +819 -0
- package/dist/react-view.d.ts +22 -0
- package/dist/react-view.js +36 -0
- package/dist/react.d.ts +17 -0
- package/dist/react.js +23 -0
- package/dist/sass-importers.d.ts +26 -0
- package/dist/sass-importers.js +32 -0
- package/dist/shell-acceptance.d.ts +21 -0
- package/dist/shell-acceptance.js +37 -0
- package/dist/shell-page.d.ts +36 -0
- package/dist/shell-page.js +90 -0
- package/dist/shell-peers.d.ts +38 -0
- package/dist/shell-peers.js +61 -0
- package/dist/shell.d.ts +99 -0
- package/dist/shell.js +52 -0
- package/dist/shells/charcell/page.d.ts +8 -0
- package/dist/shells/charcell/page.js +69 -0
- package/dist/story-source.d.ts +113 -0
- package/dist/story-source.js +271 -0
- package/dist/story.d.ts +5 -0
- package/dist/story.js +28 -0
- package/dist/testing.d.ts +218 -0
- package/dist/testing.js +284 -0
- package/dist/views.d.ts +152 -0
- package/dist/views.js +7 -0
- package/dist/vite-configuration.d.ts +114 -0
- package/dist/vite-configuration.js +578 -0
- package/package.json +123 -3
- package/src/build.ts +51 -0
- package/src/check.ts +1062 -0
- package/src/cli.ts +123 -0
- package/src/context.ts +1168 -0
- package/src/controller/catalog.ts +719 -0
- package/src/controller/create-preview-controller.ts +2683 -0
- package/src/controller/editor-tree.ts +530 -0
- package/src/controller/html-source.ts +114 -0
- package/src/controller/index.ts +105 -0
- package/src/controller/persistence.ts +403 -0
- package/src/controller/regeneration.ts +55 -0
- package/src/controller/source.ts +333 -0
- package/src/controller/store.ts +55 -0
- package/src/development-server.ts +442 -0
- package/src/emit/common.ts +201 -0
- package/src/emit/html-source.ts +402 -0
- package/src/emit/manifest.ts +241 -0
- package/src/emit/react.ts +263 -0
- package/src/emit/scratch.ts +175 -0
- package/src/emit/source.ts +1094 -0
- package/src/emit/svelte.ts +230 -0
- package/src/emit/vue.ts +194 -0
- package/src/enumerate.ts +220 -0
- package/src/generate.ts +443 -0
- package/src/html-stylesheet.ts +173 -0
- package/src/index.ts +60 -0
- package/src/landing.ts +58 -0
- package/src/lib/exported-types.ts +114 -0
- package/src/lib/html-attributes.ts +113 -0
- package/src/lib/html-warnings.ts +81 -0
- package/src/lib/jsx-roots.ts +238 -0
- package/src/lib/module-of-source.ts +26 -0
- package/src/lib/naming.ts +65 -0
- package/src/lib/parse-type.ts +143 -0
- package/src/lib/react-spelling.ts +235 -0
- package/src/lib/scenario-story.ts +97 -0
- package/src/lib/slot-fill.ts +102 -0
- package/src/lib/template-files.ts +31 -0
- package/src/lib/types.ts +778 -0
- package/src/lib/void-elements.ts +15 -0
- package/src/load.ts +144 -0
- package/src/model.ts +568 -0
- package/src/options.ts +435 -0
- package/src/prop-types.ts +133 -0
- package/src/props-from.ts +678 -0
- package/src/protocol.ts +1135 -0
- package/src/react-view.ts +45 -0
- package/src/react.ts +34 -0
- package/src/sass-importers.ts +45 -0
- package/src/shell-acceptance.ts +45 -0
- package/src/shell-page.ts +133 -0
- package/src/shell-peers.ts +70 -0
- package/src/shell.ts +194 -0
- package/src/shells/charcell/page.ts +82 -0
- package/src/story-source.ts +391 -0
- package/src/story.ts +42 -0
- package/src/testing.ts +497 -0
- package/src/views.ts +183 -0
- package/src/vite-configuration.ts +675 -0
|
@@ -0,0 +1,675 @@
|
|
|
1
|
+
// The preview's Vite configuration, built from the preview context. One server
|
|
2
|
+
// hosts the host page (the bootstrap and the shell it loads) plus the
|
|
3
|
+
// per-target preview iframes and the html one (each its own entry); the framework plugins
|
|
4
|
+
// coexist by file extension. Everything kit-specific arrives through the
|
|
5
|
+
// context: the generated registries (`@preview-generated`), the data of the
|
|
6
|
+
// kit's preview block (`@preview-configuration`, served as JSON), its custom views
|
|
7
|
+
// (`@preview-views`), its shell (`@preview-shell`), preview-only aliases,
|
|
8
|
+
// SCSS load paths and `pkg:` URLs, the prebundle exclusions for raw-`.svelte` shippers, and
|
|
9
|
+
// the packages the kit names to load once.
|
|
10
|
+
|
|
11
|
+
import { existsSync } from 'node:fs';
|
|
12
|
+
import { createRequire } from 'node:module';
|
|
13
|
+
import { dirname, posix, relative, resolve } from 'node:path';
|
|
14
|
+
import { fileURLToPath } from 'node:url';
|
|
15
|
+
import {
|
|
16
|
+
searchForWorkspaceRoot,
|
|
17
|
+
type Alias,
|
|
18
|
+
type InlineConfig,
|
|
19
|
+
type Plugin,
|
|
20
|
+
type Rollup,
|
|
21
|
+
} from 'vite';
|
|
22
|
+
import react from '@vitejs/plugin-react';
|
|
23
|
+
import vue from '@vitejs/plugin-vue';
|
|
24
|
+
import { svelte } from '@sveltejs/vite-plugin-svelte';
|
|
25
|
+
import type { PreviewContext } from './context.js';
|
|
26
|
+
import { PREVIEW_BROWSER_KEYS } from './lib/types.js';
|
|
27
|
+
import { loadKit } from './load.js';
|
|
28
|
+
import {
|
|
29
|
+
missingShellPeers,
|
|
30
|
+
missingShellPeersProblem,
|
|
31
|
+
resolvesFrom,
|
|
32
|
+
} from './shell-peers.js';
|
|
33
|
+
import {
|
|
34
|
+
HOST_PAGE,
|
|
35
|
+
loadShellPage,
|
|
36
|
+
type ResolvedShellPage,
|
|
37
|
+
} from './shell-page.js';
|
|
38
|
+
import { printHtmlSource } from './story-source.js';
|
|
39
|
+
import { writeScratch, type ScratchPayload } from './emit/scratch.js';
|
|
40
|
+
import { htmlSourceResponse } from './html-stylesheet.js';
|
|
41
|
+
import { kitImporters, kitPackageDirectories } from './sass-importers.js';
|
|
42
|
+
import {
|
|
43
|
+
HTML_SOURCE_ENDPOINT,
|
|
44
|
+
type HtmlSourceRequest,
|
|
45
|
+
} from './controller/html-source.js';
|
|
46
|
+
|
|
47
|
+
const here = dirname(fileURLToPath(import.meta.url));
|
|
48
|
+
/** The application shell shipped with this package (`<package>/application`). */
|
|
49
|
+
export const applicationRoot = resolve(here, '../application');
|
|
50
|
+
|
|
51
|
+
/** This package's root, whose dependencies the application imports. */
|
|
52
|
+
const packageRoot = resolve(here, '..');
|
|
53
|
+
|
|
54
|
+
/** This package's name: its own subpaths are never pre-bundled, so a shell
|
|
55
|
+
* installed beside it and the bootstrap load one copy of the SDK. */
|
|
56
|
+
const PACKAGE_NAME = '@scaffold-ui-kit/preview';
|
|
57
|
+
|
|
58
|
+
/** The dev server's port when the kit configures none and `dev` is given no `--port`. */
|
|
59
|
+
export const DEFAULT_PORT = 6100;
|
|
60
|
+
|
|
61
|
+
/** The directory holding the package `specifier` resolves to from `from`:
|
|
62
|
+
* its real location, which for a `link:` dependency sits outside every
|
|
63
|
+
* workspace the server would otherwise allow. */
|
|
64
|
+
function packageDirectory(specifier: string, from: string): string | undefined {
|
|
65
|
+
let resolved: string;
|
|
66
|
+
try {
|
|
67
|
+
resolved = createRequire(from).resolve(specifier);
|
|
68
|
+
} catch {
|
|
69
|
+
return undefined;
|
|
70
|
+
}
|
|
71
|
+
for (
|
|
72
|
+
let directory = dirname(resolved);
|
|
73
|
+
directory !== dirname(directory);
|
|
74
|
+
directory = dirname(directory)
|
|
75
|
+
) {
|
|
76
|
+
if (existsSync(resolve(directory, 'package.json'))) return directory;
|
|
77
|
+
}
|
|
78
|
+
return undefined;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/** The framework runtimes the preview always loads one copy of. */
|
|
82
|
+
const FRAMEWORK_RUNTIMES = ['react', 'react-dom', 'vue', 'svelte'];
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* The aliases that load one copy of each package the kit names in `dedupe`:
|
|
86
|
+
* an import of the package, or of one of its subpaths, resolves as the kit
|
|
87
|
+
* root would resolve it, whoever imports it. Vite's own `resolve.dedupe`
|
|
88
|
+
* resolves from the server's root, this package's application directory,
|
|
89
|
+
* which need not see the kit's dependencies at all; an alias also applies
|
|
90
|
+
* while Vite prebundles dependencies, so the prebundled copy is the kit's.
|
|
91
|
+
*
|
|
92
|
+
* @param names - The packages the kit names.
|
|
93
|
+
* @param kitRoot - The kit root they resolve from.
|
|
94
|
+
* @returns One alias per package.
|
|
95
|
+
* @throws When a package does not resolve from the kit root.
|
|
96
|
+
*/
|
|
97
|
+
function kitDedupeAliases(names: readonly string[], kitRoot: string): Alias[] {
|
|
98
|
+
// Any file at the kit root stands in as the importer; it need not exist.
|
|
99
|
+
const kitImporter = resolve(kitRoot, 'package.json');
|
|
100
|
+
return names.map((name) => {
|
|
101
|
+
if (!resolvesFrom(name, kitRoot)) {
|
|
102
|
+
throw new Error(
|
|
103
|
+
`[preview] preview.dedupe names '${name}', which does not resolve from the kit root (${kitRoot}): add it to the kit's dependencies`
|
|
104
|
+
);
|
|
105
|
+
}
|
|
106
|
+
return {
|
|
107
|
+
find: new RegExp(
|
|
108
|
+
`^${name.replace(/[.*+?^${}()|[\]\\/]/g, '\\$&')}(?=/|$)`
|
|
109
|
+
),
|
|
110
|
+
replacement: name,
|
|
111
|
+
customResolver(source, _importer, options) {
|
|
112
|
+
return this.resolve(source, kitImporter, {
|
|
113
|
+
...options,
|
|
114
|
+
skipSelf: true,
|
|
115
|
+
});
|
|
116
|
+
},
|
|
117
|
+
} satisfies Alias;
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
// Scenario editor regeneration endpoint: the host POSTs its editable node tree here on
|
|
122
|
+
// each structural edit; we run it through the real emitters (imported as
|
|
123
|
+
// plain Node modules: Vite's SSR pipeline would evaluate the engine's CommonJS
|
|
124
|
+
// build as ESM and fail on `exports`) and overwrite
|
|
125
|
+
// `.preview-generated/scratch/*`, which the previews import. The host reloads the preview iframes (by bumping their
|
|
126
|
+
// src) once this POST resolves; module invalidation happens before responding
|
|
127
|
+
// so the next import re-transforms fresh content.
|
|
128
|
+
export function scratchRegenerationPlugin(generatedRoot: string): Plugin {
|
|
129
|
+
return {
|
|
130
|
+
name: 'preview-scratch-regeneration',
|
|
131
|
+
configureServer(server) {
|
|
132
|
+
server.middlewares.use('/__preview_regenerate', (request, response) => {
|
|
133
|
+
if (request.method !== 'POST') {
|
|
134
|
+
response.statusCode = 405;
|
|
135
|
+
return response.end('POST only');
|
|
136
|
+
}
|
|
137
|
+
let body = '';
|
|
138
|
+
request.on('data', (chunk) => (body += chunk));
|
|
139
|
+
request.on('end', async () => {
|
|
140
|
+
try {
|
|
141
|
+
const payload = JSON.parse(body) as ScratchPayload;
|
|
142
|
+
const written = writeScratch(payload, generatedRoot);
|
|
143
|
+
for (const file of written) {
|
|
144
|
+
for (const mod of server.moduleGraph.getModulesByFile(file) ??
|
|
145
|
+
[]) {
|
|
146
|
+
server.moduleGraph.invalidateModule(mod);
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
response.statusCode = 200;
|
|
150
|
+
response.end('ok');
|
|
151
|
+
} catch (error) {
|
|
152
|
+
// The stack goes to the server log; the editor gets the message.
|
|
153
|
+
const message =
|
|
154
|
+
error instanceof Error ? error.message : String(error);
|
|
155
|
+
const detail =
|
|
156
|
+
error instanceof Error ? (error.stack ?? error.message) : message;
|
|
157
|
+
server.config.logger.error(`[scratch-regeneration] ${detail}`);
|
|
158
|
+
response.statusCode = 500;
|
|
159
|
+
response.end(message);
|
|
160
|
+
}
|
|
161
|
+
});
|
|
162
|
+
});
|
|
163
|
+
},
|
|
164
|
+
};
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
/** The module the preview's pages import the data of the kit's preview
|
|
168
|
+
* block from. */
|
|
169
|
+
export const CONFIGURATION_MODULE = '@preview-configuration';
|
|
170
|
+
|
|
171
|
+
/**
|
|
172
|
+
* The module the preview's pages import the kit's preview block from: the
|
|
173
|
+
* keys they read (`options`, `canvas`, `themes`, `mount`, `viewCanvas`),
|
|
174
|
+
* each exported as the JSON the context loader checked it can be. The kit
|
|
175
|
+
* configuration itself, and whatever it imports, stays in Node.
|
|
176
|
+
*
|
|
177
|
+
* @param context - The kit's preview context.
|
|
178
|
+
* @returns The plugin.
|
|
179
|
+
*/
|
|
180
|
+
export function configurationModulePlugin(context: PreviewContext): Plugin {
|
|
181
|
+
const resolvedId = `\0${CONFIGURATION_MODULE}`;
|
|
182
|
+
return {
|
|
183
|
+
name: 'preview-configuration',
|
|
184
|
+
resolveId(id) {
|
|
185
|
+
return id === CONFIGURATION_MODULE ? resolvedId : undefined;
|
|
186
|
+
},
|
|
187
|
+
load(id) {
|
|
188
|
+
if (id !== resolvedId) return undefined;
|
|
189
|
+
return configurationModuleSource(context);
|
|
190
|
+
},
|
|
191
|
+
};
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
/**
|
|
195
|
+
* The source of the module {@link configurationModulePlugin} serves.
|
|
196
|
+
*
|
|
197
|
+
* @param context - The kit's preview context.
|
|
198
|
+
* @returns One `export const` per key the preview's pages read.
|
|
199
|
+
*/
|
|
200
|
+
export function configurationModuleSource(context: PreviewContext): string {
|
|
201
|
+
return PREVIEW_BROWSER_KEYS.map(
|
|
202
|
+
(key) =>
|
|
203
|
+
`export const ${key} = ${
|
|
204
|
+
context.configuration[key] === undefined
|
|
205
|
+
? 'undefined'
|
|
206
|
+
: JSON.stringify(context.configuration[key])
|
|
207
|
+
};`
|
|
208
|
+
).join('\n');
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
/** The module the html pane imports for the kit's own stylesheets. */
|
|
212
|
+
export const HTML_STYLESHEETS_MODULE = '@preview-html-stylesheets';
|
|
213
|
+
|
|
214
|
+
/**
|
|
215
|
+
* The module the html pane imports for the kit's `htmlStylesheets`: one
|
|
216
|
+
* import of each, so each loads beside the theme's stylesheet as Vite
|
|
217
|
+
* loads CSS, and none for a kit that lists none.
|
|
218
|
+
*
|
|
219
|
+
* @param context - The kit's preview context.
|
|
220
|
+
* @returns The plugin.
|
|
221
|
+
*/
|
|
222
|
+
export function htmlStylesheetsPlugin(context: PreviewContext): Plugin {
|
|
223
|
+
const resolvedId = `\0${HTML_STYLESHEETS_MODULE}`;
|
|
224
|
+
return {
|
|
225
|
+
name: 'preview-html-stylesheets',
|
|
226
|
+
resolveId(id) {
|
|
227
|
+
return id === HTML_STYLESHEETS_MODULE ? resolvedId : undefined;
|
|
228
|
+
},
|
|
229
|
+
load(id) {
|
|
230
|
+
if (id !== resolvedId) return undefined;
|
|
231
|
+
return (context.configuration.htmlStylesheets ?? [])
|
|
232
|
+
.map(
|
|
233
|
+
(path) => `import ${JSON.stringify(resolve(context.kitRoot, path))};`
|
|
234
|
+
)
|
|
235
|
+
.join('\n');
|
|
236
|
+
},
|
|
237
|
+
};
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
/**
|
|
241
|
+
* The host page's start under a shell that brings a page: the page's `head`
|
|
242
|
+
* is written at the end of the host page's `<head>` and its `root` into the
|
|
243
|
+
* root element, where it shows until the shell mounts over it. The page
|
|
244
|
+
* module is loaded once, as the configuration resolves, and the directories
|
|
245
|
+
* of the files it references are added to what the development server may
|
|
246
|
+
* serve. A shell with no page leaves the host page as it is, its root empty
|
|
247
|
+
* until the shell mounts; the iframes' pages are never touched.
|
|
248
|
+
*
|
|
249
|
+
* @param context - The kit's preview context.
|
|
250
|
+
* @returns The plugin.
|
|
251
|
+
*/
|
|
252
|
+
export function hostPagePlugin(context: PreviewContext): Plugin {
|
|
253
|
+
const hostPage = HOST_PAGE;
|
|
254
|
+
let page: Promise<ResolvedShellPage | undefined> | undefined;
|
|
255
|
+
const pageFor = (serving: boolean) =>
|
|
256
|
+
(page ??= loadShellPage(context, { hostPage, serving }));
|
|
257
|
+
return {
|
|
258
|
+
name: 'preview-host-page',
|
|
259
|
+
async config(_, { command }) {
|
|
260
|
+
const resolved = await pageFor(command === 'serve');
|
|
261
|
+
if (resolved === undefined || resolved.assetDirectories.length === 0)
|
|
262
|
+
return undefined;
|
|
263
|
+
return { server: { fs: { allow: resolved.assetDirectories } } };
|
|
264
|
+
},
|
|
265
|
+
transformIndexHtml: {
|
|
266
|
+
order: 'pre',
|
|
267
|
+
async handler(html, { filename }) {
|
|
268
|
+
if (resolve(filename) !== hostPage) return html;
|
|
269
|
+
const resolved = await pageFor(false);
|
|
270
|
+
if (resolved === undefined) return html;
|
|
271
|
+
const head = resolved.head
|
|
272
|
+
.split('\n')
|
|
273
|
+
.map((line) => ` ${line}\n `)
|
|
274
|
+
.join('');
|
|
275
|
+
return html
|
|
276
|
+
.replace('</head>', () => `${resolved.head ? head : ''}</head>`)
|
|
277
|
+
.replace(
|
|
278
|
+
'<div id="root"></div>',
|
|
279
|
+
() => `<div id="root">${resolved.root}</div>`
|
|
280
|
+
);
|
|
281
|
+
},
|
|
282
|
+
},
|
|
283
|
+
};
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
/**
|
|
287
|
+
* The stylesheets each page of the static build loads: every stylesheet of
|
|
288
|
+
* the chunks its entry imports statically, at any depth.
|
|
289
|
+
*
|
|
290
|
+
* @param entry - The page's entry chunk.
|
|
291
|
+
* @param bundle - The build's output.
|
|
292
|
+
* @returns The stylesheets' file names, in import order.
|
|
293
|
+
*/
|
|
294
|
+
function entryStylesheets(
|
|
295
|
+
entry: Rollup.OutputChunk,
|
|
296
|
+
bundle: Rollup.OutputBundle
|
|
297
|
+
): string[] {
|
|
298
|
+
const stylesheets: string[] = [];
|
|
299
|
+
const seen = new Set<string>();
|
|
300
|
+
const visit = (chunk: Rollup.OutputChunk): void => {
|
|
301
|
+
if (seen.has(chunk.fileName)) return;
|
|
302
|
+
seen.add(chunk.fileName);
|
|
303
|
+
for (const imported of chunk.imports) {
|
|
304
|
+
const importee = bundle[imported];
|
|
305
|
+
if (importee?.type === 'chunk') visit(importee);
|
|
306
|
+
}
|
|
307
|
+
for (const stylesheet of chunk.viteMetadata?.importedCss ?? [])
|
|
308
|
+
if (!stylesheets.includes(stylesheet)) stylesheets.push(stylesheet);
|
|
309
|
+
};
|
|
310
|
+
visit(entry);
|
|
311
|
+
return stylesheets;
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
/** The size, in kB after minification, past which the static build warns of
|
|
315
|
+
* a chunk, as Vite warns of one by default. */
|
|
316
|
+
export const CHUNK_SIZE_WARNING_LIMIT = 500;
|
|
317
|
+
|
|
318
|
+
/**
|
|
319
|
+
* Warns of each chunk of the static build larger than
|
|
320
|
+
* {@link CHUNK_SIZE_WARNING_LIMIT} kB, in place of Vite's own warning, which
|
|
321
|
+
* the preview turns off: under the charcell shell the host page's entry
|
|
322
|
+
* chunk, which holds the preview's interface and the shell, is the preview's
|
|
323
|
+
* own and passes over that size whatever the kit holds, so it is left out. Every
|
|
324
|
+
* other chunk, the kit's components and their dependencies among them, and
|
|
325
|
+
* the host's under a shell the kit gives, is warned of by name.
|
|
326
|
+
*
|
|
327
|
+
* @param context - The preview context, for the shell it names.
|
|
328
|
+
* @returns The plugin.
|
|
329
|
+
*/
|
|
330
|
+
export function chunkSizePlugin(
|
|
331
|
+
context: Pick<PreviewContext, 'charcellShellAbsolute'>
|
|
332
|
+
): Plugin {
|
|
333
|
+
const hostIsPreviewOwn = context.charcellShellAbsolute !== undefined;
|
|
334
|
+
return {
|
|
335
|
+
name: 'preview-chunk-size',
|
|
336
|
+
apply: 'build',
|
|
337
|
+
generateBundle(_options, bundle) {
|
|
338
|
+
const large = Object.values(bundle)
|
|
339
|
+
.filter(
|
|
340
|
+
(output): output is Rollup.OutputChunk =>
|
|
341
|
+
output.type === 'chunk' &&
|
|
342
|
+
!(hostIsPreviewOwn && output.isEntry && output.name === 'host')
|
|
343
|
+
)
|
|
344
|
+
.map((chunk) => ({
|
|
345
|
+
fileName: chunk.fileName,
|
|
346
|
+
size: Buffer.byteLength(chunk.code) / 1000,
|
|
347
|
+
}))
|
|
348
|
+
.filter(({ size }) => size > CHUNK_SIZE_WARNING_LIMIT);
|
|
349
|
+
if (large.length === 0) return;
|
|
350
|
+
this.warn(
|
|
351
|
+
`some chunks are larger than ${CHUNK_SIZE_WARNING_LIMIT} kB after minification: ${large
|
|
352
|
+
.map(({ fileName, size }) => `${fileName} (${size.toFixed(2)} kB)`)
|
|
353
|
+
.join(', ')}`
|
|
354
|
+
);
|
|
355
|
+
},
|
|
356
|
+
};
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
/**
|
|
360
|
+
* Links every page of the static build to each stylesheet its entry imports.
|
|
361
|
+
*
|
|
362
|
+
* Vite's html plugin caches each chunk's stylesheet list the first time a
|
|
363
|
+
* page reaches the chunk, filtered by what that page has already linked, and
|
|
364
|
+
* reuses the cached list on every later page. When two chunks emit
|
|
365
|
+
* byte-identical CSS, which Rollup writes as one asset (a kit whose React and
|
|
366
|
+
* Vue builds share their stylesheets), and the host page imports both through
|
|
367
|
+
* the kit's views, the second chunk's list is cached empty on the host, and
|
|
368
|
+
* a framework page importing only that chunk gets no link. This plugin adds
|
|
369
|
+
* each missing link after Vite's own, before `</head>`; a page Vite linked
|
|
370
|
+
* fully is unchanged. On a page Vite linked only in part, an added link
|
|
371
|
+
* cascades after the ones Vite wrote rather than in import order, which
|
|
372
|
+
* matters only when the two stylesheets set the same property at the same
|
|
373
|
+
* specificity.
|
|
374
|
+
*
|
|
375
|
+
* @returns The plugin.
|
|
376
|
+
*/
|
|
377
|
+
export function entryStylesheetsPlugin(): Plugin {
|
|
378
|
+
let root = applicationRoot;
|
|
379
|
+
let base = './';
|
|
380
|
+
return {
|
|
381
|
+
name: 'preview-entry-stylesheets',
|
|
382
|
+
apply: 'build',
|
|
383
|
+
enforce: 'post',
|
|
384
|
+
configResolved(configuration) {
|
|
385
|
+
root = configuration.root;
|
|
386
|
+
base = configuration.base;
|
|
387
|
+
},
|
|
388
|
+
generateBundle: {
|
|
389
|
+
order: 'post',
|
|
390
|
+
handler(_options, bundle) {
|
|
391
|
+
// The preview builds with a relative base (`./`, buildViteConfiguration's `base`), so
|
|
392
|
+
// a page links an asset by its path from the page; under an absolute
|
|
393
|
+
// base it links the base followed by the asset's file name.
|
|
394
|
+
const relativeBase = base === './' || base === '';
|
|
395
|
+
const entries = Object.values(bundle).filter(
|
|
396
|
+
(output): output is Rollup.OutputChunk =>
|
|
397
|
+
output.type === 'chunk' &&
|
|
398
|
+
output.isEntry &&
|
|
399
|
+
output.facadeModuleId !== null &&
|
|
400
|
+
output.facadeModuleId.endsWith('.html')
|
|
401
|
+
);
|
|
402
|
+
for (const entry of entries) {
|
|
403
|
+
const page = relative(root, entry.facadeModuleId!)
|
|
404
|
+
.split('\\')
|
|
405
|
+
.join('/');
|
|
406
|
+
const asset = bundle[page];
|
|
407
|
+
if (asset?.type !== 'asset' || typeof asset.source !== 'string')
|
|
408
|
+
continue;
|
|
409
|
+
const html = asset.source;
|
|
410
|
+
const directory = posix.dirname(page);
|
|
411
|
+
// What the page links already, as file names in the output.
|
|
412
|
+
const linked = new Set(
|
|
413
|
+
[...html.matchAll(/href="([^"]+)"/g)].map(([, href]) =>
|
|
414
|
+
relativeBase
|
|
415
|
+
? posix.join(directory, href)
|
|
416
|
+
: href.startsWith(base)
|
|
417
|
+
? href.slice(base.length)
|
|
418
|
+
: href
|
|
419
|
+
)
|
|
420
|
+
);
|
|
421
|
+
const missing = entryStylesheets(entry, bundle)
|
|
422
|
+
.filter((stylesheet) => !linked.has(stylesheet))
|
|
423
|
+
.map((stylesheet) => {
|
|
424
|
+
if (!relativeBase) return `${base}${stylesheet}`;
|
|
425
|
+
const href = posix.relative(directory, stylesheet);
|
|
426
|
+
return href.startsWith('../') ? href : `./${href}`;
|
|
427
|
+
});
|
|
428
|
+
if (missing.length === 0) continue;
|
|
429
|
+
asset.source = html.replace(
|
|
430
|
+
'</head>',
|
|
431
|
+
missing
|
|
432
|
+
.map(
|
|
433
|
+
(href) =>
|
|
434
|
+
` <link rel="stylesheet" crossorigin href="${href}">\n`
|
|
435
|
+
)
|
|
436
|
+
.join('') + ' </head>'
|
|
437
|
+
);
|
|
438
|
+
}
|
|
439
|
+
},
|
|
440
|
+
},
|
|
441
|
+
};
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
/**
|
|
445
|
+
* The html source endpoint: the host POSTs a story (its root component, the
|
|
446
|
+
* props it shows and its slot content) and gets back the markup the story
|
|
447
|
+
* renders to, `{ markup }`, or what it holds that has none, `{ missing }`.
|
|
448
|
+
* The kit's components load as generation loads them, so a saved template
|
|
449
|
+
* prints the next time it is asked.
|
|
450
|
+
*
|
|
451
|
+
* @param context - The kit's preview context.
|
|
452
|
+
* @returns The plugin.
|
|
453
|
+
*/
|
|
454
|
+
export function htmlSourcePlugin(context: PreviewContext): Plugin {
|
|
455
|
+
return {
|
|
456
|
+
name: 'preview-html-source',
|
|
457
|
+
configureServer(server) {
|
|
458
|
+
server.middlewares.use(HTML_SOURCE_ENDPOINT, (request, response) => {
|
|
459
|
+
if (request.method !== 'POST') {
|
|
460
|
+
response.statusCode = 405;
|
|
461
|
+
return response.end('POST only');
|
|
462
|
+
}
|
|
463
|
+
let body = '';
|
|
464
|
+
request.on('data', (chunk) => (body += chunk));
|
|
465
|
+
request.on('end', async () => {
|
|
466
|
+
try {
|
|
467
|
+
const story = JSON.parse(body) as HtmlSourceRequest;
|
|
468
|
+
const { components } = await loadKit(context);
|
|
469
|
+
const enumerated = components.map((entry) => entry.component);
|
|
470
|
+
const component = enumerated.find(
|
|
471
|
+
(candidate) => candidate.name === story.rootComponent
|
|
472
|
+
);
|
|
473
|
+
if (!component) {
|
|
474
|
+
response.statusCode = 404;
|
|
475
|
+
return response.end(
|
|
476
|
+
`The kit has no component named ${story.rootComponent}.`
|
|
477
|
+
);
|
|
478
|
+
}
|
|
479
|
+
const result = await printHtmlSource(context, enumerated, {
|
|
480
|
+
component,
|
|
481
|
+
props: story.props ?? {},
|
|
482
|
+
children: story.slots?.default,
|
|
483
|
+
named: story.slots?.named ?? {},
|
|
484
|
+
...(story.around ? { around: story.around } : {}),
|
|
485
|
+
});
|
|
486
|
+
response.statusCode = 200;
|
|
487
|
+
response.setHeader('Content-Type', 'application/json');
|
|
488
|
+
response.end(
|
|
489
|
+
JSON.stringify(htmlSourceResponse(context, enumerated, result))
|
|
490
|
+
);
|
|
491
|
+
} catch (error) {
|
|
492
|
+
const message =
|
|
493
|
+
error instanceof Error ? error.message : String(error);
|
|
494
|
+
const detail =
|
|
495
|
+
error instanceof Error ? (error.stack ?? error.message) : message;
|
|
496
|
+
server.config.logger.error(`[html-source] ${detail}`);
|
|
497
|
+
response.statusCode = 500;
|
|
498
|
+
response.end(message);
|
|
499
|
+
}
|
|
500
|
+
});
|
|
501
|
+
});
|
|
502
|
+
},
|
|
503
|
+
};
|
|
504
|
+
}
|
|
505
|
+
|
|
506
|
+
/** An empty custom-view registry, aliased in when the kit registers none. */
|
|
507
|
+
const noViewsModule = resolve(applicationRoot, 'lib/no-views.ts');
|
|
508
|
+
const noCodeBlockModule = resolve(applicationRoot, 'lib/no-code-block.ts');
|
|
509
|
+
/** An empty setup module, aliased per target when the kit registers none. */
|
|
510
|
+
const noSetupModule = resolve(applicationRoot, 'lib/no-setup.ts');
|
|
511
|
+
|
|
512
|
+
/** What the `dev` command's options set over the kit's configuration. */
|
|
513
|
+
export interface DevelopmentServerOverrides {
|
|
514
|
+
/** The port, over the kit's `port`. */
|
|
515
|
+
port?: number;
|
|
516
|
+
/** The addresses to listen on, over the kit's `host`: an address, or
|
|
517
|
+
* `true` for every address. */
|
|
518
|
+
host?: string | boolean;
|
|
519
|
+
}
|
|
520
|
+
|
|
521
|
+
/**
|
|
522
|
+
* The Vite configuration for one kit's preview.
|
|
523
|
+
*
|
|
524
|
+
* @param context - The kit's preview context.
|
|
525
|
+
* @param overrides - The development server's port and host, over the
|
|
526
|
+
* kit's configured ones.
|
|
527
|
+
* @returns The configuration, for Vite's `createServer` or `build`.
|
|
528
|
+
*/
|
|
529
|
+
export function buildViteConfiguration(
|
|
530
|
+
context: PreviewContext,
|
|
531
|
+
overrides: DevelopmentServerOverrides = {}
|
|
532
|
+
): InlineConfig {
|
|
533
|
+
const { kitRoot, generatedRoot, configuration } = context;
|
|
534
|
+
// A kit built into one package per target: its other packages, imported
|
|
535
|
+
// by name as a consumer imports them.
|
|
536
|
+
const kitPackages = context.kitPackages ?? [];
|
|
537
|
+
// A shell package the kit has not installed fails here, by name, rather
|
|
538
|
+
// than as an import the bundler cannot resolve from inside the shell.
|
|
539
|
+
const shellProblem = missingShellPeersProblem(missingShellPeers(context));
|
|
540
|
+
if (shellProblem !== undefined) throw new Error(`[preview] ${shellProblem}`);
|
|
541
|
+
const setupAlias = (target: 'react' | 'vue' | 'svelte'): string => {
|
|
542
|
+
const configured = configuration.setupModules?.[target];
|
|
543
|
+
return configured ? resolve(kitRoot, configured) : noSetupModule;
|
|
544
|
+
};
|
|
545
|
+
const kitAliases = Object.fromEntries(
|
|
546
|
+
Object.entries(configuration.aliases ?? {}).map(([from, to]) => [
|
|
547
|
+
from,
|
|
548
|
+
resolve(kitRoot, to),
|
|
549
|
+
])
|
|
550
|
+
);
|
|
551
|
+
return {
|
|
552
|
+
configFile: false,
|
|
553
|
+
root: applicationRoot,
|
|
554
|
+
// Relative: the static build's pages load their scripts and styles by
|
|
555
|
+
// paths relative to themselves, so it works from any directory a file
|
|
556
|
+
// server serves it under. The development server serves from `/`.
|
|
557
|
+
base: './',
|
|
558
|
+
// Vite's dependency cache sits with the kit's generated tree, not inside the
|
|
559
|
+
// installed package: it is the kit's, and a stale one is cleared with it.
|
|
560
|
+
cacheDir: resolve(generatedRoot, '.vite'),
|
|
561
|
+
// The generator copies theme stylesheets (+ fonts) here; served at
|
|
562
|
+
// themes/<id>/theme.css in dev and copied verbatim into the static build.
|
|
563
|
+
publicDir: resolve(generatedRoot, 'public'),
|
|
564
|
+
plugins: [
|
|
565
|
+
react(),
|
|
566
|
+
vue(),
|
|
567
|
+
svelte(),
|
|
568
|
+
configurationModulePlugin(context),
|
|
569
|
+
scratchRegenerationPlugin(generatedRoot),
|
|
570
|
+
htmlSourcePlugin(context),
|
|
571
|
+
htmlStylesheetsPlugin(context),
|
|
572
|
+
hostPagePlugin(context),
|
|
573
|
+
entryStylesheetsPlugin(),
|
|
574
|
+
chunkSizePlugin(context),
|
|
575
|
+
],
|
|
576
|
+
resolve: {
|
|
577
|
+
alias: [
|
|
578
|
+
...Object.entries({
|
|
579
|
+
'@preview-generated': generatedRoot,
|
|
580
|
+
'@preview-views': context.viewsModuleAbsolute ?? noViewsModule,
|
|
581
|
+
'@preview-code-block':
|
|
582
|
+
context.codeBlockModuleAbsolute ?? noCodeBlockModule,
|
|
583
|
+
'@preview-shell': context.shellModuleAbsolute,
|
|
584
|
+
'@preview-setup/react': setupAlias('react'),
|
|
585
|
+
'@preview-setup/vue': setupAlias('vue'),
|
|
586
|
+
'@preview-setup/svelte': setupAlias('svelte'),
|
|
587
|
+
...kitAliases,
|
|
588
|
+
// Runtime template compilation (the Vue registry mounts string templates).
|
|
589
|
+
vue: 'vue/dist/vue.esm-bundler.js',
|
|
590
|
+
}).map(([find, replacement]) => ({ find, replacement })),
|
|
591
|
+
// The packages the kit names, each loaded from the kit's own copy.
|
|
592
|
+
...kitDedupeAliases(configuration.dedupe ?? [], kitRoot),
|
|
593
|
+
],
|
|
594
|
+
// One instance of each framework runtime across the boundary: the
|
|
595
|
+
// bootstrap lives in this package, the shell may live in the kit, and
|
|
596
|
+
// the kit's components resolve their own deps - without dedupe
|
|
597
|
+
// React/Vue/Svelte would each load twice (hook/context breakage).
|
|
598
|
+
dedupe: FRAMEWORK_RUNTIMES,
|
|
599
|
+
},
|
|
600
|
+
define: {
|
|
601
|
+
__VUE_OPTIONS_API__: 'true',
|
|
602
|
+
__VUE_PROD_DEVTOOLS__: 'false',
|
|
603
|
+
__VUE_PROD_HYDRATION_MISMATCH_DETAILS__: 'false',
|
|
604
|
+
},
|
|
605
|
+
css: {
|
|
606
|
+
preprocessorOptions: {
|
|
607
|
+
scss: {
|
|
608
|
+
loadPaths: (configuration.scssLoadPaths ?? []).map((loadPath) =>
|
|
609
|
+
resolve(kitRoot, loadPath)
|
|
610
|
+
),
|
|
611
|
+
// The kit's own `pkg:` URLs resolve through its package.json
|
|
612
|
+
// exports, as its build resolves them.
|
|
613
|
+
importers: kitImporters(kitRoot, kitPackageDirectories(context)),
|
|
614
|
+
},
|
|
615
|
+
},
|
|
616
|
+
},
|
|
617
|
+
optimizeDeps: {
|
|
618
|
+
// This package's subpaths stay out of the pre-bundle: a shell installed
|
|
619
|
+
// from npm imports the SDK by package name, and pre-bundling it would
|
|
620
|
+
// give the shell a second copy beside the bootstrap's.
|
|
621
|
+
// The kit's own packages are source the preview watches, as the kit
|
|
622
|
+
// root is, never a dependency to pre-bundle.
|
|
623
|
+
exclude: [
|
|
624
|
+
PACKAGE_NAME,
|
|
625
|
+
...kitPackages.map(({ name }) => name),
|
|
626
|
+
...(configuration.optimizeDepsExclude ?? []),
|
|
627
|
+
],
|
|
628
|
+
},
|
|
629
|
+
server: {
|
|
630
|
+
port: overrides.port ?? configuration.port ?? DEFAULT_PORT,
|
|
631
|
+
// Vite's own default, the local machine only, unless asked.
|
|
632
|
+
host: overrides.host ?? configuration.host,
|
|
633
|
+
fs: {
|
|
634
|
+
// The bootstrap imports this package's dependencies and the kit's
|
|
635
|
+
// components, so both workspaces are served, along with the shell's
|
|
636
|
+
// directory and, when the shell draws with charcell, charcell
|
|
637
|
+
// wherever it resolves from the shell (a link: checkout lives
|
|
638
|
+
// outside both workspaces).
|
|
639
|
+
allow: [
|
|
640
|
+
searchForWorkspaceRoot(packageRoot),
|
|
641
|
+
searchForWorkspaceRoot(kitRoot),
|
|
642
|
+
...kitPackages.map(({ directoryAbsolute }) => directoryAbsolute),
|
|
643
|
+
dirname(context.shellModuleAbsolute),
|
|
644
|
+
...[
|
|
645
|
+
packageDirectory(
|
|
646
|
+
'charcell/react/unlinked',
|
|
647
|
+
context.shellModuleAbsolute
|
|
648
|
+
),
|
|
649
|
+
].filter((directory) => directory !== undefined),
|
|
650
|
+
],
|
|
651
|
+
},
|
|
652
|
+
},
|
|
653
|
+
build: {
|
|
654
|
+
outDir: context.staticRoot,
|
|
655
|
+
emptyOutDir: true,
|
|
656
|
+
// Every script lands one directory below the output root, which is how
|
|
657
|
+
// the application finds the URL it is served under (lib/base-url.ts).
|
|
658
|
+
assetsDir: 'assets',
|
|
659
|
+
// The preview warns of a large chunk itself, leaving out the host page
|
|
660
|
+
// the kit cannot change (chunkSizePlugin).
|
|
661
|
+
chunkSizeWarningLimit: Number.POSITIVE_INFINITY,
|
|
662
|
+
rollupOptions: {
|
|
663
|
+
input: {
|
|
664
|
+
host: resolve(applicationRoot, 'index.html'),
|
|
665
|
+
react: resolve(applicationRoot, 'preview/react/preview.html'),
|
|
666
|
+
vue: resolve(applicationRoot, 'preview/vue/preview.html'),
|
|
667
|
+
svelte: resolve(applicationRoot, 'preview/svelte/preview.html'),
|
|
668
|
+
html: resolve(applicationRoot, 'preview/html/preview.html'),
|
|
669
|
+
view: resolve(applicationRoot, 'preview/view/view.html'),
|
|
670
|
+
code: resolve(applicationRoot, 'preview/code/code.html'),
|
|
671
|
+
},
|
|
672
|
+
},
|
|
673
|
+
},
|
|
674
|
+
};
|
|
675
|
+
}
|