@moostjs/vite 0.6.14 → 0.6.15

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/README.md CHANGED
@@ -149,6 +149,46 @@ await app.listen()
149
149
 
150
150
  `createSSRServer` handles dev/prod branching — in dev it creates a Vite dev server, in prod it serves built assets with `sirv`.
151
151
 
152
+ ### SSR Bundle Size
153
+
154
+ By default, `vite build` in middleware mode sets `ssr.noExternal: true` — every dependency is bundled into the SSR output. This is the safe default for two reasons:
155
+
156
+ - **Symbol-identity slot keys** — packages like `@wooksjs/event-http` use `Symbol()` for internal slot keys. If the same package is reachable via both an externalized path (Node ESM at runtime) and a bundled path (rolldown inlines it transitively), each module instance creates fresh Symbols and slot lookups miss. Bundling everything yields a single instance per package.
157
+ - **pnpm strict resolution** — externalized transitive deps may not be hoist-accessible from the consumer's top-level `node_modules`.
158
+
159
+ For a real frontend with Vue/Vue Router/etc., the resulting `dist/server/` can exceed a megabyte. To externalize stable upstream libraries and shrink the bundle, set `ssr.external` (or the equivalent `ssrExternal` plugin option):
160
+
161
+ ```ts
162
+ // vite.config.ts
163
+ export default defineConfig({
164
+ ssr: {
165
+ external: ['vue', 'vue-router', '@vue/server-renderer'],
166
+ },
167
+ plugins: [
168
+ vue(),
169
+ moostVite({
170
+ entry: '/src/main.ts',
171
+ middleware: true,
172
+ prefix: '/api',
173
+ ssrEntry: '/src/entry-server.ts',
174
+ }),
175
+ ],
176
+ })
177
+ ```
178
+
179
+ **Safe to externalize:** publicly-published, semver-stable libraries that ship a single canonical build (Vue, Vue Router, `@vue/server-renderer`, VueUse, etc.). Node's ESM resolver loads them once and identity is shared between `server.js` and the SSR entry.
180
+
181
+ **Don't externalize:** workspace packages (`workspace:*`), anything that uses `Symbol()` as a public slot key (Moost, wooks, atscript), anything not reliably hoisted by pnpm.
182
+
183
+ You can also opt out of bundle-everything by setting `ssr.noExternal` to an explicit list — the plugin honors it literally (appending only `/^@moostjs\/vite($|\/)/` so its own `define:` substitutions still land):
184
+
185
+ ```ts
186
+ ssr: {
187
+ noExternal: ['@moostjs/vite', /^@aooth\//, /^@atscript\//],
188
+ external: ['vue', 'vue-router'],
189
+ }
190
+ ```
191
+
152
192
  ## SSR Local Fetch
153
193
 
154
194
  When `ssrFetch` is enabled (default: `true`), the plugin patches `globalThis.fetch` so that local paths are routed in-process through Moost instead of making a real HTTP request. This is useful for SSR where server-side code fetches from its own API:
@@ -193,6 +233,7 @@ The plugin injects a `__VITE_ID` decorator on `@Injectable` and `@Controller` cl
193
233
  | `ssrOutlet` | `string` | `'<!--ssr-outlet-->'` | HTML placeholder for SSR-rendered content |
194
234
  | `ssrState` | `string` | `'<!--ssr-state-->'` | HTML placeholder for SSR state transfer script |
195
235
  | `serverEntry` | `string` | — | Custom production server entry file (e.g. `'./server.ts'`) |
236
+ | `ssrExternal` | `string[]` | — | Packages to keep external in the SSR build (middleware mode, `vite build` only). Concatenated with `cfg.ssr.external`. See [SSR Bundle Size](#ssr-bundle-size). |
196
237
 
197
238
  Options marked "backend mode only" are ignored when `middleware: true` — the user's `vite.config.ts` controls build/server configuration in middleware mode.
198
239
 
package/dist/index.cjs CHANGED
@@ -395,8 +395,9 @@ function moostVite(options) {
395
395
  }
396
396
  const outDir = cfg.build?.outDir || "dist";
397
397
  const isBuild = env.command === "build";
398
+ const ourPlugin = /^@moostjs\/vite($|\/)/;
398
399
  const userNoExternal = cfg.ssr?.noExternal;
399
- const ssrNoExternal = isBuild ? true : Array.from(new Set([...Array.isArray(userNoExternal) ? userNoExternal : userNoExternal && typeof userNoExternal !== "boolean" ? [userNoExternal] : [], /^@moostjs\/vite($|\/)/]));
400
+ const ssrNoExternal = userNoExternal === true ? true : userNoExternal !== void 0 ? [...Array.isArray(userNoExternal) ? userNoExternal : [userNoExternal], ourPlugin] : isBuild ? true : [ourPlugin];
400
401
  const userExternal = cfg.ssr?.external;
401
402
  const ssrExternal = isBuild ? [...Array.isArray(userExternal) ? userExternal : [], ...options.ssrExternal ?? []] : void 0;
402
403
  return {
package/dist/index.d.ts CHANGED
@@ -131,18 +131,21 @@ interface TMoostViteDevOptions {
131
131
  * - pnpm strict-resolution failures where externalized transitive deps
132
132
  * are not hoist-accessible from the consumer's `node_modules`.
133
133
  *
134
- * Use `ssrExternal` to opt specific packages OUT of bundling for cases
135
- * where bundling is impossible or undesirable — native bindings such as
136
- * `mongodb`, `ioredis`, or anything that loads `.node` modules.
134
+ * Use `ssrExternal` to opt specific packages OUT of bundling — native
135
+ * bindings (`mongodb`, `ioredis`, anything loading `.node` modules), or
136
+ * stable upstream libraries you'd rather resolve from `node_modules` at
137
+ * runtime (e.g. `['vue', 'vue-router', '@vue/server-renderer']` to drop
138
+ * a megabyte from `dist/server/`).
139
+ *
140
+ * Equivalent to `cfg.ssr.external` — entries from both are concatenated.
141
+ * The standalone `cfg.ssr.external` field works the same way; this
142
+ * plugin option exists for symmetry with `entry`/`ssrEntry`/`prefix`.
137
143
  *
138
144
  * Only applied in `middleware: true` mode during `vite build`. Dev
139
145
  * (`vite serve`) is unaffected: Vite's default externalizer continues
140
146
  * to handle node_modules, which is required so CJS-only packages like
141
147
  * `@vue/server-renderer` can be loaded by Node's ESM/CJS interop
142
148
  * instead of evaluated by Vite's ESM-only SSR module runner.
143
- *
144
- * Concatenated with any `cfg.ssr.external` the consumer sets directly
145
- * in `vite.config.ts`.
146
149
  */
147
150
  ssrExternal?: string[];
148
151
  }
package/dist/index.mjs CHANGED
@@ -364,8 +364,9 @@ function moostVite(options) {
364
364
  }
365
365
  const outDir = cfg.build?.outDir || "dist";
366
366
  const isBuild = env.command === "build";
367
+ const ourPlugin = /^@moostjs\/vite($|\/)/;
367
368
  const userNoExternal = cfg.ssr?.noExternal;
368
- const ssrNoExternal = isBuild ? true : Array.from(new Set([...Array.isArray(userNoExternal) ? userNoExternal : userNoExternal && typeof userNoExternal !== "boolean" ? [userNoExternal] : [], /^@moostjs\/vite($|\/)/]));
369
+ const ssrNoExternal = userNoExternal === true ? true : userNoExternal !== void 0 ? [...Array.isArray(userNoExternal) ? userNoExternal : [userNoExternal], ourPlugin] : isBuild ? true : [ourPlugin];
369
370
  const userExternal = cfg.ssr?.external;
370
371
  const ssrExternal = isBuild ? [...Array.isArray(userExternal) ? userExternal : [], ...options.ssrExternal ?? []] : void 0;
371
372
  return {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@moostjs/vite",
3
- "version": "0.6.14",
3
+ "version": "0.6.15",
4
4
  "description": "Vite Dev plugin for moostjs",
5
5
  "keywords": [
6
6
  "composables",
@@ -58,8 +58,8 @@
58
58
  "peerDependencies": {
59
59
  "sirv": "^3.0.0",
60
60
  "vite": "^8.0.0",
61
- "@moostjs/event-http": "^0.6.14",
62
- "moost": "^0.6.14"
61
+ "@moostjs/event-http": "^0.6.15",
62
+ "moost": "^0.6.15"
63
63
  },
64
64
  "peerDependenciesMeta": {
65
65
  "sirv": {