vite-plugin-zephyr 1.4.2 → 1.5.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.
@@ -0,0 +1,98 @@
1
+ # Remote Resolution
2
+
3
+ Use this file when the user asks how Zephyr resolves remotes, how `workspace:*` works, or which selector format to use.
4
+
5
+ ## `zephyr:dependencies`
6
+
7
+ Zephyr uses the `zephyr:dependencies` field in `package.json` to map local remote names to application identifiers and resolution selectors.
8
+
9
+ Valid shapes:
10
+
11
+ ```json
12
+ {
13
+ "zephyr:dependencies": {
14
+ "local-name": "workspace:*"
15
+ }
16
+ }
17
+ ```
18
+
19
+ ```json
20
+ {
21
+ "zephyr:dependencies": {
22
+ "local-name": "application-uid-or-name@selector"
23
+ }
24
+ }
25
+ ```
26
+
27
+ ```json
28
+ {
29
+ "zephyr:dependencies": {
30
+ "local-name": "zephyr:application-uid-or-name@selector"
31
+ }
32
+ }
33
+ ```
34
+
35
+ The `zephyr:` registry prefix is optional in current docs.
36
+
37
+ ## Selectors to explain
38
+
39
+ - Label/tag/environment style: `@latest`, `@stable`, `@production`, `@staging`
40
+ - Semver: `@^1.2.3`, `@~2.0.0`, `@1.5.0`
41
+ - Wildcard latest: `*`
42
+ - Workspace matching: `workspace:*`
43
+
44
+ ## `workspace:*`
45
+
46
+ This is the most important Zephyr-specific selector for local dev and coordinated CI.
47
+
48
+ It resolves the most recent version matching build context, including:
49
+
50
+ - git branch
51
+ - target platform
52
+ - CI vs local
53
+ - username / build identity
54
+
55
+ Why it matters:
56
+
57
+ - feature branches consume matching remotes automatically
58
+ - local dev stays isolated from CI builds
59
+ - teams do not need to hand-edit remote URLs for normal branch work
60
+
61
+ Concrete example:
62
+
63
+ - Host on branch `feature/cart`, user `alice`, local build, platform `web`
64
+ - Remote selector is `workspace:*`
65
+ - Zephyr prefers the most recent remote build that also matches `feature/cart`, `alice`, local context, and `web`
66
+ - If none exists, the SDK retries the same remote with version `*` and uses the latest published version
67
+
68
+ What to expect if no exact match exists:
69
+
70
+ - The SDK resolves version `*` silently; with `DEBUG=zephyr:remotes` it logs `No workspace build found for <remote>@workspace:*; falling back to the latest published version`.
71
+ - Some public docs describe this as a default-environment fallback; the current SDK uses the latest published version instead.
72
+ - That means the remote needs at least one published build to resolve cleanly; an exact workspace match always wins when it exists.
73
+ - If the user sees unresolved remotes, check whether the remote app has actually been built and exposed through an environment.
74
+
75
+ ## Selector guidance by scenario
76
+
77
+ | Scenario | Good default |
78
+ | ------------------------------ | --------------------------------------------------------- |
79
+ | Branch-based local dev | `workspace:*` |
80
+ | Moving preview/staging channel | environment/tag-style selector like `@staging` or `@beta` |
81
+ | Stable production pin | exact version like `@1.2.3` |
82
+ | Latest acceptable version | `*` or an explicit moving selector, depending on policy |
83
+
84
+ ## Resolution priority note
85
+
86
+ For label-like selectors, the public docs say Zephyr resolves by looking for:
87
+
88
+ 1. environment name
89
+ 2. tag name
90
+ 3. version name
91
+
92
+ If a user is confused by `production` or `staging`, explain that those names may resolve to an environment before they resolve to a tag.
93
+
94
+ ## Best docs to link
95
+
96
+ - Remote dependencies: `https://docs.zephyr-cloud.io/features/remote-dependencies.md`
97
+ - Environment overrides: `https://docs.zephyr-cloud.io/features/environment-overrides.md`
98
+ - MF guide: `https://docs.zephyr-cloud.io/tutorials/mf-guide.md`
@@ -0,0 +1,128 @@
1
+ # Setup Patterns
2
+
3
+ Use this file when the user asks how to configure a host or remote with Zephyr and Module Federation.
4
+
5
+ ## Two layers to explain
6
+
7
+ 1. Bundler/module federation config
8
+ 2. `zephyr:dependencies` mapping in `package.json`
9
+
10
+ Both are needed for a smooth Zephyr MF workflow.
11
+
12
+ ## Smallest end-to-end path
13
+
14
+ 1. Configure the remote with valid MF `name`, `filename`, and `exposes`.
15
+ 2. Configure the host with matching remote keys/names.
16
+ 3. Add `zephyr:dependencies` in the host `package.json`.
17
+ 4. Build the remote first so Zephyr can resolve it.
18
+ 5. Build the host and verify the host can load/import the remote.
19
+
20
+ ## Lifecycle map
21
+
22
+ - Build time: bundler MF config is compiled and Zephyr captures dependency declarations.
23
+ - Deploy time: Zephyr resolves remote selectors to concrete deploy targets.
24
+ - Runtime: the host loads the resolved remote entry and executes the remote code.
25
+
26
+ ## Naming map
27
+
28
+ Keep these aligned:
29
+
30
+ - remote package `name`
31
+ - remote MF config `name`
32
+ - host remote key / import name
33
+ - `zephyr:dependencies` local key
34
+ - `zephyr:dependencies` target app identifier when not using `workspace:*`
35
+
36
+ If names drift, users often get confusing resolution or runtime-load failures.
37
+
38
+ ## Vite host example
39
+
40
+ File: `https://github.com/ZephyrCloudIO/zephyr-examples/blob/main/module-federation/react-vite-rspack-webpack/host/vite.config.ts`
41
+
42
+ ```ts
43
+ import { defineConfig } from 'vite';
44
+ import react from '@vitejs/plugin-react';
45
+ import { withZephyr, type ModuleFederationOptions } from 'vite-plugin-zephyr';
46
+
47
+ const mfConfig: ModuleFederationOptions = {
48
+ name: 'vite-host',
49
+ filename: 'remoteEntry.js',
50
+ remotes: {
51
+ vite_remote: {
52
+ name: 'vite_remote',
53
+ entry: 'http://localhost:5174/remoteEntry.js',
54
+ type: 'module',
55
+ },
56
+ vite_webpack: {
57
+ name: 'vite_webpack',
58
+ entry: 'http://localhost:8080/remoteEntry.js',
59
+ type: 'var',
60
+ },
61
+ vite_rspack: {
62
+ name: 'vite_rspack',
63
+ entry: 'http://localhost:8081/remoteEntry.js',
64
+ type: 'var',
65
+ },
66
+ },
67
+ shared: {
68
+ react: { singleton: true },
69
+ 'react-dom': { singleton: true },
70
+ },
71
+ };
72
+
73
+ export default defineConfig({
74
+ plugins: [react(), withZephyr({ mfConfig })],
75
+ });
76
+ ```
77
+
78
+ ## Minimal remote example
79
+
80
+ File: `https://docs.zephyr-cloud.io/bundlers/vite.md`
81
+
82
+ ```ts
83
+ import { defineConfig } from 'vite';
84
+ import react from '@vitejs/plugin-react';
85
+ import { withZephyr, type ModuleFederationOptions } from 'vite-plugin-zephyr';
86
+
87
+ const mfConfig: ModuleFederationOptions = {
88
+ name: 'remote-app',
89
+ filename: 'remoteEntry.js',
90
+ exposes: {
91
+ './Button': './src/components/Button',
92
+ },
93
+ shared: {
94
+ react: { singleton: true },
95
+ 'react-dom': { singleton: true },
96
+ },
97
+ };
98
+
99
+ export default defineConfig({
100
+ plugins: [react(), withZephyr({ mfConfig })],
101
+ });
102
+ ```
103
+
104
+ ## Host dependency mapping
105
+
106
+ File: `https://github.com/ZephyrCloudIO/zephyr-examples/blob/main/module-federation/react-vite-rspack-webpack/host/package.json`
107
+
108
+ ```json
109
+ "zephyr:dependencies": {
110
+ "vite_remote": "workspace:*",
111
+ "vite_rspack": "workspace:*",
112
+ "vite_webpack": "workspace:*"
113
+ }
114
+ ```
115
+
116
+ ## What to explain
117
+
118
+ - Local import names must line up with the names the host uses.
119
+ - `zephyr:dependencies` tells Zephyr how to resolve those remotes at build/runtime.
120
+ - Shared React deps are usually singleton.
121
+ - In mixed-bundler Vite hosts, remote `type` matters.
122
+ - `type: 'module'` usually matches module-style Vite remotes; `type: 'var'` usually matches Webpack/Rspack-style remotes.
123
+ - Host and remote still need valid MF config even when Zephyr handles deploy-time resolution.
124
+
125
+ ## Minimal code mental model
126
+
127
+ - Host code imports/loads the remote by the host's configured remote key.
128
+ - Zephyr helps resolve where that remote should come from in deployed environments.
@@ -0,0 +1,110 @@
1
+ ---
2
+ name: zephyr-vite
3
+ description: Configure and deploy Vite applications with vite-plugin-zephyr; use
4
+ when adding withZephyr, configuring its Module Federation integration, or
5
+ diagnosing Vite build publication and plugin ordering. Use the dedicated
6
+ integrations for TanStack Start and Vinext.
7
+ metadata:
8
+ library: vite-plugin-zephyr
9
+ library_version: '1.5.0' # x-release-please-version
10
+ purpose: Configure an existing Vite application for Zephyr publication while preserving its framework plugins and selecting the correct build lifecycle.
11
+ domain: vite
12
+ type: core
13
+ sources:
14
+ - ZephyrCloudIO/zephyr-packages:**/libs/vite-plugin-zephyr/src/index.ts
15
+ - ZephyrCloudIO/zephyr-packages:**/libs/vite-plugin-zephyr/src/lib/vite-plugin-zephyr.ts
16
+ - ZephyrCloudIO/zephyr-packages:**/libs/vite-plugin-zephyr/src/lib/vite-api.integration.spec.ts
17
+ - ZephyrCloudIO/zephyr-packages:**/libs/vite-plugin-zephyr/src/package-output.spec.ts
18
+ - ZephyrCloudIO/zephyr-packages:**/libs/vite-plugin-zephyr/src/lib/__fixtures__/vite-api/skill-task.md
19
+ - ZephyrCloudIO/zephyr-packages:**/libs/vite-plugin-zephyr/README.md
20
+ ---
21
+
22
+ # Configure Vite for Zephyr
23
+
24
+ ## Setup
25
+
26
+ Read the application's existing Vite config and installed package versions before editing.
27
+ Keep its framework plugins and build options. If `vite-plugin-zephyr` is missing,
28
+ install it as a development dependency only when dependency changes are authorized.
29
+
30
+ Add `withZephyr()` to the existing plugin list. It returns a plugin array, so both
31
+ spreading it and nesting it in Vite's plugin list work:
32
+
33
+ ```typescript
34
+ import { defineConfig } from 'vite';
35
+ import { withZephyr } from 'vite-plugin-zephyr';
36
+
37
+ export default defineConfig({
38
+ plugins: [...withZephyr()],
39
+ });
40
+ ```
41
+
42
+ The installed package supports Vite 5 through 8. Multi-environment application
43
+ publication requires Vite 7 or newer. Use `vite-plugin-tanstack-start-zephyr` or
44
+ `vite-plugin-vinext-zephyr` for those frameworks rather than replacing their
45
+ specialized integration with this generic plugin.
46
+
47
+ ## Configure Module Federation
48
+
49
+ For a new federation setup, install a compatible `@module-federation/vite` peer
50
+ when authorized and pass the container config through `mfConfig`:
51
+
52
+ ```typescript
53
+ import { defineConfig } from 'vite';
54
+ import { withZephyr } from 'vite-plugin-zephyr';
55
+
56
+ export default defineConfig({
57
+ plugins: [
58
+ ...withZephyr({
59
+ mfConfig: {
60
+ name: 'catalog',
61
+ exposes: { './Product': './src/Product.tsx' },
62
+ },
63
+ }),
64
+ ],
65
+ });
66
+ ```
67
+
68
+ `withZephyr({ mfConfig })` installs the federation plugins itself. Do not also
69
+ add `federation(mfConfig)` for the same container. Existing configs that already
70
+ install `federation(...)` can keep that plugin and add plain `withZephyr()`;
71
+ Zephyr detects the existing federation config. The optional peer is unnecessary
72
+ for an ordinary Vite app and is required when `mfConfig` is supplied.
73
+
74
+ For hosts, keep normal federation wiring and Zephyr's `zephyr:dependencies`
75
+ mapping distinct. The `zephyr-module-federation` skill shipped in this package
76
+ covers `zephyr:dependencies`, remote resolution, and build order.
77
+
78
+ ## Choose the publication lifecycle
79
+
80
+ Use the application's existing Vite build command for an ordinary client app.
81
+ When an application uses `createBuilder()` with multiple environments, publish
82
+ through `builder.buildApp()` rather than building each environment separately.
83
+
84
+ When working on SSR, multi-environment builds, explicit plugin ordering, or
85
+ separate producer builds, read [build lifecycle](references/build-lifecycle.md)
86
+ before choosing options or changing hooks.
87
+
88
+ ## Avoid misleading fixes
89
+
90
+ - Do not move Zephyr universally to the end of the plugin list. It must precede
91
+ another `enforce: 'pre'` plugin with a pre-ordered `buildApp` hook. Read the
92
+ [build lifecycle](references/build-lifecycle.md) when resolving ordering conflicts.
93
+ - Do not use an arbitrary source filename as an SSR `entrypoint`. It must name
94
+ an emitted server chunk relative to the snapshot root. Read the SSR entrypoint
95
+ rules in [build lifecycle](references/build-lifecycle.md) when choosing that path.
96
+ - Do not treat a successful local asset build as proof of deployment. Check
97
+ Zephyr publication separately, especially when errors are configured to log
98
+ rather than fail the build.
99
+ - Do not put credentials in `ZE_PUBLIC_*`; those values are client-visible.
100
+
101
+ ## Verify completion
102
+
103
+ Run the authorized build with the application's existing package runner.
104
+ Confirm its expected assets are emitted and Zephyr reports a successful
105
+ publication with a version URL. A build without credentials can establish local
106
+ asset correctness, but not live deployment success. Report that distinction.
107
+
108
+ On failure, retain the actionable error and fix the matching configuration or
109
+ publication issue. Do not silently change the framework integration, suppress
110
+ errors, or claim that a partial build was deployed.
@@ -0,0 +1,70 @@
1
+ # Build lifecycle
2
+
3
+ Use this reference for SSR, multiple Vite environments, ordering conflicts, or
4
+ intentionally separate producer builds. This reference describes publication
5
+ behavior of the installed `vite-plugin-zephyr` release.
6
+
7
+ ## Direct builds and coordinated application builds
8
+
9
+ Ordinary `vite.build()` calls publish the direct build's output. For a
10
+ multi-environment Vite 7 or 8 builder, use `builder.buildApp()` so all current
11
+ environments contribute to one snapshot. Building the environments separately
12
+ is rejected instead of publishing incomplete snapshots.
13
+
14
+ Vite 6 does not dispatch plugin `buildApp` hooks. Its non-watch publication
15
+ supports one environment without an explicit builder configuration. Upgrade
16
+ Vite only when authorized; do not work around this limitation by silently
17
+ publishing only the client environment.
18
+
19
+ Put `withZephyr()` before plugins that combine `enforce: 'pre'` with a
20
+ pre-ordered `buildApp` hook. Direct non-watch builds also require Zephyr to observe
21
+ the final `outputOptions`, `writeBundle`, and `closeBundle` hooks. A later
22
+ post-ordered hook or unresolved asynchronous output plugin is rejected because
23
+ it could change output or fail after publication.
24
+
25
+ ## SSR entrypoints
26
+
27
+ Direct SSR builds infer their emitted server entry. Set `snapshotType: 'ssr'`
28
+ and `entrypoint` only when the default inference does not express the intended
29
+ snapshot. The entrypoint is an emitted path inside the snapshot, not a source
30
+ path or an absolute filesystem path. Multiple emitted server entries require
31
+ an explicit choice.
32
+
33
+ With an emitted `server/index.mjs`, the relevant options are:
34
+
35
+ ```typescript
36
+ import { withZephyr } from 'vite-plugin-zephyr';
37
+
38
+ withZephyr({
39
+ snapshotType: 'ssr',
40
+ entrypoint: 'server/index.mjs',
41
+ });
42
+ ```
43
+
44
+ Explicit options take precedence over inference. Framework files created after
45
+ Vite returns are outside this upload lifecycle. If those files must be deployed,
46
+ the framework needs a supported post-build publication step.
47
+
48
+ ## Separate producer builds
49
+
50
+ Use `withZephyrPartial()` only for intentionally separate producer invocations.
51
+ Give every producer and the finalizer the same nonempty `invocationId`, or use
52
+ the documented `ZE_BUILD_INVOCATION_ID` contract. The finalizer passes that
53
+ identity through `withZephyr({ partialBuild: { invocationId } })`.
54
+
55
+ Ambient CI metadata alone does not opt an ordinary build into partial output.
56
+ Do not invent a shared identity or reuse one across unrelated builds. A missing
57
+ identity or unavailable producer output is a failure to investigate, not a
58
+ reason to publish a reduced snapshot.
59
+
60
+ ## Base paths and public configuration
61
+
62
+ Without an explicit base, the plugin defaults build assets to `./`. Existing
63
+ bases are preserved. An origin-absolute base such as `/docs/` cannot be relocated
64
+ under another deployment prefix and can produce a warning for path addressing.
65
+
66
+ This default does not make SSR HTML generation prefix-aware. Keep the dedicated
67
+ TanStack Start and Vinext integrations for their runtime HTML behavior.
68
+
69
+ `ZE_PUBLIC_*` rewrites support public runtime configuration. Never use this
70
+ mechanism to carry authentication tokens or other secrets.