defuss-ssg 0.1.1 → 0.1.2
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/cli.mjs +8 -6
- package/dist/index.cjs +181 -162
- package/dist/index.d.cts +3 -3
- package/dist/index.d.mts +3 -3
- package/dist/index.mjs +1 -1
- package/dist/plugins/index.d.cts +1 -1
- package/dist/plugins/index.d.mts +1 -1
- package/dist/{serve-BR2MS6bN.mjs → serve-CMNixAKF.mjs} +182 -163
- package/dist/{types-BhV8wSVk.d.cts → types-C0p7aCdN.d.cts} +6 -0
- package/dist/{types-BhV8wSVk.d.mts → types-C0p7aCdN.d.mts} +6 -0
- package/package.json +1 -1
package/dist/cli.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { v as validateProjectDir, b as build, s as serve } from './serve-
|
|
2
|
+
import { v as validateProjectDir, b as build, s as serve } from './serve-CMNixAKF.mjs';
|
|
3
3
|
import { join, dirname, resolve } from 'node:path';
|
|
4
4
|
import { existsSync, readFileSync } from 'node:fs';
|
|
5
5
|
import { spawn } from 'node:child_process';
|
|
@@ -165,9 +165,11 @@ Continuing anyway \u2014 dependencies may already be available.`
|
|
|
165
165
|
|
|
166
166
|
(async () => {
|
|
167
167
|
const args = process.argv.slice(2);
|
|
168
|
-
const
|
|
169
|
-
const
|
|
170
|
-
const
|
|
168
|
+
const debug = args.includes("--debug") || args.includes("-d");
|
|
169
|
+
const positional = args.filter((a) => !a.startsWith("-"));
|
|
170
|
+
const command = positional[0];
|
|
171
|
+
const folder = positional[1];
|
|
172
|
+
const usage = "Usage: defuss-ssg <build|serve> <folder> [--debug]";
|
|
171
173
|
if (!command || !folder) {
|
|
172
174
|
console.error(usage);
|
|
173
175
|
process.exit(1);
|
|
@@ -178,14 +180,14 @@ Continuing anyway \u2014 dependencies may already be available.`
|
|
|
178
180
|
console.log(`Building ${folder}...`);
|
|
179
181
|
await build({
|
|
180
182
|
projectDir,
|
|
181
|
-
debug
|
|
183
|
+
debug,
|
|
182
184
|
mode: "build"
|
|
183
185
|
});
|
|
184
186
|
} else if (command === "serve") {
|
|
185
187
|
console.log(`Serving ${folder}...`);
|
|
186
188
|
await serve({
|
|
187
189
|
projectDir,
|
|
188
|
-
debug
|
|
190
|
+
debug});
|
|
189
191
|
} else {
|
|
190
192
|
console.error(usage);
|
|
191
193
|
process.exit(1);
|
package/dist/index.cjs
CHANGED
|
@@ -208,15 +208,13 @@ const __dirname$1 = node_path.dirname(__filename$1);
|
|
|
208
208
|
const build = async ({
|
|
209
209
|
projectDir,
|
|
210
210
|
debug = false,
|
|
211
|
-
mode = "build"
|
|
211
|
+
mode = "build",
|
|
212
|
+
changedFile
|
|
212
213
|
}) => {
|
|
213
214
|
const projectDirStatus = validateProjectDir(projectDir);
|
|
214
215
|
if (projectDirStatus.code !== "OK") return projectDirStatus;
|
|
215
216
|
const startTime = performance.now();
|
|
216
217
|
const config = await readConfig(projectDir, debug);
|
|
217
|
-
if (debug) {
|
|
218
|
-
console.log("PRE config", config);
|
|
219
|
-
}
|
|
220
218
|
if (debug) {
|
|
221
219
|
console.log("Using config:", config);
|
|
222
220
|
}
|
|
@@ -245,193 +243,213 @@ const build = async ({
|
|
|
245
243
|
}
|
|
246
244
|
if (!node_fs.existsSync(inputPagesDir)) {
|
|
247
245
|
throw new Error(`Input pages directory does not exist: ${inputPagesDir}`);
|
|
248
|
-
} else if (debug) {
|
|
249
|
-
console.log(`Input pages directory exists: ${inputPagesDir}`);
|
|
250
246
|
}
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
);
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
)
|
|
247
|
+
let changeKind = "full";
|
|
248
|
+
let changedRelative = "";
|
|
249
|
+
if (changedFile) {
|
|
250
|
+
changedRelative = changedFile.startsWith(projectDir) ? changedFile.slice(projectDir.length).replace(/^\//, "") : changedFile;
|
|
251
|
+
if (changedRelative.startsWith(config.pages + node_path.sep) || changedRelative.startsWith(config.pages + "/")) {
|
|
252
|
+
changeKind = "page";
|
|
253
|
+
} else if (changedRelative.startsWith(config.components + node_path.sep) || changedRelative.startsWith(config.components + "/")) {
|
|
254
|
+
changeKind = "component";
|
|
255
|
+
} else if (changedRelative.startsWith(config.assets + node_path.sep) || changedRelative.startsWith(config.assets + "/")) {
|
|
256
|
+
changeKind = "asset";
|
|
257
|
+
} else if (changedRelative === "config.ts" || changedRelative === "config.js") {
|
|
258
|
+
changeKind = "config";
|
|
259
|
+
}
|
|
260
|
+
if (debug) {
|
|
261
|
+
console.log(`Incremental build \u2014 changeKind: ${changeKind}, file: ${changedRelative}`);
|
|
262
|
+
}
|
|
260
263
|
}
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
264
|
+
const isFullBuild = changeKind === "full" || changeKind === "config";
|
|
265
|
+
const tempExists = node_fs.existsSync(config.tmp);
|
|
266
|
+
if (isFullBuild) {
|
|
267
|
+
for (const plugin of config.plugins || []) {
|
|
268
|
+
if (plugin.phase === "pre" && (plugin.mode === mode || plugin.mode === "both")) {
|
|
269
|
+
if (debug) {
|
|
270
|
+
console.log(`Running pre-plugin: ${plugin.name}`);
|
|
271
|
+
}
|
|
272
|
+
await plugin.fn(projectDir, config);
|
|
265
273
|
}
|
|
266
|
-
await plugin.fn(projectDir, config);
|
|
267
274
|
}
|
|
268
275
|
}
|
|
269
|
-
if (
|
|
270
|
-
if (
|
|
271
|
-
|
|
276
|
+
if (isFullBuild || !tempExists) {
|
|
277
|
+
if (tempExists) {
|
|
278
|
+
node_fs.rmSync(config.tmp, { recursive: true });
|
|
272
279
|
}
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
return
|
|
280
|
+
await promises.cp(projectDir, config.tmp, {
|
|
281
|
+
recursive: true,
|
|
282
|
+
filter: (src) => {
|
|
283
|
+
const relative = src.replace(node_path.join(projectDir, ""), "");
|
|
284
|
+
if (relative.startsWith(node_path.join("assets", "")) || relative.startsWith(node_path.join("node_modules", ""))) {
|
|
285
|
+
return false;
|
|
286
|
+
}
|
|
287
|
+
return true;
|
|
281
288
|
}
|
|
282
|
-
|
|
289
|
+
});
|
|
290
|
+
} else {
|
|
291
|
+
const srcFile = node_path.join(projectDir, changedRelative);
|
|
292
|
+
const destFile = node_path.join(config.tmp, changedRelative);
|
|
293
|
+
const destDir = node_path.dirname(destFile);
|
|
294
|
+
if (!node_fs.existsSync(destDir)) {
|
|
295
|
+
node_fs.mkdirSync(destDir, { recursive: true });
|
|
283
296
|
}
|
|
284
|
-
|
|
297
|
+
if (node_fs.existsSync(srcFile)) {
|
|
298
|
+
await promises.cp(srcFile, destFile);
|
|
299
|
+
}
|
|
300
|
+
}
|
|
285
301
|
await promises.cp(
|
|
286
|
-
// in a built situation, __dirname is the dist folder of defuss-ssg
|
|
287
302
|
node_path.resolve(node_path.join(__dirname$1, "components", "index.mjs")),
|
|
288
303
|
node_path.join(tmpComponentsDir, "hydrate.tsx")
|
|
289
|
-
// any valid JS is always a valid TS file
|
|
290
304
|
);
|
|
291
305
|
await promises.cp(
|
|
292
|
-
// in a built situation, __dirname is the dist folder of defuss-ssg
|
|
293
306
|
node_path.resolve(node_path.join(__dirname$1, "runtime.mjs")),
|
|
294
307
|
node_path.join(tmpComponentsDir, "runtime.ts")
|
|
295
|
-
// any valid JS is always a valid TS file
|
|
296
308
|
);
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
});
|
|
317
|
-
await esbuild.build({
|
|
318
|
-
entryPoints: [
|
|
319
|
-
node_path.join(tmpComponentsDir, "**/*.tsx"),
|
|
320
|
-
node_path.join(tmpComponentsDir, "**/*.ts")
|
|
321
|
-
],
|
|
322
|
-
format: "esm",
|
|
323
|
-
bundle: true,
|
|
324
|
-
// making sure we can do code splitting for shared dependencies (e.g. defuss lib)
|
|
325
|
-
splitting: true,
|
|
326
|
-
target: ["esnext"],
|
|
327
|
-
outdir: tmpComponentsDir
|
|
328
|
-
});
|
|
329
|
-
const outputFiles = await glob.async(node_path.join(tmpPagesDir, "**/*.js"));
|
|
330
|
-
if (!node_fs.existsSync(outputProjectDir)) {
|
|
331
|
-
node_fs.mkdirSync(outputProjectDir, { recursive: true });
|
|
309
|
+
if (changeKind !== "asset") {
|
|
310
|
+
const pageEntryPoints = changeKind === "page" ? [node_path.join(config.tmp, changedRelative)] : [node_path.join(tmpPagesDir, "**/*.mdx")];
|
|
311
|
+
await esbuild.build({
|
|
312
|
+
entryPoints: pageEntryPoints,
|
|
313
|
+
format: "esm",
|
|
314
|
+
bundle: true,
|
|
315
|
+
sourcemap: true,
|
|
316
|
+
jsxDev: true,
|
|
317
|
+
target: ["esnext"],
|
|
318
|
+
outdir: tmpPagesDir,
|
|
319
|
+
plugins: [
|
|
320
|
+
mdx({
|
|
321
|
+
jsxImportSource: "defuss",
|
|
322
|
+
development: true,
|
|
323
|
+
remarkPlugins: config.remarkPlugins,
|
|
324
|
+
rehypePlugins: config.rehypePlugins
|
|
325
|
+
})
|
|
326
|
+
]
|
|
327
|
+
});
|
|
332
328
|
}
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
329
|
+
if (isFullBuild || changeKind === "component") {
|
|
330
|
+
await esbuild.build({
|
|
331
|
+
entryPoints: [
|
|
332
|
+
node_path.join(tmpComponentsDir, "**/*.tsx"),
|
|
333
|
+
node_path.join(tmpComponentsDir, "**/*.ts")
|
|
334
|
+
],
|
|
335
|
+
format: "esm",
|
|
336
|
+
bundle: true,
|
|
337
|
+
splitting: true,
|
|
338
|
+
target: ["esnext"],
|
|
339
|
+
outdir: tmpComponentsDir
|
|
340
|
+
});
|
|
341
|
+
}
|
|
342
|
+
if (changeKind !== "asset") {
|
|
343
|
+
let outputFiles;
|
|
344
|
+
if (changeKind === "page") {
|
|
345
|
+
const jsFile = node_path.join(config.tmp, changedRelative.replace(/\.mdx$/, ".js"));
|
|
346
|
+
outputFiles = node_fs.existsSync(jsFile) ? [jsFile] : [];
|
|
347
|
+
} else {
|
|
348
|
+
outputFiles = await glob.async(node_path.join(tmpPagesDir, "**/*.js"));
|
|
343
349
|
}
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
const dataUrl = `data:text/javascript;base64,${encoded}`;
|
|
347
|
-
const exports$1 = await import(dataUrl);
|
|
348
|
-
if (debug) {
|
|
349
|
-
console.log("exports", exports$1);
|
|
350
|
+
if (!node_fs.existsSync(outputProjectDir)) {
|
|
351
|
+
node_fs.mkdirSync(outputProjectDir, { recursive: true });
|
|
350
352
|
}
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
353
|
+
for (const outputFile of outputFiles) {
|
|
354
|
+
const outputHtmlFilePath = outputFile.replace(".js", ".html");
|
|
355
|
+
const relativeOutputHtmlFilePath = outputHtmlFilePath.replace(
|
|
356
|
+
`${tmpPagesDir}${node_path.sep}`,
|
|
357
|
+
""
|
|
358
|
+
);
|
|
359
|
+
if (debug) {
|
|
360
|
+
console.log("Processing output file (JS):", outputFile);
|
|
361
|
+
console.log("Relative output HTML path:", relativeOutputHtmlFilePath);
|
|
362
|
+
}
|
|
363
|
+
const code = await promises.readFile(outputFile, "utf-8");
|
|
364
|
+
const encoded = Buffer.from(code).toString("base64");
|
|
365
|
+
const dataUrl = `data:text/javascript;base64,${encoded}`;
|
|
366
|
+
const exports$1 = await import(dataUrl);
|
|
367
|
+
if (debug) {
|
|
368
|
+
console.log("exports", exports$1);
|
|
369
|
+
}
|
|
370
|
+
let vdom = exports$1.default(exports$1);
|
|
371
|
+
for (const plugin of config.plugins || []) {
|
|
372
|
+
if (plugin.phase === "page-vdom" && (plugin.mode === mode || plugin.mode === "both")) {
|
|
373
|
+
if (debug) {
|
|
374
|
+
console.log(`Running page-vdom plugin: ${plugin.name}`);
|
|
375
|
+
}
|
|
376
|
+
vdom = await plugin.fn(
|
|
377
|
+
vdom,
|
|
378
|
+
relativeOutputHtmlFilePath,
|
|
379
|
+
projectDir,
|
|
380
|
+
config,
|
|
381
|
+
exports$1
|
|
382
|
+
);
|
|
356
383
|
}
|
|
357
|
-
vdom = await plugin.fn(
|
|
358
|
-
vdom,
|
|
359
|
-
relativeOutputHtmlFilePath,
|
|
360
|
-
projectDir,
|
|
361
|
-
config,
|
|
362
|
-
exports$1
|
|
363
|
-
);
|
|
364
384
|
}
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
385
|
+
const browserGlobals = server.getBrowserGlobals();
|
|
386
|
+
const document = server.getDocument(false, browserGlobals);
|
|
387
|
+
browserGlobals.document = document;
|
|
388
|
+
let el = server.renderSync(vdom, document.documentElement, {
|
|
389
|
+
browserGlobals
|
|
390
|
+
});
|
|
391
|
+
for (const plugin of config.plugins || []) {
|
|
392
|
+
if (plugin.phase === "page-dom" && (plugin.mode === mode || plugin.mode === "both")) {
|
|
393
|
+
if (debug) {
|
|
394
|
+
console.log(`Running page-dom plugin: ${plugin.name}`);
|
|
395
|
+
}
|
|
396
|
+
el = await plugin.fn(
|
|
397
|
+
el,
|
|
398
|
+
relativeOutputHtmlFilePath,
|
|
399
|
+
projectDir,
|
|
400
|
+
config
|
|
401
|
+
);
|
|
376
402
|
}
|
|
377
|
-
el = await plugin.fn(
|
|
378
|
-
el,
|
|
379
|
-
relativeOutputHtmlFilePath,
|
|
380
|
-
projectDir,
|
|
381
|
-
config
|
|
382
|
-
);
|
|
383
403
|
}
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
404
|
+
let html = server.renderToString(el);
|
|
405
|
+
for (const plugin of config.plugins || []) {
|
|
406
|
+
if (plugin.phase === "page-html" && (plugin.mode === mode || plugin.mode === "both")) {
|
|
407
|
+
if (debug) {
|
|
408
|
+
console.log(`Running page-html plugin: ${plugin.name}`);
|
|
409
|
+
}
|
|
410
|
+
html = await plugin.fn(
|
|
411
|
+
html,
|
|
412
|
+
relativeOutputHtmlFilePath,
|
|
413
|
+
projectDir,
|
|
414
|
+
config
|
|
415
|
+
);
|
|
390
416
|
}
|
|
391
|
-
html = await plugin.fn(
|
|
392
|
-
html,
|
|
393
|
-
relativeOutputHtmlFilePath,
|
|
394
|
-
projectDir,
|
|
395
|
-
config
|
|
396
|
-
);
|
|
397
417
|
}
|
|
418
|
+
const finalOutputFile = node_path.join(
|
|
419
|
+
projectDir,
|
|
420
|
+
config.output,
|
|
421
|
+
relativeOutputHtmlFilePath
|
|
422
|
+
);
|
|
423
|
+
const finalOutputDir = node_path.dirname(finalOutputFile);
|
|
424
|
+
if (!node_fs.existsSync(finalOutputDir)) {
|
|
425
|
+
node_fs.mkdirSync(finalOutputDir, { recursive: true });
|
|
426
|
+
}
|
|
427
|
+
await promises.writeFile(finalOutputFile, html);
|
|
398
428
|
}
|
|
399
|
-
if (debug) {
|
|
400
|
-
console.log("Writing HTML file", outputHtmlFilePath);
|
|
401
|
-
}
|
|
402
|
-
if (debug) {
|
|
403
|
-
console.log("Relative HTML path:", relativeOutputHtmlFilePath);
|
|
404
|
-
}
|
|
405
|
-
const finalOutputFile = node_path.join(
|
|
406
|
-
projectDir,
|
|
407
|
-
config.output,
|
|
408
|
-
relativeOutputHtmlFilePath
|
|
409
|
-
);
|
|
410
|
-
if (debug) {
|
|
411
|
-
console.log("Full HTML output path:", finalOutputFile);
|
|
412
|
-
}
|
|
413
|
-
const finalOutputDir = node_path.dirname(finalOutputFile);
|
|
414
|
-
if (!node_fs.existsSync(finalOutputDir)) {
|
|
415
|
-
node_fs.mkdirSync(finalOutputDir, { recursive: true });
|
|
416
|
-
}
|
|
417
|
-
await promises.writeFile(finalOutputFile, html);
|
|
418
429
|
}
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
430
|
+
if (isFullBuild || changeKind === "component") {
|
|
431
|
+
await promises.cp(tmpComponentsDir, outputComponentsDir, { recursive: true });
|
|
432
|
+
}
|
|
433
|
+
if (isFullBuild || changeKind === "asset") {
|
|
434
|
+
await promises.cp(inputAssetsDir, outputAssetsDir, { recursive: true });
|
|
435
|
+
}
|
|
436
|
+
if (isFullBuild || changeKind === "component") {
|
|
437
|
+
for (const plugin of config.plugins || []) {
|
|
438
|
+
if (plugin.phase === "post" && (plugin.mode === mode || plugin.mode === "both")) {
|
|
439
|
+
if (debug) {
|
|
440
|
+
console.log(`Running post-plugin: ${plugin.name}`);
|
|
441
|
+
}
|
|
442
|
+
await plugin.fn(projectDir, config);
|
|
425
443
|
}
|
|
426
|
-
await plugin.fn(projectDir, config);
|
|
427
444
|
}
|
|
428
445
|
}
|
|
429
|
-
if (!debug) {
|
|
446
|
+
if (mode === "build" && !debug) {
|
|
430
447
|
node_fs.rmSync(config.tmp, { recursive: true });
|
|
431
448
|
}
|
|
432
449
|
const endTime = performance.now();
|
|
433
450
|
const totalTime = (endTime - startTime) / 1e3;
|
|
434
|
-
|
|
451
|
+
const label = isFullBuild ? "Full build" : `Incremental build (${changeKind}: ${changedRelative})`;
|
|
452
|
+
console.log(`${label} completed in ${totalTime.toFixed(2)} seconds.`);
|
|
435
453
|
return { code: "OK", message: "Build completed successfully" };
|
|
436
454
|
};
|
|
437
455
|
|
|
@@ -494,10 +512,10 @@ const serve = async ({
|
|
|
494
512
|
path: "/livereload"
|
|
495
513
|
});
|
|
496
514
|
let isBuilding = false;
|
|
497
|
-
let pendingBuild =
|
|
515
|
+
let pendingBuild = null;
|
|
498
516
|
const triggerBuild = async (filePath) => {
|
|
499
517
|
if (isBuilding) {
|
|
500
|
-
pendingBuild =
|
|
518
|
+
pendingBuild = filePath;
|
|
501
519
|
if (debug) {
|
|
502
520
|
console.log("Build scheduled after current one completes");
|
|
503
521
|
}
|
|
@@ -505,7 +523,7 @@ const serve = async ({
|
|
|
505
523
|
}
|
|
506
524
|
isBuilding = true;
|
|
507
525
|
try {
|
|
508
|
-
await build({ projectDir, debug, mode: "serve" });
|
|
526
|
+
await build({ projectDir, debug, mode: "serve", changedFile: filePath });
|
|
509
527
|
liveReloadServer.clients.forEach((client) => {
|
|
510
528
|
if (client.readyState === 1) {
|
|
511
529
|
client.send(
|
|
@@ -521,11 +539,12 @@ const serve = async ({
|
|
|
521
539
|
} finally {
|
|
522
540
|
isBuilding = false;
|
|
523
541
|
if (pendingBuild) {
|
|
524
|
-
|
|
542
|
+
const pending = pendingBuild;
|
|
543
|
+
pendingBuild = null;
|
|
525
544
|
if (debug) {
|
|
526
545
|
console.log("Running pending build");
|
|
527
546
|
}
|
|
528
|
-
await triggerBuild(
|
|
547
|
+
await triggerBuild(pending);
|
|
529
548
|
}
|
|
530
549
|
}
|
|
531
550
|
};
|
package/dist/index.d.cts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { R as RehypePlugins, a as RemarkPlugins, S as SsgConfig, B as BuildOptions, b as Status } from './types-
|
|
2
|
-
export { c as BuildMode, P as PluginFn, d as PluginFnPageDom, e as PluginFnPageHtml, f as PluginFnPageVdom, g as PluginFnPrePost, h as SsgPlugin, i as StatusCode } from './types-
|
|
1
|
+
import { R as RehypePlugins, a as RemarkPlugins, S as SsgConfig, B as BuildOptions, b as Status } from './types-C0p7aCdN.cjs';
|
|
2
|
+
export { c as BuildMode, P as PluginFn, d as PluginFnPageDom, e as PluginFnPageHtml, f as PluginFnPageVdom, g as PluginFnPrePost, h as SsgPlugin, i as StatusCode } from './types-C0p7aCdN.cjs';
|
|
3
3
|
import '@mdx-js/esbuild';
|
|
4
4
|
import 'defuss/server';
|
|
5
5
|
|
|
@@ -19,7 +19,7 @@ declare const configDefaults: SsgConfig;
|
|
|
19
19
|
* A single, complete build process for a static site project.
|
|
20
20
|
* @param projectDir The root directory of the project to build
|
|
21
21
|
*/
|
|
22
|
-
declare const build: ({ projectDir, debug, mode, }: BuildOptions) => Promise<Status>;
|
|
22
|
+
declare const build: ({ projectDir, debug, mode, changedFile, }: BuildOptions) => Promise<Status>;
|
|
23
23
|
|
|
24
24
|
/**
|
|
25
25
|
* A simple static file server to serve the generated static site from the output folder.
|
package/dist/index.d.mts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { R as RehypePlugins, a as RemarkPlugins, S as SsgConfig, B as BuildOptions, b as Status } from './types-
|
|
2
|
-
export { c as BuildMode, P as PluginFn, d as PluginFnPageDom, e as PluginFnPageHtml, f as PluginFnPageVdom, g as PluginFnPrePost, h as SsgPlugin, i as StatusCode } from './types-
|
|
1
|
+
import { R as RehypePlugins, a as RemarkPlugins, S as SsgConfig, B as BuildOptions, b as Status } from './types-C0p7aCdN.mjs';
|
|
2
|
+
export { c as BuildMode, P as PluginFn, d as PluginFnPageDom, e as PluginFnPageHtml, f as PluginFnPageVdom, g as PluginFnPrePost, h as SsgPlugin, i as StatusCode } from './types-C0p7aCdN.mjs';
|
|
3
3
|
import '@mdx-js/esbuild';
|
|
4
4
|
import 'defuss/server';
|
|
5
5
|
|
|
@@ -19,7 +19,7 @@ declare const configDefaults: SsgConfig;
|
|
|
19
19
|
* A single, complete build process for a static site project.
|
|
20
20
|
* @param projectDir The root directory of the project to build
|
|
21
21
|
*/
|
|
22
|
-
declare const build: ({ projectDir, debug, mode, }: BuildOptions) => Promise<Status>;
|
|
22
|
+
declare const build: ({ projectDir, debug, mode, changedFile, }: BuildOptions) => Promise<Status>;
|
|
23
23
|
|
|
24
24
|
/**
|
|
25
25
|
* A simple static file server to serve the generated static site from the output folder.
|
package/dist/index.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { b as build, c as configDefaults, r as readConfig, a as rehypePlugins, d as remarkPlugins, s as serve } from './serve-
|
|
1
|
+
export { b as build, c as configDefaults, r as readConfig, a as rehypePlugins, d as remarkPlugins, s as serve } from './serve-CMNixAKF.mjs';
|
|
2
2
|
import 'chokidar';
|
|
3
3
|
import 'ultimate-express';
|
|
4
4
|
import 'node:path';
|
package/dist/plugins/index.d.cts
CHANGED
package/dist/plugins/index.d.mts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import chokidar from 'chokidar';
|
|
2
2
|
import express from 'ultimate-express';
|
|
3
|
-
import { join, sep,
|
|
3
|
+
import { join, sep, dirname, resolve } from 'node:path';
|
|
4
4
|
import { existsSync, statSync, rmSync, mkdirSync } from 'node:fs';
|
|
5
5
|
import esbuild from 'esbuild';
|
|
6
6
|
import rehypeKatex from 'rehype-katex';
|
|
@@ -205,15 +205,13 @@ const __dirname$1 = dirname(__filename$1);
|
|
|
205
205
|
const build = async ({
|
|
206
206
|
projectDir,
|
|
207
207
|
debug = false,
|
|
208
|
-
mode = "build"
|
|
208
|
+
mode = "build",
|
|
209
|
+
changedFile
|
|
209
210
|
}) => {
|
|
210
211
|
const projectDirStatus = validateProjectDir(projectDir);
|
|
211
212
|
if (projectDirStatus.code !== "OK") return projectDirStatus;
|
|
212
213
|
const startTime = performance.now();
|
|
213
214
|
const config = await readConfig(projectDir, debug);
|
|
214
|
-
if (debug) {
|
|
215
|
-
console.log("PRE config", config);
|
|
216
|
-
}
|
|
217
215
|
if (debug) {
|
|
218
216
|
console.log("Using config:", config);
|
|
219
217
|
}
|
|
@@ -242,193 +240,213 @@ const build = async ({
|
|
|
242
240
|
}
|
|
243
241
|
if (!existsSync(inputPagesDir)) {
|
|
244
242
|
throw new Error(`Input pages directory does not exist: ${inputPagesDir}`);
|
|
245
|
-
} else if (debug) {
|
|
246
|
-
console.log(`Input pages directory exists: ${inputPagesDir}`);
|
|
247
243
|
}
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
);
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
)
|
|
244
|
+
let changeKind = "full";
|
|
245
|
+
let changedRelative = "";
|
|
246
|
+
if (changedFile) {
|
|
247
|
+
changedRelative = changedFile.startsWith(projectDir) ? changedFile.slice(projectDir.length).replace(/^\//, "") : changedFile;
|
|
248
|
+
if (changedRelative.startsWith(config.pages + sep) || changedRelative.startsWith(config.pages + "/")) {
|
|
249
|
+
changeKind = "page";
|
|
250
|
+
} else if (changedRelative.startsWith(config.components + sep) || changedRelative.startsWith(config.components + "/")) {
|
|
251
|
+
changeKind = "component";
|
|
252
|
+
} else if (changedRelative.startsWith(config.assets + sep) || changedRelative.startsWith(config.assets + "/")) {
|
|
253
|
+
changeKind = "asset";
|
|
254
|
+
} else if (changedRelative === "config.ts" || changedRelative === "config.js") {
|
|
255
|
+
changeKind = "config";
|
|
256
|
+
}
|
|
257
|
+
if (debug) {
|
|
258
|
+
console.log(`Incremental build \u2014 changeKind: ${changeKind}, file: ${changedRelative}`);
|
|
259
|
+
}
|
|
257
260
|
}
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
261
|
+
const isFullBuild = changeKind === "full" || changeKind === "config";
|
|
262
|
+
const tempExists = existsSync(config.tmp);
|
|
263
|
+
if (isFullBuild) {
|
|
264
|
+
for (const plugin of config.plugins || []) {
|
|
265
|
+
if (plugin.phase === "pre" && (plugin.mode === mode || plugin.mode === "both")) {
|
|
266
|
+
if (debug) {
|
|
267
|
+
console.log(`Running pre-plugin: ${plugin.name}`);
|
|
268
|
+
}
|
|
269
|
+
await plugin.fn(projectDir, config);
|
|
262
270
|
}
|
|
263
|
-
await plugin.fn(projectDir, config);
|
|
264
271
|
}
|
|
265
272
|
}
|
|
266
|
-
if (
|
|
267
|
-
if (
|
|
268
|
-
|
|
273
|
+
if (isFullBuild || !tempExists) {
|
|
274
|
+
if (tempExists) {
|
|
275
|
+
rmSync(config.tmp, { recursive: true });
|
|
269
276
|
}
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
return
|
|
277
|
+
await cp(projectDir, config.tmp, {
|
|
278
|
+
recursive: true,
|
|
279
|
+
filter: (src) => {
|
|
280
|
+
const relative = src.replace(join(projectDir, ""), "");
|
|
281
|
+
if (relative.startsWith(join("assets", "")) || relative.startsWith(join("node_modules", ""))) {
|
|
282
|
+
return false;
|
|
283
|
+
}
|
|
284
|
+
return true;
|
|
278
285
|
}
|
|
279
|
-
|
|
286
|
+
});
|
|
287
|
+
} else {
|
|
288
|
+
const srcFile = join(projectDir, changedRelative);
|
|
289
|
+
const destFile = join(config.tmp, changedRelative);
|
|
290
|
+
const destDir = dirname(destFile);
|
|
291
|
+
if (!existsSync(destDir)) {
|
|
292
|
+
mkdirSync(destDir, { recursive: true });
|
|
280
293
|
}
|
|
281
|
-
|
|
294
|
+
if (existsSync(srcFile)) {
|
|
295
|
+
await cp(srcFile, destFile);
|
|
296
|
+
}
|
|
297
|
+
}
|
|
282
298
|
await cp(
|
|
283
|
-
// in a built situation, __dirname is the dist folder of defuss-ssg
|
|
284
299
|
resolve(join(__dirname$1, "components", "index.mjs")),
|
|
285
300
|
join(tmpComponentsDir, "hydrate.tsx")
|
|
286
|
-
// any valid JS is always a valid TS file
|
|
287
301
|
);
|
|
288
302
|
await cp(
|
|
289
|
-
// in a built situation, __dirname is the dist folder of defuss-ssg
|
|
290
303
|
resolve(join(__dirname$1, "runtime.mjs")),
|
|
291
304
|
join(tmpComponentsDir, "runtime.ts")
|
|
292
|
-
// any valid JS is always a valid TS file
|
|
293
305
|
);
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
});
|
|
314
|
-
await esbuild.build({
|
|
315
|
-
entryPoints: [
|
|
316
|
-
join(tmpComponentsDir, "**/*.tsx"),
|
|
317
|
-
join(tmpComponentsDir, "**/*.ts")
|
|
318
|
-
],
|
|
319
|
-
format: "esm",
|
|
320
|
-
bundle: true,
|
|
321
|
-
// making sure we can do code splitting for shared dependencies (e.g. defuss lib)
|
|
322
|
-
splitting: true,
|
|
323
|
-
target: ["esnext"],
|
|
324
|
-
outdir: tmpComponentsDir
|
|
325
|
-
});
|
|
326
|
-
const outputFiles = await glob.async(join(tmpPagesDir, "**/*.js"));
|
|
327
|
-
if (!existsSync(outputProjectDir)) {
|
|
328
|
-
mkdirSync(outputProjectDir, { recursive: true });
|
|
306
|
+
if (changeKind !== "asset") {
|
|
307
|
+
const pageEntryPoints = changeKind === "page" ? [join(config.tmp, changedRelative)] : [join(tmpPagesDir, "**/*.mdx")];
|
|
308
|
+
await esbuild.build({
|
|
309
|
+
entryPoints: pageEntryPoints,
|
|
310
|
+
format: "esm",
|
|
311
|
+
bundle: true,
|
|
312
|
+
sourcemap: true,
|
|
313
|
+
jsxDev: true,
|
|
314
|
+
target: ["esnext"],
|
|
315
|
+
outdir: tmpPagesDir,
|
|
316
|
+
plugins: [
|
|
317
|
+
mdx({
|
|
318
|
+
jsxImportSource: "defuss",
|
|
319
|
+
development: true,
|
|
320
|
+
remarkPlugins: config.remarkPlugins,
|
|
321
|
+
rehypePlugins: config.rehypePlugins
|
|
322
|
+
})
|
|
323
|
+
]
|
|
324
|
+
});
|
|
329
325
|
}
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
326
|
+
if (isFullBuild || changeKind === "component") {
|
|
327
|
+
await esbuild.build({
|
|
328
|
+
entryPoints: [
|
|
329
|
+
join(tmpComponentsDir, "**/*.tsx"),
|
|
330
|
+
join(tmpComponentsDir, "**/*.ts")
|
|
331
|
+
],
|
|
332
|
+
format: "esm",
|
|
333
|
+
bundle: true,
|
|
334
|
+
splitting: true,
|
|
335
|
+
target: ["esnext"],
|
|
336
|
+
outdir: tmpComponentsDir
|
|
337
|
+
});
|
|
338
|
+
}
|
|
339
|
+
if (changeKind !== "asset") {
|
|
340
|
+
let outputFiles;
|
|
341
|
+
if (changeKind === "page") {
|
|
342
|
+
const jsFile = join(config.tmp, changedRelative.replace(/\.mdx$/, ".js"));
|
|
343
|
+
outputFiles = existsSync(jsFile) ? [jsFile] : [];
|
|
344
|
+
} else {
|
|
345
|
+
outputFiles = await glob.async(join(tmpPagesDir, "**/*.js"));
|
|
340
346
|
}
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
const dataUrl = `data:text/javascript;base64,${encoded}`;
|
|
344
|
-
const exports$1 = await import(dataUrl);
|
|
345
|
-
if (debug) {
|
|
346
|
-
console.log("exports", exports$1);
|
|
347
|
+
if (!existsSync(outputProjectDir)) {
|
|
348
|
+
mkdirSync(outputProjectDir, { recursive: true });
|
|
347
349
|
}
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
350
|
+
for (const outputFile of outputFiles) {
|
|
351
|
+
const outputHtmlFilePath = outputFile.replace(".js", ".html");
|
|
352
|
+
const relativeOutputHtmlFilePath = outputHtmlFilePath.replace(
|
|
353
|
+
`${tmpPagesDir}${sep}`,
|
|
354
|
+
""
|
|
355
|
+
);
|
|
356
|
+
if (debug) {
|
|
357
|
+
console.log("Processing output file (JS):", outputFile);
|
|
358
|
+
console.log("Relative output HTML path:", relativeOutputHtmlFilePath);
|
|
359
|
+
}
|
|
360
|
+
const code = await readFile(outputFile, "utf-8");
|
|
361
|
+
const encoded = Buffer.from(code).toString("base64");
|
|
362
|
+
const dataUrl = `data:text/javascript;base64,${encoded}`;
|
|
363
|
+
const exports$1 = await import(dataUrl);
|
|
364
|
+
if (debug) {
|
|
365
|
+
console.log("exports", exports$1);
|
|
366
|
+
}
|
|
367
|
+
let vdom = exports$1.default(exports$1);
|
|
368
|
+
for (const plugin of config.plugins || []) {
|
|
369
|
+
if (plugin.phase === "page-vdom" && (plugin.mode === mode || plugin.mode === "both")) {
|
|
370
|
+
if (debug) {
|
|
371
|
+
console.log(`Running page-vdom plugin: ${plugin.name}`);
|
|
372
|
+
}
|
|
373
|
+
vdom = await plugin.fn(
|
|
374
|
+
vdom,
|
|
375
|
+
relativeOutputHtmlFilePath,
|
|
376
|
+
projectDir,
|
|
377
|
+
config,
|
|
378
|
+
exports$1
|
|
379
|
+
);
|
|
353
380
|
}
|
|
354
|
-
vdom = await plugin.fn(
|
|
355
|
-
vdom,
|
|
356
|
-
relativeOutputHtmlFilePath,
|
|
357
|
-
projectDir,
|
|
358
|
-
config,
|
|
359
|
-
exports$1
|
|
360
|
-
);
|
|
361
381
|
}
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
382
|
+
const browserGlobals = getBrowserGlobals();
|
|
383
|
+
const document = getDocument(false, browserGlobals);
|
|
384
|
+
browserGlobals.document = document;
|
|
385
|
+
let el = renderSync(vdom, document.documentElement, {
|
|
386
|
+
browserGlobals
|
|
387
|
+
});
|
|
388
|
+
for (const plugin of config.plugins || []) {
|
|
389
|
+
if (plugin.phase === "page-dom" && (plugin.mode === mode || plugin.mode === "both")) {
|
|
390
|
+
if (debug) {
|
|
391
|
+
console.log(`Running page-dom plugin: ${plugin.name}`);
|
|
392
|
+
}
|
|
393
|
+
el = await plugin.fn(
|
|
394
|
+
el,
|
|
395
|
+
relativeOutputHtmlFilePath,
|
|
396
|
+
projectDir,
|
|
397
|
+
config
|
|
398
|
+
);
|
|
373
399
|
}
|
|
374
|
-
el = await plugin.fn(
|
|
375
|
-
el,
|
|
376
|
-
relativeOutputHtmlFilePath,
|
|
377
|
-
projectDir,
|
|
378
|
-
config
|
|
379
|
-
);
|
|
380
400
|
}
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
401
|
+
let html = renderToString(el);
|
|
402
|
+
for (const plugin of config.plugins || []) {
|
|
403
|
+
if (plugin.phase === "page-html" && (plugin.mode === mode || plugin.mode === "both")) {
|
|
404
|
+
if (debug) {
|
|
405
|
+
console.log(`Running page-html plugin: ${plugin.name}`);
|
|
406
|
+
}
|
|
407
|
+
html = await plugin.fn(
|
|
408
|
+
html,
|
|
409
|
+
relativeOutputHtmlFilePath,
|
|
410
|
+
projectDir,
|
|
411
|
+
config
|
|
412
|
+
);
|
|
387
413
|
}
|
|
388
|
-
html = await plugin.fn(
|
|
389
|
-
html,
|
|
390
|
-
relativeOutputHtmlFilePath,
|
|
391
|
-
projectDir,
|
|
392
|
-
config
|
|
393
|
-
);
|
|
394
414
|
}
|
|
415
|
+
const finalOutputFile = join(
|
|
416
|
+
projectDir,
|
|
417
|
+
config.output,
|
|
418
|
+
relativeOutputHtmlFilePath
|
|
419
|
+
);
|
|
420
|
+
const finalOutputDir = dirname(finalOutputFile);
|
|
421
|
+
if (!existsSync(finalOutputDir)) {
|
|
422
|
+
mkdirSync(finalOutputDir, { recursive: true });
|
|
423
|
+
}
|
|
424
|
+
await writeFile(finalOutputFile, html);
|
|
395
425
|
}
|
|
396
|
-
if (debug) {
|
|
397
|
-
console.log("Writing HTML file", outputHtmlFilePath);
|
|
398
|
-
}
|
|
399
|
-
if (debug) {
|
|
400
|
-
console.log("Relative HTML path:", relativeOutputHtmlFilePath);
|
|
401
|
-
}
|
|
402
|
-
const finalOutputFile = join(
|
|
403
|
-
projectDir,
|
|
404
|
-
config.output,
|
|
405
|
-
relativeOutputHtmlFilePath
|
|
406
|
-
);
|
|
407
|
-
if (debug) {
|
|
408
|
-
console.log("Full HTML output path:", finalOutputFile);
|
|
409
|
-
}
|
|
410
|
-
const finalOutputDir = dirname(finalOutputFile);
|
|
411
|
-
if (!existsSync(finalOutputDir)) {
|
|
412
|
-
mkdirSync(finalOutputDir, { recursive: true });
|
|
413
|
-
}
|
|
414
|
-
await writeFile(finalOutputFile, html);
|
|
415
426
|
}
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
427
|
+
if (isFullBuild || changeKind === "component") {
|
|
428
|
+
await cp(tmpComponentsDir, outputComponentsDir, { recursive: true });
|
|
429
|
+
}
|
|
430
|
+
if (isFullBuild || changeKind === "asset") {
|
|
431
|
+
await cp(inputAssetsDir, outputAssetsDir, { recursive: true });
|
|
432
|
+
}
|
|
433
|
+
if (isFullBuild || changeKind === "component") {
|
|
434
|
+
for (const plugin of config.plugins || []) {
|
|
435
|
+
if (plugin.phase === "post" && (plugin.mode === mode || plugin.mode === "both")) {
|
|
436
|
+
if (debug) {
|
|
437
|
+
console.log(`Running post-plugin: ${plugin.name}`);
|
|
438
|
+
}
|
|
439
|
+
await plugin.fn(projectDir, config);
|
|
422
440
|
}
|
|
423
|
-
await plugin.fn(projectDir, config);
|
|
424
441
|
}
|
|
425
442
|
}
|
|
426
|
-
if (!debug) {
|
|
443
|
+
if (mode === "build" && !debug) {
|
|
427
444
|
rmSync(config.tmp, { recursive: true });
|
|
428
445
|
}
|
|
429
446
|
const endTime = performance.now();
|
|
430
447
|
const totalTime = (endTime - startTime) / 1e3;
|
|
431
|
-
|
|
448
|
+
const label = isFullBuild ? "Full build" : `Incremental build (${changeKind}: ${changedRelative})`;
|
|
449
|
+
console.log(`${label} completed in ${totalTime.toFixed(2)} seconds.`);
|
|
432
450
|
return { code: "OK", message: "Build completed successfully" };
|
|
433
451
|
};
|
|
434
452
|
|
|
@@ -491,10 +509,10 @@ const serve = async ({
|
|
|
491
509
|
path: "/livereload"
|
|
492
510
|
});
|
|
493
511
|
let isBuilding = false;
|
|
494
|
-
let pendingBuild =
|
|
512
|
+
let pendingBuild = null;
|
|
495
513
|
const triggerBuild = async (filePath) => {
|
|
496
514
|
if (isBuilding) {
|
|
497
|
-
pendingBuild =
|
|
515
|
+
pendingBuild = filePath;
|
|
498
516
|
if (debug) {
|
|
499
517
|
console.log("Build scheduled after current one completes");
|
|
500
518
|
}
|
|
@@ -502,7 +520,7 @@ const serve = async ({
|
|
|
502
520
|
}
|
|
503
521
|
isBuilding = true;
|
|
504
522
|
try {
|
|
505
|
-
await build({ projectDir, debug, mode: "serve" });
|
|
523
|
+
await build({ projectDir, debug, mode: "serve", changedFile: filePath });
|
|
506
524
|
liveReloadServer.clients.forEach((client) => {
|
|
507
525
|
if (client.readyState === 1) {
|
|
508
526
|
client.send(
|
|
@@ -518,11 +536,12 @@ const serve = async ({
|
|
|
518
536
|
} finally {
|
|
519
537
|
isBuilding = false;
|
|
520
538
|
if (pendingBuild) {
|
|
521
|
-
|
|
539
|
+
const pending = pendingBuild;
|
|
540
|
+
pendingBuild = null;
|
|
522
541
|
if (debug) {
|
|
523
542
|
console.log("Running pending build");
|
|
524
543
|
}
|
|
525
|
-
await triggerBuild(
|
|
544
|
+
await triggerBuild(pending);
|
|
526
545
|
}
|
|
527
546
|
}
|
|
528
547
|
};
|
|
@@ -30,6 +30,12 @@ interface BuildOptions {
|
|
|
30
30
|
* Defaults to "build"
|
|
31
31
|
*/
|
|
32
32
|
mode: Omit<BuildMode, "both">;
|
|
33
|
+
/**
|
|
34
|
+
* When set, only the changed file is rebuilt instead of the entire project.
|
|
35
|
+
* This is used by the dev server for incremental rebuilds.
|
|
36
|
+
* The path should be absolute.
|
|
37
|
+
*/
|
|
38
|
+
changedFile?: string;
|
|
33
39
|
}
|
|
34
40
|
type PluginFn = PluginFnPageHtml | PluginFnPageVdom | PluginFnPageDom | PluginFnPrePost;
|
|
35
41
|
/**
|
|
@@ -30,6 +30,12 @@ interface BuildOptions {
|
|
|
30
30
|
* Defaults to "build"
|
|
31
31
|
*/
|
|
32
32
|
mode: Omit<BuildMode, "both">;
|
|
33
|
+
/**
|
|
34
|
+
* When set, only the changed file is rebuilt instead of the entire project.
|
|
35
|
+
* This is used by the dev server for incremental rebuilds.
|
|
36
|
+
* The path should be absolute.
|
|
37
|
+
*/
|
|
38
|
+
changedFile?: string;
|
|
33
39
|
}
|
|
34
40
|
type PluginFn = PluginFnPageHtml | PluginFnPageVdom | PluginFnPageDom | PluginFnPrePost;
|
|
35
41
|
/**
|