Website Structure

This commit is contained in:
supalerk-ar66 2026-01-13 10:46:40 +07:00
parent 62812f2090
commit 71f0676a62
22365 changed files with 4265753 additions and 791 deletions

View file

@ -0,0 +1,58 @@
import { addVitePlugin } from '@nuxt/kit';
import { resolve, join } from 'pathe';
import { readdir, lstat } from 'node:fs/promises';
import { createVitePluginInspect } from './vite-inspect.mjs';
import '@nuxt/devtools-kit';
async function getFolderSize(dir) {
const dirents = await readdir(dir, {
withFileTypes: true
});
if (dirents.length === 0)
return 0;
const files = [];
const directorys = [];
for (const dirent of dirents) {
if (dirent.isFile()) {
files.push(dirent);
continue;
}
if (dirent.isDirectory())
directorys.push(dirent);
}
const sizes = await Promise.all(
[
files.map(async (file) => {
const path = resolve(dir, file.name);
const { size } = await lstat(path);
return size;
}),
directorys.map((directory) => {
const path = resolve(dir, directory.name);
return getFolderSize(path);
})
].flat()
);
return sizes.reduce((total, size) => total += size, 0);
}
async function setup(nuxt, options) {
if (options.viteInspect !== false) {
addVitePlugin(
await createVitePluginInspect({
build: true,
outputDir: join(nuxt.options.analyzeDir, ".vite-inspect")
})
);
}
nuxt.hook("build:analyze:done", async (meta) => {
const _meta = meta;
_meta.size = _meta.size || {};
const dirs = [join(meta.buildDir, "dist/client"), meta.outDir];
const [clientBundleSize, nitroBundleSize] = await Promise.all(dirs.map(getFolderSize));
_meta.size.clientBundle = clientBundleSize;
_meta.size.nitroBundle = nitroBundleSize;
});
}
export { setup };

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,68 @@
function setup({ nuxt }) {
if (!nuxt.options.dev || nuxt.options.test)
return;
nuxt.hook("app:templates", (app) => {
app.templates.filter((i) => i.filename?.startsWith("plugins/")).forEach((i) => {
if (!i.getContents)
return;
const original = i.getContents;
i.getContents = async (...args) => {
let content = await original(...args);
const PAYLOAD_KEY = "__NUXT_DEVTOOLS_PLUGINS_METRIC__";
const WRAPPER_KEY = "__DEVTOOLS_WRAPPER__";
if (content.includes(PAYLOAD_KEY))
return content;
const snippets = `
if (!globalThis.${PAYLOAD_KEY}) {
Object.defineProperty(globalThis, '${PAYLOAD_KEY}', {
value: [],
enumerable: false,
configurable: true,
})
}
function ${WRAPPER_KEY} (plugin, src) {
if (!plugin)
return plugin
return defineNuxtPlugin({
...plugin,
async setup (...args) {
const start = performance.now()
const result = await plugin.apply(this, args)
const end = performance.now()
globalThis.${PAYLOAD_KEY}.push({
src,
start,
end,
duration: end - start,
})
return result
}
})
}
`;
const imports = Array.from(content.matchAll(/(?:\n|^)import (.*) from ['"](.*)['"]/g)).map(([, name, path]) => ({ name, path }));
content = content.replace(/\nexport default\s*\[([\s\S]*)\]/, (_, itemsRaw) => {
const items = itemsRaw.split(",").map((i2) => i2.trim()).map((i2) => {
const importItem = imports.find(({ name }) => name === i2);
if (!importItem)
return i2;
return `${WRAPPER_KEY}(${i2}, ${JSON.stringify(importItem.path)})`;
});
return `
${snippets}
export default [
${items.join(",\n")}
]
`;
});
content = `import { defineNuxtPlugin } from "#imports"
${content}`;
return content;
};
});
});
}
export { setup };

View file

@ -0,0 +1,73 @@
import { resolve } from 'pathe';
import semver from 'semver';
import { runtimeDir } from '../dirs.mjs';
import 'node:path';
import 'node:url';
import 'is-installed-globally';
function setup({ nuxt, options }) {
const helperPath = resolve(runtimeDir, "function-metrics-helpers");
const includeFrom = options.timeline?.functions?.includeFrom || [
"#app",
"@unhead/vue"
];
const include = options.timeline?.functions?.include || [
(i) => includeFrom.includes(i.from),
(i) => i.from.includes("composables")
];
const exclude = options.timeline?.functions?.exclude || [
/^define[A-Z]/
];
function filter(item) {
if (item.type)
return false;
const name = item.as || item.name;
if (!include.some((f) => typeof f === "function" ? f(item) : typeof f === "string" ? name === f : f.test(name)))
return false;
if (exclude.some((f) => typeof f === "function" ? f(item) : typeof f === "string" ? name === f : f.test(name)))
return false;
return true;
}
nuxt.hook("imports:context", (unimport) => {
const ctx = unimport.getInternalContext();
if (!ctx.version || !semver.gte(ctx.version, "3.1.0"))
throw new Error(`[Nuxt DevTools] The timeline feature requires \`unimport\` >= v3.1.0, but got \`${ctx.version || "(unknown)"}\`. Please upgrade using \`nuxi upgrade --force\`.`);
ctx.addons.push(
{
injectImportsResolved(imports, _code, id) {
if (id?.includes("?macro=true"))
return;
return imports.map((i) => {
if (!filter(i))
return i;
const name = i.as || i.name;
return {
...i,
meta: {
wrapperOriginalAs: name
},
as: `_$__${name}`
};
});
},
injectImportsStringified(str, imports, s, id) {
if (id?.includes("?macro=true"))
return;
const code = s.toString();
const injected = imports.filter((i) => i.meta?.wrapperOriginalAs);
if (injected.length) {
const result = [
str,
code.includes("__nuxtTimelineWrap") ? "" : `import { __nuxtTimelineWrap } from ${JSON.stringify(helperPath)}`,
...injected.map((i) => `const ${i.meta.wrapperOriginalAs} = __nuxtTimelineWrap(${JSON.stringify(i.name)}, ${i.as})`),
""
].join(";");
return result;
}
}
}
);
});
}
export { setup };

View file

@ -0,0 +1,61 @@
import { addCustomTab } from '@nuxt/devtools-kit';
import { addVitePlugin } from '@nuxt/kit';
async function createVitePluginInspect(options) {
return await import('vite-plugin-inspect').then((r) => r.default(options));
}
async function setup({ nuxt, rpc }) {
const plugin = await createVitePluginInspect();
addVitePlugin(plugin);
let api;
nuxt.hook("vite:serverCreated", () => {
api = plugin.api;
});
addCustomTab(() => ({
name: "builtin-vite-inspect",
title: "Inspect",
icon: "carbon-ibm-watson-discovery",
category: "advanced",
view: {
type: "iframe",
src: `${nuxt.options.app.baseURL}${nuxt.options.app.buildAssetsDir}/__inspect/`.replace(/\/\//g, "/")
}
}), nuxt);
async function getComponentsRelationships() {
const meta = await api?.rpc.getMetadata();
const modules = (meta && meta.instances[0] ? await api?.rpc.getModulesList({
vite: meta.instances[0].vite,
env: meta.instances[0].environments[0]
}) : null) || [];
const components = await rpc.functions.getComponents() || [];
const vueModules = modules.filter((m) => {
const plainId = m.id.replace(/\?v=\w+$/, "");
if (components.some((c) => c.filePath === plainId))
return true;
return m.id.match(/\.vue($|\?v=)/);
});
const graph = vueModules.map((i) => {
function searchForVueDeps(id, seen = /* @__PURE__ */ new Set()) {
if (seen.has(id))
return [];
seen.add(id);
const module = modules.find((m) => m.id === id);
if (!module)
return [];
return module.deps.flatMap((i2) => {
if (vueModules.find((m) => m.id === i2))
return [i2];
return searchForVueDeps(i2, seen);
});
}
return {
id: i.id,
deps: searchForVueDeps(i.id)
};
});
return graph;
}
rpc.functions.getComponentsRelationships = getComponentsRelationships;
}
export { createVitePluginInspect, setup };

View file

@ -0,0 +1,196 @@
import { existsSync } from 'node:fs';
import fsp from 'node:fs/promises';
import { hostname } from 'node:os';
import { resolve } from 'node:path';
import { startSubprocess } from '@nuxt/devtools-kit';
import { logger } from '@nuxt/kit';
import { execa } from 'execa';
import { checkPort, getPort } from 'get-port-please';
import which from 'which';
import { L as LOG_PREFIX } from './module-main.mjs';
import 'consola/utils';
import 'pathe';
import 'sirv';
import 'vite';
import '../shared/devtools.DuFZOCNN.mjs';
import '../dirs.mjs';
import 'node:url';
import 'is-installed-globally';
import 'ohash';
import 'birpc';
import 'structured-clone-es';
import 'simple-git';
import 'tinyglobby';
import 'image-meta';
import 'perfect-debounce';
import 'destr';
import '../../dist/runtime/shared/hooks.js';
import 'node:process';
import 'node:module';
import 'pkg-types';
import 'node:assert';
import 'node:v8';
import 'node:util';
import 'local-pkg';
import 'magicast';
import 'magicast/helpers';
import 'nypm';
import 'semver';
const codeBinaryOptions = {
"ms-code-cli": {
codeBinary: "code",
launchArg: "serve-web",
licenseTermsArg: "--accept-server-license-terms",
connectionTokenArg: "--without-connection-token"
},
"ms-code-server": {
codeBinary: "code-server",
launchArg: "serve-local",
licenseTermsArg: "--accept-server-license-terms",
connectionTokenArg: "--without-connection-token"
},
"coder-code-server": {
codeBinary: "code-server",
launchArg: "serve-local",
licenseTermsArg: "",
connectionTokenArg: ""
}
};
async function setup({ nuxt, options, openInEditorHooks, rpc }) {
const vsOptions = options?.vscode || {};
const codeServer = vsOptions?.codeServer || "ms-code-server";
const { codeBinary, launchArg, licenseTermsArg, connectionTokenArg } = codeBinaryOptions[codeServer];
const installed = !!await which(codeBinary).catch(() => null);
let port = vsOptions?.port || 3080;
let url = `http://localhost:${port}`;
const host = vsOptions?.host ? `--host=${vsOptions.host}` : "--host=127.0.0.1";
let loaded = false;
let promise = null;
const mode = vsOptions?.mode || "local-serve";
const computerHostName = vsOptions.tunnel?.name || hostname().split(".").join("");
const root = nuxt.options.rootDir;
const vscodeServerControllerFile = resolve(root, ".vscode", ".server-controller-port.log");
openInEditorHooks.push(async (file) => {
if (!existsSync(vscodeServerControllerFile))
return false;
try {
const { port: port2 } = JSON.parse(await fsp.readFile(vscodeServerControllerFile, "utf-8"));
const url2 = `http://localhost:${port2}/open?path=${encodeURIComponent(`${root}/${file}`)}`;
await fetch(url2);
rpc.broadcast.navigateTo("/modules/custom-builtin-vscode");
return true;
} catch (e) {
console.debug(`Failed to open file "${file}" in VS Code Server`);
console.debug(e);
return false;
}
});
async function startCodeServer() {
if (existsSync(vscodeServerControllerFile))
await fsp.rm(vscodeServerControllerFile, { force: true });
if (vsOptions?.reuseExistingServer && !await checkPort(port)) {
loaded = true;
url = `http://localhost:${port}/?folder=${encodeURIComponent(root)}`;
logger.info(LOG_PREFIX, `Existing VS Code Server found at port ${port}...`);
return;
}
port = await getPort({ port });
url = `http://localhost:${port}/?folder=${encodeURIComponent(root)}`;
logger.info(LOG_PREFIX, `Starting VS Code Server at ${url} ...`);
execa(codeBinary, [
"--install-extension",
"antfu.vscode-server-controller"
], { stderr: "inherit", stdout: "ignore", reject: false });
startSubprocess(
{
command: codeBinary,
args: [
launchArg,
licenseTermsArg,
connectionTokenArg,
`--port=${port}`,
host
]
},
{
id: "devtools:vscode",
name: "VS Code Server",
icon: "logos-visual-studio-code"
},
nuxt
);
for (let i = 0; i < 100; i++) {
if (await fetch(url).then((r) => r.ok).catch(() => false))
break;
await new Promise((resolve2) => setTimeout(resolve2, 500));
}
await new Promise((resolve2) => setTimeout(resolve2, 2e3));
loaded = true;
}
async function startCodeTunnel() {
const { stdout: currentDir } = await execa("pwd");
url = `https://vscode.dev/tunnel/${computerHostName}${currentDir}`;
logger.info(LOG_PREFIX, `Starting VS Code tunnel at ${url} ...`);
const command = execa("code", [
"tunnel",
"--accept-server-license-terms",
"--name",
`${computerHostName}`
]);
command.stderr?.pipe(process.stderr);
command.stdout?.pipe(process.stdout);
nuxt.hook("close", () => {
command.kill();
});
for (let i = 0; i < 100; i++) {
if (await fetch(url).then((r) => r.ok).catch(() => false))
break;
await new Promise((resolve2) => setTimeout(resolve2, 500));
}
await new Promise((resolve2) => setTimeout(resolve2, 2e3));
loaded = true;
}
async function start() {
if (mode === "tunnel")
await startCodeTunnel();
else
await startCodeServer();
}
nuxt.hook("devtools:customTabs", (tabs) => {
tabs.push({
name: "builtin-vscode",
title: "VS Code",
icon: "bxl-visual-studio",
category: "modules",
requireAuth: true,
view: !installed && !(vsOptions?.mode === "tunnel") ? {
type: "launch",
title: "Install VS Code Server",
description: `It seems you don't have code-server installed.
Learn more about it with <a href="https://code.visualstudio.com/blogs/2022/07/07/vscode-server" target="_blank">this guide</a>.
Once installed, restart Nuxt and visit this tab again.`,
actions: []
} : !loaded ? {
type: "launch",
description: "Launch VS Code right in the devtools!",
actions: [{
label: promise ? "Starting..." : "Launch",
pending: !!promise,
handle: () => {
promise = promise || start();
return promise;
}
}]
} : {
type: "iframe",
src: url
}
});
});
if (vsOptions?.startOnBoot)
promise = promise || start();
}
export { setup };

View file

@ -0,0 +1,19 @@
import { addPluginTemplate, resolvePath } from '@nuxt/kit';
import { join } from 'pathe';
import { runtimeDir } from '../dirs.mjs';
import 'node:path';
import 'node:url';
import 'is-installed-globally';
async function setup({ nuxt }) {
if (!nuxt.options.dev || nuxt.options.test)
return;
addPluginTemplate({
name: "vue-devtools-client",
mode: "client",
order: -1e3,
src: await resolvePath(join(runtimeDir, "vue-devtools-client"))
});
}
export { setup };

View file

@ -0,0 +1,14 @@
import { addVitePlugin } from '@nuxt/kit';
import { VueTracer } from 'vite-plugin-vue-tracer';
function setup({ nuxt, options }) {
if (!nuxt.options.dev || nuxt.options.test)
return;
if (!options.componentInspector)
return;
const plugin = VueTracer();
if (plugin)
addVitePlugin(plugin);
}
export { setup };