@nuxt/vite-server-nightly 0.0.0 β†’ 5.0.0-29802883.a46ecec7

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 ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2016-present - Nuxt Team
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,119 @@
1
+ <a href="https://nuxt.com"><img width="830" height="213" src="https://github.com/nuxt/nuxt/blob/main/.github/assets/banner.svg" alt="Nuxt banner"></a>
2
+
3
+ # Nuxt
4
+
5
+ <p>
6
+ <a href="https://npmx.dev/package/nuxt"><img src="https://npmx.dev/api/registry/badge/version/nuxt" alt="Version"></a>
7
+ <a href="https://npmx.dev/package/nuxt"><img src="https://npmx.dev/api/registry/badge/downloads/nuxt" alt="Downloads"></a>
8
+ <a href="https://github.com/nuxt/nuxt/blob/main/LICENSE"><img src="https://img.shields.io/github/license/nuxt/nuxt.svg?style=flat&colorA=18181B&colorB=28CF8D" alt="License"></a>
9
+ <a href="https://nuxt.com/modules"><img src="https://img.shields.io/badge/dynamic/json?url=https://nuxt.com/api/v1/modules&query=$.stats.modules&label=Modules&style=flat&colorA=18181B&colorB=28CF8D" alt="Modules"></a>
10
+ <a href="https://nuxt.com"><img src="https://img.shields.io/badge/Nuxt%20Docs-18181B?logo=nuxt" alt="Website"></a>
11
+ <a href="https://chat.nuxt.dev"><img src="https://img.shields.io/badge/Nuxt%20Discord-18181B?logo=discord" alt="Discord"></a>
12
+ <a href="https://securityscorecards.dev/viewer/?uri=github.com/nuxt/nuxt"><img src="https://api.securityscorecards.dev/projects/github.com/nuxt/nuxt/badge" alt="Nuxt openssf scorecard score"></a>
13
+ <a href="https://deepwiki.com/nuxt/nuxt"><img src="https://deepwiki.com/badge.svg" alt="Ask DeepWiki"></a>
14
+ </p>
15
+
16
+ Nuxt is a free and open-source framework with an intuitive and extendable way to create type-safe, performant and production-grade full-stack web applications and websites with Vue.js.
17
+
18
+ It provides a number of features that make it easy to build fast, SEO-friendly, and scalable web applications, including:
19
+ - Server-side rendering, static site generation, hybrid rendering and edge-side rendering
20
+ - Automatic routing with code-splitting and pre-fetching
21
+ - Data fetching and state management
22
+ - Search engine optimization and defining meta tags
23
+ - Auto imports of components, composables and utils
24
+ - TypeScript with zero configuration
25
+ - Go full-stack with our server/ directory
26
+ - Extensible with [300+ modules](https://nuxt.com/modules)
27
+ - Deployment to a variety of [hosting platforms](https://nuxt.com/deploy)
28
+ - ...[and much more](https://nuxt.com) πŸš€
29
+
30
+ ### Table of Contents
31
+
32
+ - πŸš€ [Getting Started](#getting-started)
33
+ - πŸ’» [Vue Development](#vue-development)
34
+ - πŸ“– [Documentation](#documentation)
35
+ - 🧩 [Modules](#modules)
36
+ - ❀️ [Contribute](#contribute)
37
+ - 🏠 [Local Development](#local-development)
38
+ - πŸ›Ÿ [Professional Support](#professional-support)
39
+ - πŸ”— [Follow Us](#follow-us)
40
+ - βš–οΈ [License](#license)
41
+
42
+ ---
43
+
44
+ ## <a name="getting-started">πŸš€ Getting Started</a>
45
+
46
+ Use the following command to create a new starter project. This will create a starter project with all the necessary files and dependencies:
47
+
48
+ ```bash
49
+ npm create nuxt@latest <my-project>
50
+ ```
51
+
52
+ > [!TIP]
53
+ > Discover also [nuxt.new](https://nuxt.new): Open a Nuxt starter on CodeSandbox, StackBlitz or locally to get up and running in a few seconds.
54
+
55
+ ## <a name="vue-development">πŸ’» Vue Development</a>
56
+
57
+ Simple, intuitive and powerful, Nuxt lets you write Vue components in a way that makes sense. Every repetitive task is automated, so you can focus on writing your full-stack Vue application with confidence.
58
+
59
+ Example of an `app.vue`:
60
+
61
+ ```vue
62
+ <script setup lang="ts">
63
+ useSeoMeta({
64
+ title: 'Meet Nuxt',
65
+ description: 'The Intuitive Vue Framework.',
66
+ })
67
+ </script>
68
+
69
+ <template>
70
+ <div id="app">
71
+ <AppHeader />
72
+ <NuxtPage />
73
+ <AppFooter />
74
+ </div>
75
+ </template>
76
+
77
+ <style scoped>
78
+ #app {
79
+ background-color: #020420;
80
+ color: #00DC82;
81
+ }
82
+ </style>
83
+ ```
84
+
85
+ ## <a name="documentation">πŸ“– Documentation</a>
86
+
87
+ We highly recommend you take a look at the [Nuxt documentation](https://nuxt.com/docs) to level up. It’s a great resource for learning more about the framework. It covers everything from getting started to advanced topics.
88
+
89
+ ## <a name="modules">🧩 Modules</a>
90
+
91
+ Discover our [list of modules](https://nuxt.com/modules) to supercharge your Nuxt project, created by the Nuxt team and community.
92
+
93
+ ## <a name="contribute">❀️ Contribute</a>
94
+
95
+ We invite you to contribute and help improve Nuxt πŸ’š
96
+
97
+ Here are a few ways you can get involved:
98
+ - **Reporting Bugs:** If you come across any bugs or issues, please check out the [reporting bugs guide](https://nuxt.com/docs/4.x/community/reporting-bugs) to learn how to submit a bug report.
99
+ - **Suggestions:** Have ideas to enhance Nuxt? We'd love to hear them! Check out the [contribution guide](https://nuxt.com/docs/4.x/community/contribution) to share your suggestions.
100
+ - **Questions:** If you have questions or need assistance, the [getting help guide](https://nuxt.com/docs/4.x/community/getting-help) provides resources to help you out.
101
+
102
+ ## <a name="local-development">🏠 Local Development</a>
103
+
104
+ Follow the docs to [Set Up Your Local Development Environment](https://nuxt.com/docs/4.x/community/framework-contribution#setup) to contribute to the framework and documentation.
105
+
106
+ ## <a name="professional-support">πŸ›Ÿ Professional Support</a>
107
+
108
+ - Technical audit & consulting: [Nuxt Experts](https://nuxt.com/enterprise/support)
109
+ - Custom development & more: [Nuxt Agencies Partners](https://nuxt.com/enterprise/agencies)
110
+
111
+ ## <a name="follow-us">πŸ”— Follow Us</a>
112
+
113
+ <p valign="center">
114
+ <a href="https://go.nuxt.com/discord"><img width="20" src="https://github.com/nuxt/nuxt/blob/main/.github/assets/discord.svg" alt="Discord"></a>&nbsp;&nbsp;<a href="https://go.nuxt.com/x"><img width="20" src="https://github.com/nuxt/nuxt/blob/main/.github/assets/twitter.svg" alt="Twitter"></a>&nbsp;&nbsp;<a href="https://go.nuxt.com/github"><img width="20" src="https://github.com/nuxt/nuxt/blob/main/.github/assets/github.svg" alt="GitHub"></a>&nbsp;&nbsp;<a href="https://go.nuxt.com/bluesky"><img width="20" src="https://github.com/nuxt/nuxt/blob/main/.github/assets/bluesky.svg" alt="Bluesky"></a>
115
+ </p>
116
+
117
+ ## <a name="license">βš–οΈ License</a>
118
+
119
+ [MIT](https://github.com/nuxt/nuxt/blob/main/LICENSE)
@@ -0,0 +1,23 @@
1
+ import { Nuxt } from "@nuxt/schema";
2
+ //#region src/index.d.ts
3
+ /**
4
+ * Experimental server builder implemented with Vite alone.
5
+ *
6
+ * It builds the client, emits a document for it, and ships no server of its own: with
7
+ * `ssr: false` that is a complete static SPA. With SSR enabled the server environment is
8
+ * built too, but running it is left to a Vite plugin or a custom server.
9
+ *
10
+ * Features that need a server are therefore unsupported: server routes and middleware,
11
+ * route rules, prerendering, and composables that need a request (such as
12
+ * `useRequestEvent`). Modules work to the extent that they do not require one:
13
+ * `useNitro()` throws and the `nitro:config` / `nitro:init` hooks never fire.
14
+ *
15
+ * TODO: render on the server, by extracting the renderer from `@nuxt/nitro-server` into
16
+ * something both builders can depend on, and exposing it here as a `{ fetch }` entry
17
+ * a plugin-provided target can run. Until then the document carries an
18
+ * `<!--ssr-outlet-->` marker, so a target can supply its own renderer.
19
+ * TODO: skip building the server environment if unclaimed.
20
+ */
21
+ declare function bundle(nuxt: Nuxt): Promise<void>;
22
+ //#endregion
23
+ export { bundle };
package/dist/index.mjs ADDED
@@ -0,0 +1,339 @@
1
+ import { existsSync } from "node:fs";
2
+ import { dirname, join, relative, resolve } from "pathe";
3
+ import { addTemplate, addVitePlugin, getLayerDirectories, logger, resolvePath } from "@nuxt/kit";
4
+ import { bundlerDiagnostics, setServerBuild } from "@nuxt/kit/internal";
5
+ import { defu } from "defu";
6
+ import { resolveModulePath } from "exsolve";
7
+ import { fileURLToPath } from "node:url";
8
+ import { NodeRequest, sendNodeResponse } from "srvx/node";
9
+ import { serveStatic } from "srvx/static";
10
+ import { cp, mkdir, readFile, rm, writeFile } from "node:fs/promises";
11
+ import { joinURL, withTrailingSlash } from "ufo";
12
+ import { link } from "clickable-path";
13
+ //#region src/dirs.ts
14
+ let _distDir = dirname(fileURLToPath(import.meta.url));
15
+ if (/(?:chunks|shared)$/.test(_distDir)) _distDir = dirname(_distDir);
16
+ const distDir = _distDir;
17
+ //#endregion
18
+ //#region src/html.ts
19
+ const ESCAPES = {
20
+ "&": "&amp;",
21
+ "<": "&lt;",
22
+ ">": "&gt;",
23
+ "\"": "&quot;"
24
+ };
25
+ function escapeAttr(value) {
26
+ return value.replace(/[&<>"]/g, (c) => ESCAPES[c]);
27
+ }
28
+ function renderAttrs(attrs) {
29
+ let rendered = "";
30
+ for (const key in attrs) {
31
+ const value = attrs[key];
32
+ if (value === void 0 || value === null || value === false) continue;
33
+ rendered += value === true ? ` ${key}` : ` ${key}="${escapeAttr(String(value))}"`;
34
+ }
35
+ return rendered;
36
+ }
37
+ function renderTag(tag, input) {
38
+ const { innerHTML, children, textContent, ...attrs } = input;
39
+ const content = innerHTML ?? children ?? textContent;
40
+ const open = `<${tag}${renderAttrs(attrs)}>`;
41
+ return VOID_TAGS.has(tag) ? open : `${open}${content ?? ""}</${tag}>`;
42
+ }
43
+ const VOID_TAGS = /* @__PURE__ */ new Set([
44
+ "base",
45
+ "link",
46
+ "meta"
47
+ ]);
48
+ /**
49
+ * Renders the head entries configured in `app.head`. Anything registered at runtime
50
+ * (`useHead`, `definePageMeta`) is applied by unhead once the app mounts, so it is
51
+ * intentionally absent from the static shell.
52
+ */
53
+ function renderConfiguredHead(nuxt) {
54
+ const head = nuxt.options.app.head;
55
+ const tags = [];
56
+ if (head.title) tags.push(`<title>${escapeAttr(head.title)}</title>`);
57
+ if (head.base) tags.push(renderTag("base", head.base));
58
+ for (const meta of head.meta || []) tags.push(renderTag("meta", meta));
59
+ for (const link of head.link || []) tags.push(renderTag("link", link));
60
+ for (const style of head.style || []) tags.push(renderTag("style", style));
61
+ for (const script of head.script || []) tags.push(renderTag("script", script));
62
+ for (const noscript of head.noscript || []) tags.push(renderTag("noscript", noscript));
63
+ return tags.join("");
64
+ }
65
+ /**
66
+ * The client reads `window.__NUXT__` for public runtime config and to decide whether
67
+ * it is hydrating server-rendered markup.
68
+ */
69
+ function renderPayload(nuxt) {
70
+ const payload = {
71
+ serverRendered: false,
72
+ config: {
73
+ public: nuxt.options.runtimeConfig.public,
74
+ app: nuxt.options.runtimeConfig.app
75
+ }
76
+ };
77
+ return `<script>window.__NUXT__=${JSON.stringify(payload).replace(/</g, "\\u003C")}<\/script>`;
78
+ }
79
+ /**
80
+ * Renders the SPA document.
81
+ *
82
+ * Only the app entry is linked: stylesheets, module preloads and the transforms of any
83
+ * configured Vite plugin are added by Vite itself, which owns this document as an HTML
84
+ * build input (and, in dev, transforms it on the way out).
85
+ */
86
+ function renderIndexHtml(nuxt, entry, spaLoadingTemplate = "") {
87
+ const app = nuxt.options.app;
88
+ const rootAttrs = renderAttrs(app.rootAttrs);
89
+ const teleportAttrs = renderAttrs(app.teleportAttrs);
90
+ const head = renderConfiguredHead(nuxt);
91
+ const loader = spaLoadingTemplate ? `<${app.spaLoaderTag}${renderAttrs(app.spaLoaderAttrs)}>${spaLoadingTemplate}</${app.spaLoaderTag}>` : "";
92
+ const root = nuxt.options.ssr === false ? "" : "<!--ssr-outlet-->";
93
+ const body = [
94
+ `<${app.rootTag}${rootAttrs}>${root}</${app.rootTag}>`,
95
+ loader,
96
+ `<${app.teleportTag}${teleportAttrs}></${app.teleportTag}>`,
97
+ renderPayload(nuxt),
98
+ `<script type="module" src="${escapeAttr(entry)}"><\/script>`
99
+ ].join("");
100
+ return [
101
+ "<!DOCTYPE html>",
102
+ `<html${renderAttrs(app.head.htmlAttrs || {})}>`,
103
+ `<head>${head}</head>`,
104
+ `<body${renderAttrs(app.head.bodyAttrs || {})}>${body}</body>`,
105
+ "</html>"
106
+ ].join("");
107
+ }
108
+ //#endregion
109
+ //#region src/templates/spa-loading-icon.ts
110
+ const template = () => {
111
+ return "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"80\" fill=\"none\" class=\"nuxt-spa-loading\" viewBox=\"0 0 37 25\"><path d=\"M24.236 22.006h10.742L25.563 5.822l-8.979 14.31a4 4 0 0 1-3.388 1.874H2.978l11.631-20 5.897 10.567\"/></svg><style>.nuxt-spa-loading{position:fixed;top:50%;left:50%;transform:translate(-50%,-50%)}.nuxt-spa-loading>path{fill:none;stroke:#00dc82;stroke-width:4px;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:128;stroke-dashoffset:128;animation:nuxt-spa-loading-move 3s linear infinite}@keyframes nuxt-spa-loading-move{to{stroke-dashoffset:-128}}</style>";
112
+ };
113
+ //#endregion
114
+ //#region src/output.ts
115
+ /** Static hosts commonly map unknown paths to one of these files. */
116
+ const SPA_FALLBACK_FILES = [
117
+ "index.html",
118
+ "200.html",
119
+ "404.html"
120
+ ];
121
+ async function writeStaticOutput(nuxt, publicDir) {
122
+ const clientDir = resolve(nuxt.options.buildDir, "dist/client");
123
+ const document = resolve(clientDir, "index.html");
124
+ if (!existsSync(document)) throw new Error(`[nuxt:vite-server] Expected \`${document}\` to exist. Did the client build run?`);
125
+ const html = await readFile(document, "utf-8");
126
+ await rm(resolve(clientDir, "manifest.json"), { force: true });
127
+ await mkdir(publicDir, { recursive: true });
128
+ for (const dirs of getLayerDirectories(nuxt)) if (existsSync(dirs.public)) await cp(dirs.public, publicDir, { recursive: true });
129
+ await cp(clientDir, publicDir, { recursive: true });
130
+ for (const file of SPA_FALLBACK_FILES) await writeFile(join(publicDir, file), html, "utf-8");
131
+ logger.success(`Static SPA output written to ${link(publicDir)}`);
132
+ }
133
+ async function spaLoadingTemplate(nuxt) {
134
+ if (nuxt.options.spaLoadingTemplate === false) return "";
135
+ const candidates = typeof nuxt.options.spaLoadingTemplate === "string" ? [resolve(nuxt.options.srcDir, nuxt.options.spaLoadingTemplate)] : nuxt.options._layers.map((layer) => resolve(layer.config.srcDir, layer.config.dir?.app || "app", "spa-loading-template.html"));
136
+ for (const candidate of candidates) if (existsSync(candidate)) return (await readFile(candidate, "utf-8")).trim();
137
+ if (nuxt.options.spaLoadingTemplate === true) return template();
138
+ if (nuxt.options.spaLoadingTemplate) bundlerDiagnostics.NUXT_B7016({ path: nuxt.options.spaLoadingTemplate });
139
+ return "";
140
+ }
141
+ function publicDirs(nuxt) {
142
+ return getLayerDirectories(nuxt).map((dirs) => withTrailingSlash(dirs.public)).filter((dir) => existsSync(dir));
143
+ }
144
+ //#endregion
145
+ //#region src/document.ts
146
+ /**
147
+ * Path of the SPA document, at the root of the Vite project so that it is emitted at the
148
+ * root of the client output. A project may put a real file here to take over the
149
+ * document entirely, as it would in any other Vite app; otherwise it is generated.
150
+ */
151
+ function documentPath(nuxt) {
152
+ return resolve(nuxt.options.vite.root || nuxt.options.srcDir, "index.html");
153
+ }
154
+ async function resolveDocument(nuxt) {
155
+ const path = documentPath(nuxt);
156
+ if (existsSync(path)) return readFile(path, "utf-8");
157
+ const entry = await resolvePath(resolve(nuxt.options.appDir, nuxt.options.dev || nuxt.options.experimental.asyncEntry ? "entry.async" : "entry"));
158
+ return renderIndexHtml(nuxt, nuxt.options.dev ? joinURL("/@fs", entry) : "./" + relative(resolve(path, ".."), entry), await spaLoadingTemplate(nuxt));
159
+ }
160
+ /**
161
+ * Provides the generated document as the contents of the HTML build input, so that
162
+ * nothing has to be written into the project to build it.
163
+ */
164
+ function DocumentPlugin(nuxt) {
165
+ const path = documentPath(nuxt);
166
+ return {
167
+ name: "nuxt:vite-server:document",
168
+ apply: "build",
169
+ applyToEnvironment: (environment) => environment.name === "client",
170
+ resolveId: {
171
+ order: "pre",
172
+ filter: { id: new RegExp(`^${escape(path)}$`) },
173
+ handler: (id) => id
174
+ },
175
+ load: {
176
+ filter: { id: new RegExp(`^${escape(path)}$`) },
177
+ handler: () => resolveDocument(nuxt)
178
+ }
179
+ };
180
+ }
181
+ /**
182
+ * `experimental.entryImportMap` rewrites cross-chunk imports of the entry to the bare
183
+ * `#entry` specifier, so that its hash cannot leak into the chunks importing it. That
184
+ * leaves the document responsible for mapping the specifier to the emitted chunk.
185
+ */
186
+ function EntryImportMapPlugin() {
187
+ return {
188
+ name: "nuxt:vite-server:entry-import-map",
189
+ apply: "build",
190
+ applyToEnvironment: (environment) => environment.name === "client",
191
+ transformIndexHtml: {
192
+ order: "post",
193
+ handler(_html, ctx) {
194
+ for (const chunk of Object.values(ctx.bundle || {})) if (chunk.type === "chunk" && chunk.isEntry && chunk.name === "entry") return [{
195
+ tag: "script",
196
+ attrs: { type: "importmap" },
197
+ children: JSON.stringify({ imports: { "#entry": "./" + chunk.fileName } }),
198
+ injectTo: "head-prepend"
199
+ }];
200
+ }
201
+ }
202
+ };
203
+ }
204
+ /**
205
+ * Builds the client environment, and marks the ssr environment as built when nothing
206
+ * will render on the server, so that the orchestrator skips it.
207
+ *
208
+ * A `buildApp` hook rather than a `builder.buildApp` config option, so that a plugin
209
+ * bringing its own deploy target (`@cloudflare/vite-plugin`, for one) keeps its own
210
+ * orchestration and its own environments: those are built as usual.
211
+ */
212
+ function BuildEnvironmentsPlugin(nuxt) {
213
+ return {
214
+ name: "nuxt:vite-server:build-environments",
215
+ apply: "build",
216
+ buildApp: {
217
+ order: "pre",
218
+ async handler(builder) {
219
+ const ssr = builder.environments.ssr;
220
+ if (ssr && nuxt.options.ssr === false) ssr.isBuilt = true;
221
+ for (const environment of [builder.environments.client, ssr]) if (environment && !environment.isBuilt) await builder.build(environment);
222
+ }
223
+ }
224
+ };
225
+ }
226
+ function escape(path) {
227
+ return path.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
228
+ }
229
+ //#endregion
230
+ //#region src/dev.ts
231
+ function setupDevServer(nuxt) {
232
+ let viteServer;
233
+ nuxt.hook("vite:serverCreated", (server) => {
234
+ viteServer = server;
235
+ });
236
+ const staticMiddleware = publicDirs(nuxt).map((dir) => serveStatic({ dir }));
237
+ const shell = async (url) => {
238
+ const html = await resolveDocument(nuxt);
239
+ return new Response(viteServer ? await viteServer.transformIndexHtml(url, html) : html, { headers: { "content-type": "text/html;charset=utf-8" } });
240
+ };
241
+ nuxt.server = { handler: async (req, res) => {
242
+ if (viteServer && await handledByVite(viteServer, req, res)) return;
243
+ const request = new NodeRequest({
244
+ req,
245
+ res
246
+ });
247
+ const next = (index) => {
248
+ const middleware = staticMiddleware[index];
249
+ return middleware ? middleware(request, () => next(index + 1)) : shell(req.url || "/");
250
+ };
251
+ await sendNodeResponse(res, await next(0));
252
+ } };
253
+ }
254
+ function handledByVite(server, req, res) {
255
+ return new Promise((resolvePromise, reject) => {
256
+ const originalUrl = req.url;
257
+ server.middlewares.handle(req, res, (error) => {
258
+ req.url = originalUrl;
259
+ if (error) return reject(error);
260
+ resolvePromise(false);
261
+ });
262
+ res.on("close", () => resolvePromise(true));
263
+ }).then((handled) => handled || res.writableEnded);
264
+ }
265
+ //#endregion
266
+ //#region src/index.ts
267
+ /**
268
+ * Experimental server builder implemented with Vite alone.
269
+ *
270
+ * It builds the client, emits a document for it, and ships no server of its own: with
271
+ * `ssr: false` that is a complete static SPA. With SSR enabled the server environment is
272
+ * built too, but running it is left to a Vite plugin or a custom server.
273
+ *
274
+ * Features that need a server are therefore unsupported: server routes and middleware,
275
+ * route rules, prerendering, and composables that need a request (such as
276
+ * `useRequestEvent`). Modules work to the extent that they do not require one:
277
+ * `useNitro()` throws and the `nitro:config` / `nitro:init` hooks never fire.
278
+ *
279
+ * TODO: render on the server, by extracting the renderer from `@nuxt/nitro-server` into
280
+ * something both builders can depend on, and exposing it here as a `{ fetch }` entry
281
+ * a plugin-provided target can run. Until then the document carries an
282
+ * `<!--ssr-outlet-->` marker, so a target can supply its own renderer.
283
+ * TODO: skip building the server environment if unclaimed.
284
+ */
285
+ function bundle(nuxt) {
286
+ if (nuxt.options.builder !== "@nuxt/vite-builder") throw new Error("`@nuxt/vite-server` requires the Vite builder.");
287
+ logger.warn("`@nuxt/vite-server` is experimental. It builds with Vite alone and ships no server, so features and modules that need one will not work.");
288
+ if (nuxt.options.ssr !== false) logger.warn("`@nuxt/vite-server` does not render on the server. The server environment is built for a vite plugin or a custom server to run; until one does, the document is served as a client-only shell.");
289
+ warnUnsupported(nuxt);
290
+ const outputDir = resolve(nuxt.options.rootDir, nuxt.options.nitro.output?.dir || ".output");
291
+ const publicDir = resolve(outputDir, "public");
292
+ setServerBuild({
293
+ name: "vite",
294
+ label: "Vite SPA",
295
+ output: {
296
+ dir: () => outputDir,
297
+ publicDir: () => publicDir
298
+ },
299
+ capabilities: {
300
+ server: nuxt.options.ssr !== false,
301
+ dev: true
302
+ },
303
+ buildsSeparately: false,
304
+ runtime: {
305
+ fetch: resolve(distDir, "runtime/fetch"),
306
+ runtimeConfig: resolve(nuxt.options.buildDir, "vite-server/runtime-config.mjs")
307
+ },
308
+ preview: { staticDir: () => publicDir }
309
+ }, nuxt);
310
+ addTemplate({
311
+ filename: "vite-server/runtime-config.mjs",
312
+ write: true,
313
+ getContents: ({ nuxt }) => [`const config = ${JSON.stringify({
314
+ app: nuxt.options.runtimeConfig.app,
315
+ public: nuxt.options.runtimeConfig.public
316
+ })}`, `export const useRuntimeConfig = () => globalThis.__NUXT__?.config || config`].join("\n")
317
+ });
318
+ nuxt.options.experimental.appManifest = false;
319
+ nuxt.options.alias["#app-manifest"] = resolveModulePath("mocked-exports/empty", { from: import.meta.url });
320
+ nuxt.options.vite.plugins ||= [];
321
+ nuxt.options.vite.plugins.push(BuildEnvironmentsPlugin(nuxt));
322
+ if (!nuxt.options.dev) {
323
+ nuxt.options.vite.$client = defu(nuxt.options.vite.$client, { build: { rolldownOptions: { input: { index: documentPath(nuxt) } } } });
324
+ addVitePlugin(() => [DocumentPlugin(nuxt), EntryImportMapPlugin()], { server: false });
325
+ }
326
+ if (nuxt.options.dev) setupDevServer(nuxt);
327
+ else nuxt.hook("build:done", () => writeStaticOutput(nuxt, publicDir));
328
+ return Promise.resolve();
329
+ }
330
+ function warnUnsupported(nuxt) {
331
+ const unsupported = [];
332
+ if (nuxt.options.serverHandlers.length || getLayerDirectories(nuxt).some((dirs) => existsSync(dirs.server))) unsupported.push("server routes and server middleware");
333
+ if (Object.keys(nuxt.options.routeRules || {}).length || Object.keys(nuxt.options.nitro.routeRules || {}).length) unsupported.push("route rules");
334
+ if (nuxt.options.nitro.prerender?.routes?.length || nuxt.options.nitro.prerender?.crawlLinks) unsupported.push("prerendering");
335
+ if (nuxt.options.dev && nuxt.options.devServerHandlers.length) unsupported.push("dev server handlers");
336
+ if (unsupported.length) logger.warn(`\`@nuxt/vite-server\` builds a static SPA with no server, so ${unsupported.join(", ")} will be ignored.`);
337
+ }
338
+ //#endregion
339
+ export { bundle };
@@ -0,0 +1,4 @@
1
+ //#region src/runtime/fetch.ts
2
+ const fetch = (...args) => globalThis.fetch(...args);
3
+ //#endregion
4
+ export { fetch };
package/package.json CHANGED
@@ -1,8 +1,49 @@
1
1
  {
2
2
  "name": "@nuxt/vite-server-nightly",
3
- "version": "0.0.0",
3
+ "version": "5.0.0-29802883.a46ecec7",
4
+ "repository": {
5
+ "type": "git",
6
+ "url": "git+https://github.com/nuxt/nuxt.git",
7
+ "directory": "packages/vite-server"
8
+ },
9
+ "description": "Experimental pure Vite server builder for Nuxt",
10
+ "homepage": "https://nuxt.com",
11
+ "license": "MIT",
12
+ "type": "module",
13
+ "types": "./dist/index.d.mts",
14
+ "exports": {
15
+ ".": "./dist/index.mjs",
16
+ "./package.json": "./package.json"
17
+ },
4
18
  "files": [
5
19
  "dist"
6
20
  ],
7
- "author": "Daniel Roe <daniel@roe.dev>"
8
- }
21
+ "dependencies": {
22
+ "@nuxt/kit": "npm:@nuxt/kit-nightly@5.0.0-29802883.a46ecec7",
23
+ "clickable-path": "^0.1.0",
24
+ "defu": "^6.1.7",
25
+ "exsolve": "^1.1.1",
26
+ "mocked-exports": "^0.1.1",
27
+ "pathe": "^2.0.3",
28
+ "srvx": "0.11.22",
29
+ "ufo": "^1.6.4"
30
+ },
31
+ "devDependencies": {
32
+ "@nuxt/schema": "npm:@nuxt/schema-nightly@5.0.0-29802883.a46ecec7",
33
+ "tsdown": "0.22.14",
34
+ "vite": "^8.2.2",
35
+ "vitest": "4.1.11"
36
+ },
37
+ "peerDependencies": {
38
+ "nuxt": "npm:nuxt-nightly@5.0.0-29802883.a46ecec7",
39
+ "vite": "^8.2.2"
40
+ },
41
+ "engines": {
42
+ "node": "^22.19.0 || ^24.11.0 || >=26.0.0"
43
+ },
44
+ "_name": "@nuxt/vite-server",
45
+ "scripts": {
46
+ "build": "tsdown",
47
+ "test:attw": "node ../../scripts/test-attw.ts"
48
+ }
49
+ }
package/dist/.gitkeep DELETED
File without changes