@sigx/ssg 0.2.1 → 0.2.3
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/dist/build-DP9zez3B.js +254 -0
- package/dist/{build-qmtK32gt.js.map → build-DP9zez3B.js.map} +1 -1
- package/dist/build.js +2 -2
- package/dist/cli.js +5 -0
- package/dist/cli.js.map +2 -2
- package/dist/client.js +21 -38
- package/dist/client.js.map +1 -1
- package/dist/dev.js +38 -58
- package/dist/dev.js.map +1 -1
- package/dist/index.js +17 -53
- package/dist/index.js.map +1 -1
- package/dist/plugin-EIAzPLvE.js +446 -0
- package/dist/{plugin-Bik0HMne.js.map → plugin-EIAzPLvE.js.map} +1 -1
- package/dist/virtual-entries-CH-0HuqJ.js +904 -0
- package/dist/{virtual-entries-TuNN2It1.js.map → virtual-entries-CH-0HuqJ.js.map} +1 -1
- package/dist/vite/plugin.js +2 -2
- package/dist/vite/virtual-entries.d.ts.map +1 -1
- package/package.json +4 -4
- package/dist/build-qmtK32gt.js +0 -385
- package/dist/plugin-Bik0HMne.js +0 -632
- package/dist/virtual-entries-TuNN2It1.js +0 -1298
package/dist/build-qmtK32gt.js
DELETED
|
@@ -1,385 +0,0 @@
|
|
|
1
|
-
import { A as resolveConfigPaths, C as extractParams, S as expandDynamicRoute, T as scanPages, k as loadConfig, l as generateProductionHtmlTemplate, m as discoverLayouts, o as detectCustomEntries, s as generateClientEntry, u as generateServerEntry, w as isDynamicRoute } from "./virtual-entries-TuNN2It1.js";
|
|
2
|
-
import path from "node:path";
|
|
3
|
-
import fs from "node:fs/promises";
|
|
4
|
-
import fsSync from "node:fs";
|
|
5
|
-
import { pathToFileURL } from "node:url";
|
|
6
|
-
//#region src/sitemap.ts
|
|
7
|
-
/**
|
|
8
|
-
* Sitemap Generation
|
|
9
|
-
*
|
|
10
|
-
* Generates XML sitemaps for SSG sites following the sitemap protocol.
|
|
11
|
-
* https://www.sitemaps.org/protocol.html
|
|
12
|
-
*/
|
|
13
|
-
/**
|
|
14
|
-
* Generate sitemap XML content
|
|
15
|
-
*/
|
|
16
|
-
function generateSitemap(entries, config) {
|
|
17
|
-
const siteUrl = config.site?.url?.replace(/\/$/, "") || "";
|
|
18
|
-
const base = config.base?.replace(/\/$/, "") || "";
|
|
19
|
-
return `<?xml version="1.0" encoding="UTF-8"?>
|
|
20
|
-
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
|
|
21
|
-
${entries.map((entry) => {
|
|
22
|
-
const loc = `${siteUrl}${base}${entry.path}`;
|
|
23
|
-
const lastmod = entry.lastmod ? typeof entry.lastmod === "string" ? entry.lastmod : entry.lastmod.toISOString().split("T")[0] : void 0;
|
|
24
|
-
return ` <url>
|
|
25
|
-
<loc>${escapeXml(loc)}</loc>${lastmod ? `
|
|
26
|
-
<lastmod>${lastmod}</lastmod>` : ""}${entry.changefreq ? `
|
|
27
|
-
<changefreq>${entry.changefreq}</changefreq>` : ""}${entry.priority !== void 0 ? `
|
|
28
|
-
<priority>${entry.priority.toFixed(1)}</priority>` : ""}
|
|
29
|
-
</url>`;
|
|
30
|
-
}).join("\n")}
|
|
31
|
-
</urlset>`;
|
|
32
|
-
}
|
|
33
|
-
/**
|
|
34
|
-
* Generate robots.txt content
|
|
35
|
-
*/
|
|
36
|
-
function generateRobotsTxt(config, sitemapPath = "/sitemap.xml") {
|
|
37
|
-
return `User-agent: *
|
|
38
|
-
Allow: /
|
|
39
|
-
|
|
40
|
-
Sitemap: ${config.site?.url?.replace(/\/$/, "") || ""}${config.base?.replace(/\/$/, "") || ""}${sitemapPath}
|
|
41
|
-
`;
|
|
42
|
-
}
|
|
43
|
-
/**
|
|
44
|
-
* Convert page build results to sitemap entries
|
|
45
|
-
*/
|
|
46
|
-
function pagesToSitemapEntries(pages, options = {}) {
|
|
47
|
-
const { exclude = [], defaultChangefreq = "weekly", defaultPriority = .5 } = options;
|
|
48
|
-
return pages.filter((page) => {
|
|
49
|
-
for (const pattern of exclude) if (pattern.includes("*")) {
|
|
50
|
-
if (new RegExp("^" + pattern.replace(/\*/g, ".*").replace(/\?/g, ".") + "$").test(page.path)) return false;
|
|
51
|
-
} else if (page.path === pattern) return false;
|
|
52
|
-
return true;
|
|
53
|
-
}).map((page) => {
|
|
54
|
-
const depth = page.path.split("/").filter(Boolean).length;
|
|
55
|
-
let priority = defaultPriority;
|
|
56
|
-
if (page.path === "/") priority = 1;
|
|
57
|
-
else if (depth === 1) priority = .8;
|
|
58
|
-
else if (depth === 2) priority = .6;
|
|
59
|
-
return {
|
|
60
|
-
path: page.path,
|
|
61
|
-
changefreq: defaultChangefreq,
|
|
62
|
-
priority
|
|
63
|
-
};
|
|
64
|
-
});
|
|
65
|
-
}
|
|
66
|
-
/**
|
|
67
|
-
* Write sitemap and robots.txt to output directory
|
|
68
|
-
*/
|
|
69
|
-
async function writeSitemap(pages, config, outDir, options = {}) {
|
|
70
|
-
const entries = pagesToSitemapEntries(pages, options);
|
|
71
|
-
if (options.additionalUrls) entries.push(...options.additionalUrls);
|
|
72
|
-
const sitemapContent = generateSitemap(entries, config);
|
|
73
|
-
const sitemapPath = path.join(outDir, "sitemap.xml");
|
|
74
|
-
await fs.writeFile(sitemapPath, sitemapContent, "utf-8");
|
|
75
|
-
const robotsContent = generateRobotsTxt(config);
|
|
76
|
-
const robotsPath = path.join(outDir, "robots.txt");
|
|
77
|
-
await fs.writeFile(robotsPath, robotsContent, "utf-8");
|
|
78
|
-
return {
|
|
79
|
-
sitemapPath,
|
|
80
|
-
robotsPath
|
|
81
|
-
};
|
|
82
|
-
}
|
|
83
|
-
/**
|
|
84
|
-
* Escape special XML characters
|
|
85
|
-
*/
|
|
86
|
-
function escapeXml(str) {
|
|
87
|
-
return str.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'");
|
|
88
|
-
}
|
|
89
|
-
//#endregion
|
|
90
|
-
//#region src/build.ts
|
|
91
|
-
/**
|
|
92
|
-
* SSG Build CLI
|
|
93
|
-
*
|
|
94
|
-
* Static site generation build process:
|
|
95
|
-
* 1. Load configuration
|
|
96
|
-
* 2. Scan routes and expand dynamic paths
|
|
97
|
-
* 3. Build with Vite for production
|
|
98
|
-
* 4. Render each route to static HTML
|
|
99
|
-
* 5. Write output files
|
|
100
|
-
* 6. Generate sitemap and robots.txt
|
|
101
|
-
*/
|
|
102
|
-
/**
|
|
103
|
-
* Build static site
|
|
104
|
-
*/
|
|
105
|
-
async function build(options = {}) {
|
|
106
|
-
const startTime = Date.now();
|
|
107
|
-
const root = process.cwd();
|
|
108
|
-
const warnings = [];
|
|
109
|
-
const pages = [];
|
|
110
|
-
console.log("\n🚀 @sigx/ssg - Building static site...\n");
|
|
111
|
-
console.log("📦 Loading configuration...");
|
|
112
|
-
const resolvedConfig = resolveConfigPaths(await loadConfig(options.configPath), root);
|
|
113
|
-
console.log("🔍 Scanning pages...");
|
|
114
|
-
const routes = await scanPages(resolvedConfig, root);
|
|
115
|
-
console.log(` Found ${routes.length} page(s)`);
|
|
116
|
-
console.log("📐 Discovering layouts...");
|
|
117
|
-
const layouts = await discoverLayouts(resolvedConfig, root);
|
|
118
|
-
console.log(` Found ${layouts.length} layout(s)`);
|
|
119
|
-
const entryDetection = detectCustomEntries(root, resolvedConfig);
|
|
120
|
-
if (entryDetection.useVirtualClient || entryDetection.useVirtualServer) {
|
|
121
|
-
console.log("📦 Using zero-config mode");
|
|
122
|
-
if (entryDetection.useVirtualClient) console.log(" → Virtual client entry");
|
|
123
|
-
if (entryDetection.useVirtualServer) console.log(" → Virtual server entry");
|
|
124
|
-
if (entryDetection.useVirtualHtml) console.log(" → Virtual HTML template");
|
|
125
|
-
}
|
|
126
|
-
const clientEntry = await getClientEntryPoint(resolvedConfig, root);
|
|
127
|
-
const ssrEntry = await getSSREntryPoint(resolvedConfig, root);
|
|
128
|
-
const htmlTemplatePath = path.join(root, "index.html");
|
|
129
|
-
let cleanupHtml = false;
|
|
130
|
-
let originalHtmlContent = null;
|
|
131
|
-
if (!entryDetection.useVirtualHtml && fsSync.existsSync(htmlTemplatePath)) originalHtmlContent = fsSync.readFileSync(htmlTemplatePath, "utf-8");
|
|
132
|
-
const htmlContent = await getHtmlTemplate(resolvedConfig, root, clientEntry);
|
|
133
|
-
fsSync.writeFileSync(htmlTemplatePath, htmlContent, "utf-8");
|
|
134
|
-
cleanupHtml = entryDetection.useVirtualHtml;
|
|
135
|
-
console.log("🔨 Building with Vite...");
|
|
136
|
-
const vite = await import("vite");
|
|
137
|
-
try {
|
|
138
|
-
const clientInput = htmlTemplatePath;
|
|
139
|
-
await vite.build({
|
|
140
|
-
root,
|
|
141
|
-
mode: "production",
|
|
142
|
-
build: {
|
|
143
|
-
outDir: resolvedConfig.outDir,
|
|
144
|
-
emptyOutDir: false,
|
|
145
|
-
ssrManifest: true,
|
|
146
|
-
rollupOptions: { input: clientInput }
|
|
147
|
-
},
|
|
148
|
-
logLevel: options.verbose ? "info" : "warn"
|
|
149
|
-
});
|
|
150
|
-
const ssrOutDir = path.join(resolvedConfig.outDir, ".ssg");
|
|
151
|
-
await vite.build({
|
|
152
|
-
root,
|
|
153
|
-
mode: "production",
|
|
154
|
-
build: {
|
|
155
|
-
outDir: ssrOutDir,
|
|
156
|
-
ssr: true,
|
|
157
|
-
rollupOptions: { input: ssrEntry }
|
|
158
|
-
},
|
|
159
|
-
logLevel: options.verbose ? "info" : "warn"
|
|
160
|
-
});
|
|
161
|
-
console.log("📝 Collecting paths to render...");
|
|
162
|
-
const pathsToRender = await collectPaths(routes, root, warnings);
|
|
163
|
-
console.log(` ${pathsToRender.length} path(s) to render`);
|
|
164
|
-
const outputDirs = /* @__PURE__ */ new Set();
|
|
165
|
-
for (const pathInfo of pathsToRender) {
|
|
166
|
-
const outputPath = getOutputPath(pathInfo.path, resolvedConfig.outDir);
|
|
167
|
-
outputDirs.add(path.dirname(outputPath));
|
|
168
|
-
}
|
|
169
|
-
await Promise.all(Array.from(outputDirs).map((dir) => fs.mkdir(dir, { recursive: true })));
|
|
170
|
-
console.log("🎨 Rendering pages...");
|
|
171
|
-
const ssrEntryName = path.basename(ssrEntry, path.extname(ssrEntry)) + ".js";
|
|
172
|
-
const entryModule = await import(pathToFileURL(path.join(ssrOutDir, ssrEntryName)).href);
|
|
173
|
-
const templatePath = path.join(resolvedConfig.outDir, "index.html");
|
|
174
|
-
const template = await fs.readFile(templatePath, "utf-8");
|
|
175
|
-
const CONCURRENCY = options.concurrency ?? 20;
|
|
176
|
-
const verbose = options.verbose ?? false;
|
|
177
|
-
async function renderPage(pathInfo) {
|
|
178
|
-
const renderStart = Date.now();
|
|
179
|
-
try {
|
|
180
|
-
const appHtml = await entryModule.render(pathInfo.path, {
|
|
181
|
-
params: pathInfo.params,
|
|
182
|
-
props: pathInfo.props
|
|
183
|
-
});
|
|
184
|
-
let html = template.replace("<!--app-html-->", appHtml);
|
|
185
|
-
const headTags = generateHeadTags(pathInfo, resolvedConfig);
|
|
186
|
-
html = html.replace("<!--head-tags-->", headTags);
|
|
187
|
-
const outputPath = getOutputPath(pathInfo.path, resolvedConfig.outDir);
|
|
188
|
-
const renderTime = Date.now() - renderStart;
|
|
189
|
-
return {
|
|
190
|
-
pathInfo,
|
|
191
|
-
html,
|
|
192
|
-
outputPath,
|
|
193
|
-
renderTime
|
|
194
|
-
};
|
|
195
|
-
} catch (err) {
|
|
196
|
-
const errorMessage = err instanceof Error ? err.message : String(err);
|
|
197
|
-
console.error(` ❌ ${pathInfo.path}: ${errorMessage}`);
|
|
198
|
-
warnings.push(`Failed to render ${pathInfo.path}: ${errorMessage}`);
|
|
199
|
-
return null;
|
|
200
|
-
}
|
|
201
|
-
}
|
|
202
|
-
console.log(" Phase 1: Rendering...");
|
|
203
|
-
const renderPhaseStart = Date.now();
|
|
204
|
-
const renderResults = [];
|
|
205
|
-
for (let i = 0; i < pathsToRender.length; i += CONCURRENCY) {
|
|
206
|
-
const batch = pathsToRender.slice(i, i + CONCURRENCY);
|
|
207
|
-
const results = await Promise.all(batch.map(renderPage));
|
|
208
|
-
for (const result of results) if (result) renderResults.push(result);
|
|
209
|
-
}
|
|
210
|
-
const renderPhaseDuration = Date.now() - renderPhaseStart;
|
|
211
|
-
console.log(` Phase 1 complete: ${renderResults.length} pages in ${renderPhaseDuration}ms (${Math.round(renderPhaseDuration / renderResults.length)}ms avg)`);
|
|
212
|
-
console.log(" Phase 2: Writing files...");
|
|
213
|
-
const writePhaseStart = Date.now();
|
|
214
|
-
const WRITE_CONCURRENCY = 10;
|
|
215
|
-
for (let i = 0; i < renderResults.length; i += WRITE_CONCURRENCY) {
|
|
216
|
-
const batch = renderResults.slice(i, i + WRITE_CONCURRENCY);
|
|
217
|
-
await Promise.all(batch.map(async (result) => {
|
|
218
|
-
await fs.writeFile(result.outputPath, result.html, "utf-8");
|
|
219
|
-
const size = Buffer.byteLength(result.html, "utf-8");
|
|
220
|
-
pages.push({
|
|
221
|
-
path: result.pathInfo.path,
|
|
222
|
-
file: result.outputPath,
|
|
223
|
-
time: result.renderTime,
|
|
224
|
-
size
|
|
225
|
-
});
|
|
226
|
-
if (verbose) console.log(` ✓ ${result.pathInfo.path} (${result.renderTime}ms, ${formatBytes(size)})`);
|
|
227
|
-
}));
|
|
228
|
-
}
|
|
229
|
-
const writePhaseDuration = Date.now() - writePhaseStart;
|
|
230
|
-
console.log(` Phase 2 complete: ${renderResults.length} files in ${writePhaseDuration}ms`);
|
|
231
|
-
if (!verbose) console.log(` ✓ Rendered ${renderResults.length} pages`);
|
|
232
|
-
await fs.rm(ssrOutDir, {
|
|
233
|
-
recursive: true,
|
|
234
|
-
force: true
|
|
235
|
-
});
|
|
236
|
-
if (pages.length > 0) {
|
|
237
|
-
console.log("🗺️ Generating sitemap...");
|
|
238
|
-
await writeSitemap(pages, resolvedConfig, resolvedConfig.outDir);
|
|
239
|
-
console.log(" ✓ sitemap.xml");
|
|
240
|
-
console.log(" ✓ robots.txt");
|
|
241
|
-
}
|
|
242
|
-
} finally {
|
|
243
|
-
await cleanupTempEntries(root);
|
|
244
|
-
if (cleanupHtml) try {
|
|
245
|
-
await fs.unlink(htmlTemplatePath);
|
|
246
|
-
} catch {}
|
|
247
|
-
else if (originalHtmlContent !== null) try {
|
|
248
|
-
await fs.writeFile(htmlTemplatePath, originalHtmlContent, "utf-8");
|
|
249
|
-
} catch {}
|
|
250
|
-
}
|
|
251
|
-
const totalTime = Date.now() - startTime;
|
|
252
|
-
console.log(`\n✅ Built ${pages.length} page(s) in ${totalTime}ms`);
|
|
253
|
-
if (warnings.length > 0) {
|
|
254
|
-
console.log(`\n⚠️ ${warnings.length} warning(s):`);
|
|
255
|
-
for (const warning of warnings) console.log(` - ${warning}`);
|
|
256
|
-
}
|
|
257
|
-
console.log(`\n📁 Output: ${resolvedConfig.outDir}\n`);
|
|
258
|
-
return {
|
|
259
|
-
pages,
|
|
260
|
-
totalTime,
|
|
261
|
-
warnings
|
|
262
|
-
};
|
|
263
|
-
}
|
|
264
|
-
/**
|
|
265
|
-
* Collect all paths to render, expanding dynamic routes
|
|
266
|
-
*/
|
|
267
|
-
async function collectPaths(routes, root, warnings) {
|
|
268
|
-
const paths = [];
|
|
269
|
-
for (const route of routes) if (isDynamicRoute(route)) try {
|
|
270
|
-
const pageModule = await import(pathToFileURL(route.file).href);
|
|
271
|
-
if (!pageModule.getStaticPaths) {
|
|
272
|
-
const params = extractParams(route.path).join(", ");
|
|
273
|
-
console.warn(`\n⚠️ SSG102: Dynamic route missing getStaticPaths()\n 📁 ${route.file}\n Route: ${route.path} (params: ${params})\n 💡 Export getStaticPaths() to generate static pages:\n\n export async function getStaticPaths() {\n return [{ params: { ${params.split(", ")[0]}: 'value' } }];\n }\n`);
|
|
274
|
-
warnings.push(`Route ${route.path} has dynamic segments [${params}] but no getStaticPaths() export. Skipping.`);
|
|
275
|
-
continue;
|
|
276
|
-
}
|
|
277
|
-
const staticPaths = await pageModule.getStaticPaths();
|
|
278
|
-
for (const staticPath of staticPaths) {
|
|
279
|
-
const expandedPaths = expandDynamicRoute(route, [staticPath]);
|
|
280
|
-
for (const expandedPath of expandedPaths) paths.push({
|
|
281
|
-
path: expandedPath,
|
|
282
|
-
route,
|
|
283
|
-
params: staticPath.params,
|
|
284
|
-
props: staticPath.props
|
|
285
|
-
});
|
|
286
|
-
}
|
|
287
|
-
} catch (err) {
|
|
288
|
-
warnings.push(`Failed to load ${route.file}: ${err}`);
|
|
289
|
-
}
|
|
290
|
-
else paths.push({
|
|
291
|
-
path: route.path,
|
|
292
|
-
route,
|
|
293
|
-
params: {}
|
|
294
|
-
});
|
|
295
|
-
return paths;
|
|
296
|
-
}
|
|
297
|
-
/**
|
|
298
|
-
* Generate head tags for a page
|
|
299
|
-
*/
|
|
300
|
-
function generateHeadTags(pathInfo, config) {
|
|
301
|
-
const tags = [];
|
|
302
|
-
const meta = pathInfo.route.meta || {};
|
|
303
|
-
const title = meta.title || config.site?.title;
|
|
304
|
-
if (title) tags.push(`<title>${escapeHtml(title)}</title>`);
|
|
305
|
-
const description = meta.description || config.site?.description;
|
|
306
|
-
if (description) tags.push(`<meta name="description" content="${escapeHtml(description)}">`);
|
|
307
|
-
if (config.site?.url) {
|
|
308
|
-
const canonical = new URL(pathInfo.path, config.site.url).href;
|
|
309
|
-
tags.push(`<link rel="canonical" href="${canonical}">`);
|
|
310
|
-
}
|
|
311
|
-
return tags.join("\n ");
|
|
312
|
-
}
|
|
313
|
-
/**
|
|
314
|
-
* Get output file path for a URL path
|
|
315
|
-
*/
|
|
316
|
-
function getOutputPath(urlPath, outDir) {
|
|
317
|
-
let normalized = urlPath.replace(/^\//, "").replace(/\/$/, "");
|
|
318
|
-
if (!normalized) normalized = "index";
|
|
319
|
-
if (!normalized.endsWith(".html")) normalized = path.join(normalized, "index.html");
|
|
320
|
-
return path.join(outDir, normalized);
|
|
321
|
-
}
|
|
322
|
-
/**
|
|
323
|
-
* Get SSR entry point
|
|
324
|
-
* Returns virtual module ID if no custom entry exists
|
|
325
|
-
*/
|
|
326
|
-
async function getSSREntryPoint(config, root) {
|
|
327
|
-
const detection = detectCustomEntries(root, config);
|
|
328
|
-
if (!detection.useVirtualServer && detection.customServerPath) return detection.customServerPath;
|
|
329
|
-
const virtualServerCode = generateServerEntry(config);
|
|
330
|
-
const tempServerPath = path.join(root, ".ssg-temp-entry-server.tsx");
|
|
331
|
-
fsSync.writeFileSync(tempServerPath, virtualServerCode, "utf-8");
|
|
332
|
-
return tempServerPath;
|
|
333
|
-
}
|
|
334
|
-
/**
|
|
335
|
-
* Get client entry point
|
|
336
|
-
* Returns virtual module ID if no custom entry exists
|
|
337
|
-
*/
|
|
338
|
-
async function getClientEntryPoint(config, root) {
|
|
339
|
-
const detection = detectCustomEntries(root, config);
|
|
340
|
-
if (!detection.useVirtualClient && detection.customClientPath) return detection.customClientPath;
|
|
341
|
-
const virtualClientCode = generateClientEntry(config, detection);
|
|
342
|
-
const tempClientPath = path.join(root, ".ssg-temp-entry-client.tsx");
|
|
343
|
-
fsSync.writeFileSync(tempClientPath, virtualClientCode, "utf-8");
|
|
344
|
-
return tempClientPath;
|
|
345
|
-
}
|
|
346
|
-
/**
|
|
347
|
-
* Clean up temporary entry files
|
|
348
|
-
*/
|
|
349
|
-
async function cleanupTempEntries(root) {
|
|
350
|
-
const tempFiles = [path.join(root, ".ssg-temp-entry-server.tsx"), path.join(root, ".ssg-temp-entry-client.tsx")];
|
|
351
|
-
for (const file of tempFiles) try {
|
|
352
|
-
await fs.unlink(file);
|
|
353
|
-
} catch {}
|
|
354
|
-
}
|
|
355
|
-
/**
|
|
356
|
-
* Get or generate HTML template
|
|
357
|
-
*/
|
|
358
|
-
async function getHtmlTemplate(config, root, clientEntryPath) {
|
|
359
|
-
const detection = detectCustomEntries(root, config);
|
|
360
|
-
if (!detection.useVirtualHtml && detection.customHtmlPath) {
|
|
361
|
-
let html = await fs.readFile(detection.customHtmlPath, "utf-8");
|
|
362
|
-
const relativePath = "./" + path.relative(root, clientEntryPath).replace(/\\/g, "/");
|
|
363
|
-
html = html.replace(/<script([^>]*)\s+src=["']?\/@ssg\/client\.tsx["']?/g, `<script$1 src="${relativePath}"`);
|
|
364
|
-
return html;
|
|
365
|
-
}
|
|
366
|
-
return generateProductionHtmlTemplate(config, clientEntryPath);
|
|
367
|
-
}
|
|
368
|
-
/**
|
|
369
|
-
* Format bytes to human-readable string
|
|
370
|
-
*/
|
|
371
|
-
function formatBytes(bytes) {
|
|
372
|
-
if (bytes < 1024) return `${bytes}B`;
|
|
373
|
-
if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)}KB`;
|
|
374
|
-
return `${(bytes / (1024 * 1024)).toFixed(1)}MB`;
|
|
375
|
-
}
|
|
376
|
-
/**
|
|
377
|
-
* Escape HTML special characters
|
|
378
|
-
*/
|
|
379
|
-
function escapeHtml(str) {
|
|
380
|
-
return str.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'");
|
|
381
|
-
}
|
|
382
|
-
//#endregion
|
|
383
|
-
export { writeSitemap as a, pagesToSitemapEntries as i, generateRobotsTxt as n, generateSitemap as r, build as t };
|
|
384
|
-
|
|
385
|
-
//# sourceMappingURL=build-qmtK32gt.js.map
|