initial commit

This commit is contained in:
Zoe
2023-01-03 09:29:04 -06:00
commit 7851137d88
12889 changed files with 2557443 additions and 0 deletions

View File

@@ -0,0 +1,31 @@
import { transform } from 'esbuild';
import { visualizer } from 'rollup-plugin-visualizer';
function analyzePlugin(ctx) {
return [
{
name: "nuxt:analyze-minify",
async generateBundle(_opts, outputBundle) {
for (const [_bundleId, bundle] of Object.entries(outputBundle)) {
if (bundle.type !== "chunk") {
continue;
}
const originalEntries = Object.entries(bundle.modules);
const minifiedEntries = await Promise.all(originalEntries.map(async ([moduleId, module]) => {
const { code } = await transform(module.code || "", { minify: true });
return [moduleId, { ...module, code }];
}));
bundle.modules = Object.fromEntries(minifiedEntries);
}
}
},
visualizer({
...ctx.nuxt.options.build.analyze,
filename: ctx.nuxt.options.build.analyze.filename.replace("{name}", "client"),
title: "Client bundle stats",
gzipSize: true
})
];
}
export { analyzePlugin };

View File

@@ -0,0 +1,226 @@
import { pathToFileURL } from 'node:url';
import { existsSync } from 'node:fs';
import { builtinModules } from 'node:module';
import { normalize, resolve, isAbsolute } from 'pathe';
import { genObjectFromRawEntries, genDynamicImport } from 'knitwork';
import fse from 'fs-extra';
import { debounce } from 'perfect-debounce';
import { isIgnored, logger } from '@nuxt/kit';
import { h as hashId, c as createIsExternal, u as uniq, w as writeManifest, i as isCSS } from '../shared/vite-builder.1c88b3ee.mjs';
import 'vite';
import '@rollup/plugin-replace';
import 'mlly';
import 'ufo';
import 'pathe/utils';
import 'pkg-types';
import '@vitejs/plugin-vue';
import '@vitejs/plugin-vue-jsx';
import 'get-port-please';
import 'defu';
import 'h3';
import 'ohash';
import 'vite-node/server';
import 'vue-bundle-renderer';
import 'externality';
import 'escape-string-regexp';
import 'unplugin';
import 'estree-walker';
import 'magic-string';
async function transformRequest(opts, id) {
if (id && id.startsWith("/@id/__x00__")) {
id = "\0" + id.slice("/@id/__x00__".length);
}
if (id && id.startsWith("/@id/")) {
id = id.slice("/@id/".length);
}
if (id && !id.startsWith("/@fs/") && id.startsWith("/")) {
const resolvedPath = resolve(opts.viteServer.config.root, "." + id);
if (existsSync(resolvedPath)) {
id = resolvedPath;
}
}
id = id.replace(/^\/?(?=\w:)/, "/@fs/");
const externalId = id.replace(/\?v=\w+$|^\/@fs/, "");
if (await opts.isExternal(externalId)) {
const path = builtinModules.includes(externalId.split("node:").pop()) ? externalId : isAbsolute(externalId) ? pathToFileURL(externalId).href : externalId;
return {
code: `(global, module, _, exports, importMeta, ssrImport, ssrDynamicImport, ssrExportAll) =>
${genDynamicImport(path, { wrapper: false })}
.then(r => {
if (r.default && r.default.__esModule)
r = r.default
exports.default = r.default
ssrExportAll(r)
})
.catch(e => {
console.error(e)
throw new Error(${JSON.stringify(`[vite dev] Error loading external "${id}".`)})
})`,
deps: [],
dynamicDeps: []
};
}
const res = await opts.viteServer.transformRequest(id, { ssr: true }).catch((err) => {
console.warn(`[SSR] Error transforming ${id}:`, err);
}) || { code: "", map: {}, deps: [], dynamicDeps: [] };
const code = `async function (global, module, exports, __vite_ssr_exports__, __vite_ssr_import_meta__, __vite_ssr_import__, __vite_ssr_dynamic_import__, __vite_ssr_exportAll__) {
${res.code || "/* empty */"};
}`;
return { code, deps: res.deps || [], dynamicDeps: res.dynamicDeps || [] };
}
async function transformRequestRecursive(opts, id, parent = "<entry>", chunks = {}) {
if (chunks[id]) {
chunks[id].parents.push(parent);
return;
}
const res = await transformRequest(opts, id);
const deps = uniq([...res.deps, ...res.dynamicDeps]);
chunks[id] = {
id,
code: res.code,
deps,
parents: [parent]
};
for (const dep of deps) {
await transformRequestRecursive(opts, dep, id, chunks);
}
return Object.values(chunks);
}
async function bundleRequest(opts, entryURL) {
const chunks = await transformRequestRecursive(opts, entryURL);
const listIds = (ids) => ids.map((id) => `// - ${id} (${hashId(id)})`).join("\n");
const chunksCode = chunks.map((chunk) => `
// --------------------
// Request: ${chunk.id}
// Parents:
${listIds(chunk.parents)}
// Dependencies:
${listIds(chunk.deps)}
// --------------------
const ${hashId(chunk.id + "-" + chunk.code)} = ${chunk.code}
`).join("\n");
const manifestCode = `const __modules__ = ${genObjectFromRawEntries(chunks.map((chunk) => [chunk.id, hashId(chunk.id + "-" + chunk.code)]))}`;
const ssrModuleLoader = `
const __pendingModules__ = new Map()
const __pendingImports__ = new Map()
const __ssrContext__ = { global: globalThis }
function __ssrLoadModule__(url, urlStack = []) {
const pendingModule = __pendingModules__.get(url)
if (pendingModule) { return pendingModule }
const modulePromise = __instantiateModule__(url, urlStack)
__pendingModules__.set(url, modulePromise)
modulePromise.catch(() => { __pendingModules__.delete(url) })
.finally(() => { __pendingModules__.delete(url) })
return modulePromise
}
async function __instantiateModule__(url, urlStack) {
const mod = __modules__[url]
if (mod.stubModule) { return mod.stubModule }
const stubModule = { [Symbol.toStringTag]: 'Module' }
Object.defineProperty(stubModule, '__esModule', { value: true })
mod.stubModule = stubModule
// https://vitejs.dev/guide/api-hmr.html
const importMeta = { url, hot: { accept() {}, prune() {}, dispose() {}, invalidate() {}, decline() {}, on() {} } }
urlStack = urlStack.concat(url)
const isCircular = url => urlStack.includes(url)
const pendingDeps = []
const ssrImport = async (dep) => {
// TODO: Handle externals if dep[0] !== '.' | '/'
if (!isCircular(dep) && !__pendingImports__.get(dep)?.some(isCircular)) {
pendingDeps.push(dep)
if (pendingDeps.length === 1) {
__pendingImports__.set(url, pendingDeps)
}
await __ssrLoadModule__(dep, urlStack)
if (pendingDeps.length === 1) {
__pendingImports__.delete(url)
} else {
pendingDeps.splice(pendingDeps.indexOf(dep), 1)
}
}
return __modules__[dep].stubModule
}
function ssrDynamicImport (dep) {
// TODO: Handle dynamic import starting with . relative to url
return ssrImport(dep)
}
function ssrExportAll(sourceModule) {
for (const key in sourceModule) {
if (key !== 'default') {
try {
Object.defineProperty(stubModule, key, {
enumerable: true,
configurable: true,
get() { return sourceModule[key] }
})
} catch (_err) { }
}
}
}
const cjsModule = {
get exports () {
return stubModule.default
},
set exports (v) {
stubModule.default = v
},
}
await mod(
__ssrContext__.global,
cjsModule,
stubModule.default,
stubModule,
importMeta,
ssrImport,
ssrDynamicImport,
ssrExportAll
)
return stubModule
}
`;
const code = [
chunksCode,
manifestCode,
ssrModuleLoader,
`export default await __ssrLoadModule__(${JSON.stringify(entryURL)})`
].join("\n\n");
return {
code,
ids: chunks.map((i) => i.id)
};
}
async function initViteDevBundler(ctx, onBuild) {
const viteServer = ctx.ssrServer;
const options = {
viteServer,
isExternal: createIsExternal(viteServer, ctx.nuxt.options.rootDir)
};
const _doBuild = async () => {
const start = Date.now();
const { code, ids } = await bundleRequest(options, ctx.entry);
await fse.writeFile(resolve(ctx.nuxt.options.buildDir, "dist/server/server.mjs"), code, "utf-8");
await writeManifest(ctx, ids.filter(isCSS).map((i) => i.slice(1)));
const time = Date.now() - start;
logger.success(`Vite server built in ${time}ms`);
await onBuild();
};
const doBuild = debounce(_doBuild);
await _doBuild();
viteServer.watcher.on("all", (_event, file) => {
file = normalize(file);
if (file.indexOf(ctx.nuxt.options.buildDir) === 0 || isIgnored(file)) {
return;
}
doBuild();
});
ctx.nuxt.hook("app:templatesGenerated", () => doBuild());
}
export { bundleRequest, initViteDevBundler };

20
node_modules/@nuxt/vite-builder/dist/index.d.ts generated vendored Normal file
View File

@@ -0,0 +1,20 @@
import * as vite from 'vite';
import { InlineConfig, SSROptions } from 'vite';
import { Nuxt } from '@nuxt/schema';
import { Options } from '@vitejs/plugin-vue';
interface ViteOptions extends InlineConfig {
vue?: Options;
ssr?: SSROptions;
devBundler?: 'vite-node' | 'legacy';
}
interface ViteBuildContext {
nuxt: Nuxt;
config: ViteOptions;
entry: string;
clientServer?: vite.ViteDevServer;
ssrServer?: vite.ViteDevServer;
}
declare function bundle(nuxt: Nuxt): Promise<void>;
export { ViteBuildContext, ViteOptions, bundle };

26
node_modules/@nuxt/vite-builder/dist/index.mjs generated vendored Normal file
View File

@@ -0,0 +1,26 @@
export { b as bundle } from './shared/vite-builder.1c88b3ee.mjs';
import 'vite';
import 'pathe';
import '@nuxt/kit';
import '@rollup/plugin-replace';
import 'mlly';
import 'ufo';
import 'pathe/utils';
import 'pkg-types';
import '@vitejs/plugin-vue';
import '@vitejs/plugin-vue-jsx';
import 'get-port-please';
import 'defu';
import 'h3';
import 'node:fs';
import 'ohash';
import 'node:url';
import 'vite-node/server';
import 'fs-extra';
import 'vue-bundle-renderer';
import 'externality';
import 'knitwork';
import 'escape-string-regexp';
import 'unplugin';
import 'estree-walker';
import 'magic-string';

View File

@@ -0,0 +1,2 @@
declare function _default(): Promise<any>;
export default _default;

View File

@@ -0,0 +1,3 @@
import { viteNodeFetch } from './vite-node-shared.mjs'
export default () => viteNodeFetch('/manifest')

View File

@@ -0,0 +1,2 @@
export const viteNodeOptions: any;
export const viteNodeFetch: import("ofetch/dist/error-8a55452d").$;

View File

@@ -0,0 +1,8 @@
export interface ViteNodeRuntimeOptions {
baseURL: string,
rootDir: string,
entryPath: string,
base: string
}
export function getViteNodeOptions (): ViteNodeRuntimeOptions

View File

@@ -0,0 +1,11 @@
import { Agent as HTTPSAgent } from 'node:https'
import { $fetch } from 'ofetch'
export const viteNodeOptions = JSON.parse(process.env.NUXT_VITE_NODE_OPTIONS || '{}')
export const viteNodeFetch = $fetch.create({
baseURL: viteNodeOptions.baseURL,
agent: viteNodeOptions.baseURL.startsWith('https://')
? new HTTPSAgent({ rejectUnauthorized: false })
: null
})

View File

@@ -0,0 +1,2 @@
declare function _default(ssrContext: any): Promise<any>;
export default _default;

View File

@@ -0,0 +1,99 @@
import { performance } from 'node:perf_hooks'
import { createError } from 'h3'
import { ViteNodeRunner } from 'vite-node/client'
import consola from 'consola'
import { viteNodeOptions, viteNodeFetch } from './vite-node-shared.mjs'
const runner = createRunner()
let render
export default async (ssrContext) => {
// Workaround for stub mode
// https://github.com/nuxt/framework/pull/3983
process.server = true
// Invalidate cache for files changed since last rendering
const invalidates = await viteNodeFetch('/invalidates')
const updates = runner.moduleCache.invalidateDepTree(invalidates)
// Execute SSR bundle on demand
const start = performance.now()
render = (updates.has(viteNodeOptions.entryPath) || !render) ? (await runner.executeFile(viteNodeOptions.entryPath)).default : render
if (updates.size) {
const time = Math.round((performance.now() - start) * 1000) / 1000
consola.success(`Vite server hmr ${updates.size} files`, time ? `in ${time}ms` : '')
}
const result = await render(ssrContext)
return result
}
function createRunner () {
const _importers = new Map()
return new ViteNodeRunner({
root: viteNodeOptions.root, // Equals to Nuxt `srcDir`
base: viteNodeOptions.base,
resolveId (id, importer) { _importers.set(id, importer) },
async fetchModule (id) {
const importer = _importers.get(id)
_importers.delete(id)
id = id.replace(/\/\//g, '/') // TODO: fix in vite-node
return await viteNodeFetch('/module/' + encodeURI(id)).catch((err) => {
const errorData = err?.data?.data
if (!errorData) {
throw err
}
let _err
try {
const { message, stack } = formatViteError(errorData, id, importer)
_err = createError({
statusMessage: 'Vite Error',
message,
stack
})
} catch (formatError) {
consola.warn('Internal nuxt error while formatting vite-node error. Please report this!', formatError)
const message = `[vite-node] [TransformError] ${errorData?.message || '-'}`
consola.error(message, errorData)
throw createError({
statusMessage: 'Vite Error',
message,
stack: `${message}\nat ${id}\n` + (errorData?.stack || '')
})
}
throw _err
})
}
})
}
function formatViteError (errorData, id, importer) {
const errorCode = errorData.name || errorData.reasonCode || errorData.code
const frame = errorData.frame || errorData.source || errorData.pluginCode
const getLocId = (locObj = {}) => locObj.file || locObj.id || locObj.url || id || ''
const getLocPos = (locObj = {}) => locObj.line ? `${locObj.line}:${locObj.column || 0}` : ''
const locId = getLocId(errorData.loc) || getLocId(errorData.location) || getLocId(errorData.input) || getLocId(errorData)
const locPos = getLocPos(errorData.loc) || getLocPos(errorData.location) || getLocPos(errorData.input) || getLocPos(errorData)
const loc = locId.replace(process.cwd(), '.') + (locPos ? `:${locPos}` : '')
const message = [
'[vite-node]',
errorData.plugin && `[plugin:${errorData.plugin}]`,
errorCode && `[${errorCode}]`,
loc,
errorData.reason && `: ${errorData.reason}`,
frame && `<br><pre>${frame.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;')}</pre><br>`
].filter(Boolean).join(' ')
const stack = [
message,
`at ${loc} ${importer ? `(imported from ${importer})` : ''}`,
errorData.stack
].filter(Boolean).join('\n')
return {
message,
stack
}
}

View File

@@ -0,0 +1,842 @@
import * as vite from 'vite';
import { resolve, dirname, join, relative, isAbsolute } from 'pathe';
import { logger, resolveModule, requireModule, resolvePath, isIgnored, addVitePlugin } from '@nuxt/kit';
import replace from '@rollup/plugin-replace';
import { resolve as resolve$1, findStaticImports, sanitizeFilePath } from 'mlly';
import { joinURL, withoutLeadingSlash, parseURL, parseQuery, withTrailingSlash } from 'ufo';
import { filename } from 'pathe/utils';
import { resolveTSConfig } from 'pkg-types';
import vuePlugin from '@vitejs/plugin-vue';
import viteJsxPlugin from '@vitejs/plugin-vue-jsx';
import { getPort } from 'get-port-please';
import defu from 'defu';
import { toNodeListener, createApp, defineEventHandler, defineLazyEventHandler, eventHandler, createError } from 'h3';
import 'node:fs';
import { hash } from 'ohash';
import { fileURLToPath, pathToFileURL } from 'node:url';
import { ViteNodeServer } from 'vite-node/server';
import fse from 'fs-extra';
import { normalizeViteManifest } from 'vue-bundle-renderer';
import { ExternalsDefaults, isExternal } from 'externality';
import { genObjectFromRawEntries } from 'knitwork';
import escapeRE from 'escape-string-regexp';
import { createUnplugin } from 'unplugin';
import { walk } from 'estree-walker';
import MagicString from 'magic-string';
function cacheDirPlugin(rootDir, name) {
const optimizeCacheDir = resolve(rootDir, "node_modules/.cache/vite", name);
return {
name: "nuxt:cache-dir",
configResolved(resolvedConfig) {
resolvedConfig.optimizeCacheDir = optimizeCacheDir;
}
};
}
function uniq(arr) {
return Array.from(new Set(arr));
}
const IS_CSS_RE = /\.(?:css|scss|sass|postcss|less|stylus|styl)(\?[^.]+)?$/;
function isCSS(file) {
return IS_CSS_RE.test(file);
}
function hashId(id) {
return "$id_" + hash(id);
}
function devStyleSSRPlugin(options) {
return {
name: "nuxt:dev-style-ssr",
apply: "serve",
enforce: "post",
transform(code, id) {
if (!isCSS(id) || !code.includes("import.meta.hot")) {
return;
}
let moduleId = id;
if (moduleId.startsWith(options.srcDir)) {
moduleId = moduleId.slice(options.srcDir.length);
}
const selector = joinURL(options.buildAssetsURL, moduleId);
return code + `
document.querySelectorAll(\`link[href="${selector}"]\`).forEach(i=>i.remove())`;
}
};
}
let _distDir = dirname(fileURLToPath(import.meta.url));
if (_distDir.match(/(chunks|shared)$/)) {
_distDir = dirname(_distDir);
}
const distDir = _distDir;
resolve(distDir, "..");
function createIsExternal(viteServer, rootDir) {
const externalOpts = {
inline: [
/virtual:/,
/\.ts$/,
...ExternalsDefaults.inline || [],
...viteServer.config.ssr.noExternal
],
external: [
...viteServer.config.ssr.external || [],
/node_modules/
],
resolve: {
type: "module",
extensions: [".ts", ".js", ".json", ".vue", ".mjs", ".jsx", ".tsx", ".wasm"]
}
};
return (id) => isExternal(id, rootDir, externalOpts);
}
function viteNodePlugin(ctx) {
const invalidates = /* @__PURE__ */ new Set();
function markInvalidate(mod) {
if (!mod.id) {
return;
}
if (invalidates.has(mod.id)) {
return;
}
invalidates.add(mod.id);
for (const importer of mod.importers) {
markInvalidate(importer);
}
}
return {
name: "nuxt:vite-node-server",
enforce: "post",
configureServer(server) {
server.middlewares.use("/__nuxt_vite_node__", toNodeListener(createViteNodeApp(ctx, invalidates)));
ctx.nuxt.hook("app:templatesGenerated", () => {
for (const [id, mod] of server.moduleGraph.idToModuleMap) {
if (id.startsWith("virtual:")) {
markInvalidate(mod);
}
}
});
},
handleHotUpdate({ file, server }) {
const mods = server.moduleGraph.getModulesByFile(file) || [];
for (const mod of mods) {
markInvalidate(mod);
}
}
};
}
function getManifest(ctx) {
const css = Array.from(ctx.ssrServer.moduleGraph.urlToModuleMap.keys()).filter((i) => isCSS(i));
const manifest = normalizeViteManifest({
"@vite/client": {
file: "@vite/client",
css,
module: true,
isEntry: true
},
[ctx.entry]: {
file: ctx.entry,
isEntry: true,
module: true,
resourceType: "script"
}
});
return manifest;
}
function createViteNodeApp(ctx, invalidates = /* @__PURE__ */ new Set()) {
const app = createApp();
app.use("/manifest", defineEventHandler(() => {
const manifest = getManifest(ctx);
return manifest;
}));
app.use("/invalidates", defineEventHandler(() => {
const ids = Array.from(invalidates);
invalidates.clear();
return ids;
}));
app.use("/module", defineLazyEventHandler(() => {
const viteServer = ctx.ssrServer;
const node = new ViteNodeServer(viteServer, {
deps: {
inline: [
/\/(nuxt|nuxt3)\//,
/^#/,
...ctx.nuxt.options.build.transpile
]
},
transformMode: {
ssr: [/.*/],
web: []
}
});
const isExternal = createIsExternal(viteServer, ctx.nuxt.options.rootDir);
node.shouldExternalize = async (id) => {
const result = await isExternal(id);
if (result?.external) {
return resolve$1(result.id, { url: ctx.nuxt.options.modulesDir });
}
return false;
};
return eventHandler(async (event) => {
const moduleId = decodeURI(event.node.req.url).substring(1);
if (moduleId === "/") {
throw createError({ statusCode: 400 });
}
const module = await node.fetchModule(moduleId).catch((err) => {
const errorData = {
code: "VITE_ERROR",
id: moduleId,
stack: "",
...err
};
throw createError({ data: errorData });
});
return module;
});
}));
return app;
}
async function initViteNodeServer(ctx) {
const viteNodeServerOptions = {
baseURL: `${ctx.nuxt.options.devServer.url}__nuxt_vite_node__`,
root: ctx.nuxt.options.srcDir,
entryPath: ctx.entry,
base: ctx.ssrServer.config.base || "/_nuxt/"
};
process.env.NUXT_VITE_NODE_OPTIONS = JSON.stringify(viteNodeServerOptions);
const serverResolvedPath = resolve(distDir, "runtime/vite-node.mjs");
const manifestResolvedPath = resolve(distDir, "runtime/client.manifest.mjs");
await fse.writeFile(
resolve(ctx.nuxt.options.buildDir, "dist/server/server.mjs"),
`export { default } from ${JSON.stringify(pathToFileURL(serverResolvedPath).href)}`
);
await fse.writeFile(
resolve(ctx.nuxt.options.buildDir, "dist/server/client.manifest.mjs"),
`export { default } from ${JSON.stringify(pathToFileURL(manifestResolvedPath).href)}`
);
}
async function buildClient(ctx) {
const clientConfig = vite.mergeConfig(ctx.config, {
entry: ctx.entry,
base: ctx.nuxt.options.dev ? joinURL(ctx.nuxt.options.app.baseURL.replace(/^\.\//, "/") || "/", ctx.nuxt.options.app.buildAssetsDir) : "./",
experimental: {
renderBuiltUrl: (filename, { type, hostType }) => {
if (hostType !== "js" || type === "asset") {
return { relative: true };
}
return { runtime: `globalThis.__publicAssetsURL(${JSON.stringify(filename)})` };
}
},
define: {
"process.server": false,
"process.client": true,
"module.hot": false
},
optimizeDeps: {
entries: [ctx.entry]
},
resolve: {
alias: {
"#build/plugins": resolve(ctx.nuxt.options.buildDir, "plugins/client"),
"#internal/nitro": resolve(ctx.nuxt.options.buildDir, "nitro.client.mjs")
},
dedupe: ["vue"]
},
build: {
sourcemap: ctx.nuxt.options.sourcemap.client ? ctx.config.build?.sourcemap ?? true : false,
manifest: true,
outDir: resolve(ctx.nuxt.options.buildDir, "dist/client"),
rollupOptions: {
input: ctx.entry
}
},
plugins: [
cacheDirPlugin(ctx.nuxt.options.rootDir, "client"),
vuePlugin(ctx.config.vue),
viteJsxPlugin(),
devStyleSSRPlugin({
srcDir: ctx.nuxt.options.srcDir,
buildAssetsURL: joinURL(ctx.nuxt.options.app.baseURL, ctx.nuxt.options.app.buildAssetsDir)
}),
viteNodePlugin(ctx)
],
appType: "custom",
server: {
middlewareMode: true
}
});
if (!ctx.nuxt.options.dev) {
clientConfig.server.hmr = false;
}
clientConfig.build.rollupOptions = defu(clientConfig.build.rollupOptions, {
output: {
chunkFileNames: ctx.nuxt.options.dev ? void 0 : withoutLeadingSlash(join(ctx.nuxt.options.app.buildAssetsDir, "[name].[hash].js")),
entryFileNames: ctx.nuxt.options.dev ? "entry.js" : withoutLeadingSlash(join(ctx.nuxt.options.app.buildAssetsDir, "[name].[hash].js"))
}
});
if (clientConfig.server && clientConfig.server.hmr !== false) {
const hmrPortDefault = 24678;
const hmrPort = await getPort({
port: hmrPortDefault,
ports: Array.from({ length: 20 }, (_, i) => hmrPortDefault + 1 + i)
});
clientConfig.server = defu(clientConfig.server, {
https: ctx.nuxt.options.devServer.https,
hmr: {
protocol: ctx.nuxt.options.devServer.https ? "wss" : "ws",
port: hmrPort
}
});
}
if (ctx.nuxt.options.build.analyze) {
clientConfig.plugins.push(...await import('../chunks/analyze.mjs').then((r) => r.analyzePlugin(ctx)));
}
await ctx.nuxt.callHook("vite:extendConfig", clientConfig, { isClient: true, isServer: false });
if (ctx.nuxt.options.dev) {
const viteServer = await vite.createServer(clientConfig);
ctx.clientServer = viteServer;
await ctx.nuxt.callHook("vite:serverCreated", viteServer, { isClient: true, isServer: false });
const viteRoutes = viteServer.middlewares.stack.map((m) => m.route).filter((r) => r.length > 1);
const viteMiddleware = defineEventHandler(async (event) => {
const originalURL = event.node.req.url;
if (!viteRoutes.some((route) => originalURL.startsWith(route)) && !originalURL.startsWith(clientConfig.base)) {
event.node.req.url = joinURL("/__url", originalURL);
}
await new Promise((resolve2, reject) => {
viteServer.middlewares.handle(event.node.req, event.node.res, (err) => {
event.node.req.url = originalURL;
return err ? reject(err) : resolve2(null);
});
});
});
await ctx.nuxt.callHook("server:devHandler", viteMiddleware);
ctx.nuxt.hook("close", async () => {
await viteServer.close();
});
} else {
const start = Date.now();
await vite.build(clientConfig);
await ctx.nuxt.callHook("vite:compiled");
logger.info(`Client built in ${Date.now() - start}ms`);
}
}
function ssrStylesPlugin(options) {
const cssMap = {};
const idRefMap = {};
const relativeToSrcDir = (path) => relative(options.srcDir, path);
const warnCache = /* @__PURE__ */ new Set();
return {
name: "ssr-styles",
generateBundle(outputOptions) {
const emitted = {};
for (const file in cssMap) {
const { files, inBundle } = cssMap[file];
if (!files.length || !inBundle) {
continue;
}
const base = typeof outputOptions.assetFileNames === "string" ? outputOptions.assetFileNames : outputOptions.assetFileNames({
type: "asset",
name: `${filename(file)}-styles.mjs`,
source: ""
});
emitted[file] = this.emitFile({
type: "asset",
name: `${filename(file)}-styles.mjs`,
source: [
...files.map((css, i) => `import style_${i} from './${relative(dirname(base), this.getFileName(css))}';`),
`export default [${files.map((_, i) => `style_${i}`).join(", ")}]`
].join("\n")
});
}
for (const key in emitted) {
options.chunksWithInlinedCSS.add(key);
}
this.emitFile({
type: "asset",
fileName: "styles.mjs",
source: [
"const interopDefault = r => r.default || r || []",
`export default ${genObjectFromRawEntries(
Object.entries(emitted).map(([key, value]) => [key, `() => import('./${this.getFileName(value)}').then(interopDefault)`])
)}`
].join("\n")
});
},
renderChunk(_code, chunk) {
if (!chunk.facadeModuleId) {
return null;
}
const id = relativeToSrcDir(chunk.facadeModuleId);
for (const file in chunk.modules) {
const relativePath = relativeToSrcDir(file);
if (relativePath in cssMap) {
cssMap[relativePath].inBundle = cssMap[relativePath].inBundle ?? !!id;
}
}
return null;
},
async transform(code, id) {
const { pathname, search } = parseURL(decodeURIComponent(pathToFileURL(id).href));
const query = parseQuery(search);
if (!pathname.match(/\.(vue|((c|m)?j|t)sx?)$/g) || query.macro) {
return;
}
if (options.shouldInline && !options.shouldInline(id)) {
return;
}
const relativeId = relativeToSrcDir(id);
cssMap[relativeId] = cssMap[relativeId] || { files: [] };
let styleCtr = 0;
for (const i of findStaticImports(code)) {
const { type } = parseQuery(i.specifier);
if (type !== "style" && !i.specifier.endsWith(".css")) {
continue;
}
const resolved = await this.resolve(i.specifier, id);
if (!resolved) {
continue;
}
if (!await this.resolve(resolved.id + "?inline&used")) {
if (!warnCache.has(resolved.id)) {
warnCache.add(resolved.id);
this.warn(`[nuxt] Cannot extract styles for \`${i.specifier}\`. Its styles will not be inlined when server-rendering.`);
}
continue;
}
const ref = this.emitFile({
type: "chunk",
name: `${filename(id)}-styles-${++styleCtr}.mjs`,
id: resolved.id + "?inline&used"
});
idRefMap[relativeToSrcDir(resolved.id)] = ref;
cssMap[relativeId].files.push(ref);
}
}
};
}
async function writeManifest(ctx, css = []) {
const clientDist = resolve(ctx.nuxt.options.buildDir, "dist/client");
const serverDist = resolve(ctx.nuxt.options.buildDir, "dist/server");
const devClientManifest = {
"@vite/client": {
isEntry: true,
file: "@vite/client",
css,
module: true,
resourceType: "script"
},
[ctx.entry]: {
isEntry: true,
file: ctx.entry,
module: true,
resourceType: "script"
}
};
const clientManifest = ctx.nuxt.options.dev ? devClientManifest : await fse.readJSON(resolve(clientDist, "manifest.json"));
const buildAssetsDir = withTrailingSlash(withoutLeadingSlash(ctx.nuxt.options.app.buildAssetsDir));
const BASE_RE = new RegExp(`^${escapeRE(buildAssetsDir)}`);
for (const key in clientManifest) {
if (clientManifest[key].file) {
clientManifest[key].file = clientManifest[key].file.replace(BASE_RE, "");
}
for (const item of ["css", "assets"]) {
if (clientManifest[key][item]) {
clientManifest[key][item] = clientManifest[key][item].map((i) => i.replace(BASE_RE, ""));
}
}
}
await fse.mkdirp(serverDist);
const manifest = normalizeViteManifest(clientManifest);
await ctx.nuxt.callHook("build:manifest", manifest);
await fse.writeFile(resolve(serverDist, "client.manifest.json"), JSON.stringify(manifest, null, 2), "utf8");
await fse.writeFile(resolve(serverDist, "client.manifest.mjs"), "export default " + JSON.stringify(manifest, null, 2), "utf8");
if (!ctx.nuxt.options.dev) {
await fse.rm(resolve(clientDist, "manifest.json"), { force: true });
}
}
async function buildServer(ctx) {
const _resolve = (id) => resolveModule(id, { paths: ctx.nuxt.options.modulesDir });
const serverConfig = vite.mergeConfig(ctx.config, {
entry: ctx.entry,
base: ctx.nuxt.options.dev ? joinURL(ctx.nuxt.options.app.baseURL.replace(/^\.\//, "/") || "/", ctx.nuxt.options.app.buildAssetsDir) : void 0,
experimental: {
renderBuiltUrl: (filename, { type, hostType }) => {
if (hostType !== "js") {
return { relative: true };
}
if (type === "public") {
return { runtime: `globalThis.__publicAssetsURL(${JSON.stringify(filename)})` };
}
if (type === "asset") {
const relativeFilename = filename.replace(withTrailingSlash(withoutLeadingSlash(ctx.nuxt.options.app.buildAssetsDir)), "");
return { runtime: `globalThis.__buildAssetsURL(${JSON.stringify(relativeFilename)})` };
}
}
},
define: {
"process.server": true,
"process.client": false,
"typeof window": '"undefined"',
"typeof document": '"undefined"',
"typeof navigator": '"undefined"',
"typeof location": '"undefined"',
"typeof XMLHttpRequest": '"undefined"'
},
optimizeDeps: {
entries: [ctx.entry]
},
resolve: {
alias: {
"#build/plugins": resolve(ctx.nuxt.options.buildDir, "plugins/server"),
...ctx.nuxt.options.experimental.externalVue || ctx.nuxt.options.dev ? {} : {
"@vue/reactivity": _resolve(`@vue/reactivity/dist/reactivity.cjs${ctx.nuxt.options.dev ? "" : ".prod"}.js`),
"@vue/shared": _resolve(`@vue/shared/dist/shared.cjs${ctx.nuxt.options.dev ? "" : ".prod"}.js`),
"vue-router": _resolve(`vue-router/dist/vue-router.cjs${ctx.nuxt.options.dev ? "" : ".prod"}.js`),
"vue/server-renderer": _resolve("vue/server-renderer"),
"vue/compiler-sfc": _resolve("vue/compiler-sfc"),
vue: _resolve(`vue/dist/vue.cjs${ctx.nuxt.options.dev ? "" : ".prod"}.js`)
}
}
},
ssr: {
external: ctx.nuxt.options.experimental.externalVue ? ["#internal/nitro", "#internal/nitro/utils", "vue", "vue-router"] : ["#internal/nitro", "#internal/nitro/utils"],
noExternal: [
...ctx.nuxt.options.build.transpile,
/\/esm\/.*\.js$/,
/\.(es|esm|esm-browser|esm-bundler).js$/,
"/__vue-jsx",
"#app",
/^nuxt(\/|$)/,
/(nuxt|nuxt3)\/(dist|src|app)/
]
},
build: {
sourcemap: ctx.nuxt.options.sourcemap.server ? ctx.config.build?.sourcemap ?? true : false,
outDir: resolve(ctx.nuxt.options.buildDir, "dist/server"),
ssr: ctx.nuxt.options.ssr ?? true,
rollupOptions: {
input: ctx.entry,
external: ["#internal/nitro", ...ctx.nuxt.options.experimental.externalVue ? ["vue", "vue-router"] : []],
output: {
entryFileNames: "server.mjs",
preferConst: true,
inlineDynamicImports: !ctx.nuxt.options.experimental.viteServerDynamicImports,
format: "module"
},
onwarn(warning, rollupWarn) {
if (warning.code && ["UNUSED_EXTERNAL_IMPORT"].includes(warning.code)) {
return;
}
rollupWarn(warning);
}
}
},
server: {
preTransformRequests: false,
hmr: false
},
plugins: [
cacheDirPlugin(ctx.nuxt.options.rootDir, "server"),
vuePlugin(ctx.config.vue),
viteJsxPlugin()
]
});
if (ctx.nuxt.options.experimental.inlineSSRStyles) {
const chunksWithInlinedCSS = /* @__PURE__ */ new Set();
serverConfig.plugins.push(ssrStylesPlugin({
srcDir: ctx.nuxt.options.srcDir,
chunksWithInlinedCSS,
shouldInline: typeof ctx.nuxt.options.experimental.inlineSSRStyles === "function" ? ctx.nuxt.options.experimental.inlineSSRStyles : void 0
}));
ctx.nuxt.hook("build:manifest", (manifest) => {
for (const key in manifest) {
const entry = manifest[key];
const shouldRemoveCSS = chunksWithInlinedCSS.has(key);
if (shouldRemoveCSS) {
entry.css = [];
}
}
});
}
await ctx.nuxt.callHook("vite:extendConfig", serverConfig, { isClient: false, isServer: true });
const onBuild = () => ctx.nuxt.callHook("vite:compiled");
if (!ctx.nuxt.options.dev) {
const start = Date.now();
logger.info("Building server...");
await vite.build(serverConfig);
await writeManifest(ctx);
await onBuild();
logger.success(`Server built in ${Date.now() - start}ms`);
return;
}
await writeManifest(ctx);
if (!ctx.nuxt.options.ssr) {
await onBuild();
return;
}
const viteServer = await vite.createServer(serverConfig);
ctx.ssrServer = viteServer;
await ctx.nuxt.callHook("vite:serverCreated", viteServer, { isClient: false, isServer: true });
ctx.nuxt.hook("close", () => viteServer.close());
await viteServer.pluginContainer.buildStart({});
if (ctx.config.devBundler !== "legacy") {
await initViteNodeServer(ctx);
} else {
logger.info("Vite server using legacy server bundler...");
await import('../chunks/dev-bundler.mjs').then((r) => r.initViteDevBundler(ctx, onBuild));
}
}
const PREFIX = "virtual:nuxt:";
function virtual(vfs) {
const extensions = ["", ".ts", ".vue", ".mjs", ".cjs", ".js", ".json"];
const resolveWithExt = (id) => {
for (const ext of extensions) {
const rId = id + ext;
if (rId in vfs) {
return rId;
}
}
return null;
};
return {
name: "virtual",
resolveId(id, importer) {
if (process.platform === "win32" && isAbsolute(id)) {
id = resolve(id);
}
const resolvedId = resolveWithExt(id);
if (resolvedId) {
return PREFIX + resolvedId;
}
if (importer && !isAbsolute(id)) {
const importerNoPrefix = importer.startsWith(PREFIX) ? importer.slice(PREFIX.length) : importer;
const importedDir = dirname(importerNoPrefix);
const resolved = resolveWithExt(join(importedDir, id));
if (resolved) {
return PREFIX + resolved;
}
}
return null;
},
load(id) {
if (!id.startsWith(PREFIX)) {
return null;
}
const idNoPrefix = id.slice(PREFIX.length);
if (idNoPrefix in vfs) {
return {
code: vfs[idNoPrefix],
map: null
};
}
}
};
}
async function warmupViteServer(server, entries, isServer) {
const warmedUrls = /* @__PURE__ */ new Set();
const warmup = async (url) => {
if (warmedUrls.has(url)) {
return;
}
warmedUrls.add(url);
try {
await server.transformRequest(url, { ssr: isServer });
} catch (e) {
logger.debug("Warmup for %s failed with: %s", url, e);
}
const mod = await server.moduleGraph.getModuleByUrl(url, isServer);
const deps = mod?.ssrTransformResult?.deps || Array.from(mod?.importedModules || []).map((m) => m.url);
await Promise.all(deps.map((m) => warmup(m.replace("/@id/__x00__", "\0"))));
};
await Promise.all(entries.map((entry) => warmup(entry)));
}
function resolveCSSOptions(nuxt) {
const css = {
postcss: {
plugins: []
}
};
const lastPlugins = ["autoprefixer", "cssnano"];
css.postcss.plugins = Object.entries(nuxt.options.postcss.plugins).sort((a, b) => lastPlugins.indexOf(a[0]) - lastPlugins.indexOf(b[0])).filter(([, opts]) => opts).map(([name, opts]) => {
const plugin = requireModule(name, {
paths: [
...nuxt.options.modulesDir,
distDir
]
});
return plugin(opts);
});
return css;
}
const keyedFunctions = [
"useState",
"useFetch",
"useAsyncData",
"useLazyAsyncData",
"useLazyFetch"
];
const KEYED_FUNCTIONS_RE = new RegExp(`(${keyedFunctions.join("|")})`);
const stringTypes = ["Literal", "TemplateLiteral"];
const composableKeysPlugin = createUnplugin((options) => {
return {
name: "nuxt:composable-keys",
enforce: "post",
transformInclude(id) {
const { pathname, search } = parseURL(decodeURIComponent(pathToFileURL(id).href));
return !pathname.match(/node_modules\/nuxt3?\//) && pathname.match(/\.(m?[jt]sx?|vue)/) && parseQuery(search).type !== "style" && !parseQuery(search).macro;
},
transform(code, id) {
if (!KEYED_FUNCTIONS_RE.test(code)) {
return;
}
const { 0: script = code, index: codeIndex = 0 } = code.match(/(?<=<script[^>]*>)[\S\s.]*?(?=<\/script>)/) || { index: 0, 0: code };
const s = new MagicString(code);
let count = 0;
const relativeID = isAbsolute(id) ? relative(options.rootDir, id) : id;
walk(this.parse(script, {
sourceType: "module",
ecmaVersion: "latest"
}), {
enter(_node) {
if (_node.type !== "CallExpression" || _node.callee.type !== "Identifier") {
return;
}
const node = _node;
const name = "name" in node.callee && node.callee.name;
if (!name || !keyedFunctions.includes(name) || node.arguments.length >= 4) {
return;
}
switch (name) {
case "useState":
if (node.arguments.length >= 2 || stringTypes.includes(node.arguments[0]?.type)) {
return;
}
break;
case "useFetch":
case "useLazyFetch":
if (node.arguments.length >= 3 || stringTypes.includes(node.arguments[1]?.type)) {
return;
}
break;
case "useAsyncData":
case "useLazyAsyncData":
if (node.arguments.length >= 3 || stringTypes.includes(node.arguments[0]?.type) || stringTypes.includes(node.arguments[node.arguments.length - 1]?.type)) {
return;
}
break;
}
const endsWithComma = code.slice(codeIndex + node.start, codeIndex + node.end - 1).trim().endsWith(",");
s.appendLeft(
codeIndex + node.end - 1,
(node.arguments.length && !endsWithComma ? ", " : "") + "'$" + hash(`${relativeID}-${++count}`) + "'"
);
}
});
if (s.hasChanged()) {
return {
code: s.toString(),
map: options.sourcemap ? s.generateMap({ source: id, includeContent: true }) : void 0
};
}
}
};
});
async function bundle(nuxt) {
const useAsyncEntry = nuxt.options.experimental.asyncEntry || nuxt.options.vite.devBundler === "vite-node" && nuxt.options.dev;
const entry = await resolvePath(resolve(nuxt.options.appDir, useAsyncEntry ? "entry.async" : "entry"));
const ctx = {
nuxt,
entry,
config: vite.mergeConfig(
{
resolve: {
alias: {
...nuxt.options.alias,
"#app": nuxt.options.appDir,
"#build/plugins": "",
"#build": nuxt.options.buildDir,
"web-streams-polyfill/ponyfill/es2018": "unenv/runtime/mock/empty",
"abort-controller": "unenv/runtime/mock/empty"
}
},
optimizeDeps: {
include: ["vue"]
},
css: resolveCSSOptions(nuxt),
build: {
rollupOptions: {
output: {
sanitizeFileName: sanitizeFilePath,
assetFileNames: nuxt.options.dev ? void 0 : (chunk) => withoutLeadingSlash(join(nuxt.options.app.buildAssetsDir, `${sanitizeFilePath(filename(chunk.name))}.[hash].[ext]`))
}
},
watch: {
exclude: nuxt.options.ignore
}
},
plugins: [
composableKeysPlugin.vite({ sourcemap: nuxt.options.sourcemap.server || nuxt.options.sourcemap.client, rootDir: nuxt.options.rootDir }),
replace({
...Object.fromEntries([";", "(", "{", "}", " ", " ", "\n"].map((d) => [`${d}global.`, `${d}globalThis.`])),
preventAssignment: true
}),
virtual(nuxt.vfs)
],
vue: {
reactivityTransform: nuxt.options.experimental.reactivityTransform
},
server: {
watch: { ignored: isIgnored },
fs: {
allow: [
nuxt.options.appDir,
...nuxt.options._layers.map((l) => l.config.rootDir)
]
}
}
},
nuxt.options.vite
)
};
if (!nuxt.options.dev) {
ctx.config.server.watch = void 0;
ctx.config.build.watch = void 0;
}
await nuxt.callHook("vite:extend", ctx);
if (ctx.nuxt.options.typescript.typeCheck === true || ctx.nuxt.options.typescript.typeCheck === "build" && !ctx.nuxt.options.dev) {
const checker = await import('vite-plugin-checker').then((r) => r.default);
addVitePlugin(checker({
vueTsc: {
tsconfigPath: await resolveTSConfig(ctx.nuxt.options.rootDir)
}
}), { client: !nuxt.options.ssr, server: nuxt.options.ssr });
}
nuxt.hook("vite:serverCreated", (server, env) => {
ctx.nuxt.hook("app:templatesGenerated", () => {
for (const [id, mod] of server.moduleGraph.idToModuleMap) {
if (id.startsWith("virtual:")) {
server.moduleGraph.invalidateModule(mod);
}
}
});
if (nuxt.options.vite.warmupEntry !== false && !(env.isServer && ctx.nuxt.options.vite.devBundler !== "legacy")) {
const start = Date.now();
warmupViteServer(server, [join("/@fs/", ctx.entry)], env.isServer).then(() => logger.info(`Vite ${env.isClient ? "client" : "server"} warmed up in ${Date.now() - start}ms`)).catch(logger.error);
}
});
await buildClient(ctx);
await buildServer(ctx);
}
export { bundle as b, createIsExternal as c, hashId as h, isCSS as i, uniq as u, writeManifest as w };