slidev-workspace 0.5.1 → 0.6.0
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.js +79 -5
- package/dist/index.js +10 -7
- package/dist/plugin-slides.js +29 -1
- package/package.json +1 -1
- package/src/preview/composables/useSlides.ts +5 -3
package/dist/cli.js
CHANGED
|
@@ -2,12 +2,12 @@
|
|
|
2
2
|
import { fileURLToPath } from "node:url";
|
|
3
3
|
import { dirname, join, resolve } from "node:path";
|
|
4
4
|
import { existsSync, mkdirSync, readdirSync } from "node:fs";
|
|
5
|
-
import { cp } from "node:fs/promises";
|
|
5
|
+
import { cp, rm } from "node:fs/promises";
|
|
6
6
|
import { execSync } from "node:child_process";
|
|
7
7
|
import { build, createServer } from "vite";
|
|
8
8
|
import vue from "@vitejs/plugin-vue";
|
|
9
9
|
import tailwindcss from "@tailwindcss/vite";
|
|
10
|
-
import { existsSync as existsSync$1, readFileSync, readdirSync as readdirSync$1, watch } from "fs";
|
|
10
|
+
import { cpSync, existsSync as existsSync$1, readFileSync, readdirSync as readdirSync$1, watch } from "fs";
|
|
11
11
|
import { basename, join as join$1, resolve as resolve$1 } from "path";
|
|
12
12
|
import { parse } from "yaml";
|
|
13
13
|
import { spawn } from "child_process";
|
|
@@ -219,6 +219,34 @@ function slidesPlugin() {
|
|
|
219
219
|
let devServers = [];
|
|
220
220
|
return {
|
|
221
221
|
name: "vite-plugin-slides",
|
|
222
|
+
async closeBundle() {
|
|
223
|
+
try {
|
|
224
|
+
const config = loadConfig();
|
|
225
|
+
const slidesDirs = resolveSlidesDirs(config);
|
|
226
|
+
for (const slidesDir of slidesDirs) {
|
|
227
|
+
if (!existsSync$1(slidesDir)) continue;
|
|
228
|
+
const slideDirs = readdirSync$1(slidesDir, { withFileTypes: true }).filter((dirent) => dirent.isDirectory()).filter((dirent) => !(config.exclude || []).includes(dirent.name)).map((dirent) => dirent.name);
|
|
229
|
+
for (const slideDir of slideDirs) {
|
|
230
|
+
const slideDistPath = join$1(slidesDir, slideDir, "dist");
|
|
231
|
+
const assetsPath = join$1(slideDistPath, "assets");
|
|
232
|
+
if (!existsSync$1(assetsPath)) continue;
|
|
233
|
+
const assetFiles = readdirSync$1(assetsPath);
|
|
234
|
+
const ogImageFile = assetFiles.find((file) => /^og-image-[a-zA-Z0-9]+\.png$/.test(file));
|
|
235
|
+
if (ogImageFile) {
|
|
236
|
+
const sourceFile = join$1(assetsPath, ogImageFile);
|
|
237
|
+
const destFile = join$1(slideDistPath, "og-image.png");
|
|
238
|
+
try {
|
|
239
|
+
cpSync(sourceFile, destFile, { force: true });
|
|
240
|
+
} catch (error) {
|
|
241
|
+
console.warn(`⚠ Failed to copy og-image for ${slideDir}:`, error);
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
} catch (error) {
|
|
247
|
+
console.warn("⚠ og-image post-build error:", error);
|
|
248
|
+
}
|
|
249
|
+
},
|
|
222
250
|
async configureServer(server) {
|
|
223
251
|
const watchers = [];
|
|
224
252
|
const config = loadConfig();
|
|
@@ -337,6 +365,46 @@ async function buildAllSlides() {
|
|
|
337
365
|
}
|
|
338
366
|
}
|
|
339
367
|
}
|
|
368
|
+
async function exportOgImages() {
|
|
369
|
+
const workspaceCwd = process.env.SLIDEV_WORKSPACE_CWD || process.cwd();
|
|
370
|
+
const config = loadConfig(workspaceCwd);
|
|
371
|
+
const slidesDirs = resolveSlidesDirs(config, workspaceCwd);
|
|
372
|
+
console.log("🖼️ Exporting OG images for all slides...");
|
|
373
|
+
try {
|
|
374
|
+
execSync("pnpm -r export --format png --range 1", {
|
|
375
|
+
cwd: workspaceCwd,
|
|
376
|
+
stdio: "inherit"
|
|
377
|
+
});
|
|
378
|
+
console.log("📦 Copying exported images to og-image.png...");
|
|
379
|
+
for (const slidesDir of slidesDirs) {
|
|
380
|
+
if (!existsSync(slidesDir)) {
|
|
381
|
+
console.warn(`⚠️ Slides directory not found: ${slidesDir}`);
|
|
382
|
+
continue;
|
|
383
|
+
}
|
|
384
|
+
const slides = readdirSync(slidesDir, { withFileTypes: true }).filter((dirent) => dirent.isDirectory()).map((dirent) => dirent.name);
|
|
385
|
+
for (const slideName of slides) {
|
|
386
|
+
const slideDir = join(slidesDir, slideName);
|
|
387
|
+
const packageJsonPath = join(slideDir, "package.json");
|
|
388
|
+
if (!existsSync(packageJsonPath)) continue;
|
|
389
|
+
const exportedFile = join(slideDir, "slides-export", "1.png");
|
|
390
|
+
const targetFile = join(slideDir, "og-image.png");
|
|
391
|
+
const exportDir = join(slideDir, "slides-export");
|
|
392
|
+
if (existsSync(exportedFile)) {
|
|
393
|
+
await cp(exportedFile, targetFile);
|
|
394
|
+
console.log(`✅ Generated OG image for: ${slideName}`);
|
|
395
|
+
await rm(exportDir, {
|
|
396
|
+
recursive: true,
|
|
397
|
+
force: true
|
|
398
|
+
});
|
|
399
|
+
} else console.warn(`⚠️ Export file not found for ${slideName}: ${exportedFile}`);
|
|
400
|
+
}
|
|
401
|
+
}
|
|
402
|
+
console.log("✅ All OG images exported successfully!");
|
|
403
|
+
} catch (error) {
|
|
404
|
+
console.error("❌ Failed to export OG images:", error);
|
|
405
|
+
process.exit(1);
|
|
406
|
+
}
|
|
407
|
+
}
|
|
340
408
|
async function copyToGhPages() {
|
|
341
409
|
const workspaceCwd = process.env.SLIDEV_WORKSPACE_CWD || process.cwd();
|
|
342
410
|
const config = loadConfig(workspaceCwd);
|
|
@@ -396,13 +464,15 @@ Usage:
|
|
|
396
464
|
slidev-workspace <command> [options]
|
|
397
465
|
|
|
398
466
|
Commands:
|
|
399
|
-
dev
|
|
400
|
-
build
|
|
401
|
-
|
|
467
|
+
dev Start the development server
|
|
468
|
+
build Build the project for production
|
|
469
|
+
export-og Export OG images for all slides
|
|
470
|
+
help Show this help message
|
|
402
471
|
|
|
403
472
|
Examples:
|
|
404
473
|
slidev-workspace dev # Start development server
|
|
405
474
|
slidev-workspace build # Build all slides and preview app
|
|
475
|
+
slidev-workspace export-og # Export OG images for all slides
|
|
406
476
|
|
|
407
477
|
Configuration:
|
|
408
478
|
Use slidev-workspace.yml to set baseUrl for all builds
|
|
@@ -421,6 +491,10 @@ async function main() {
|
|
|
421
491
|
process.env.SLIDEV_WORKSPACE_CWD = process.cwd();
|
|
422
492
|
await runViteBuild();
|
|
423
493
|
break;
|
|
494
|
+
case "export-og":
|
|
495
|
+
process.env.SLIDEV_WORKSPACE_CWD = process.cwd();
|
|
496
|
+
await exportOgImages();
|
|
497
|
+
break;
|
|
424
498
|
case "help":
|
|
425
499
|
case "--help":
|
|
426
500
|
case "-h":
|
package/dist/index.js
CHANGED
|
@@ -55,18 +55,21 @@ function isUrl(str) {
|
|
|
55
55
|
* returns: "http://localhost:3001/og-image.png"
|
|
56
56
|
*
|
|
57
57
|
* Example (production mode with og-image.png):
|
|
58
|
-
* returns: "https://my-slides.com/slidev-workspace-starter/og-image.png"
|
|
58
|
+
* returns: "https://my-slides.com/slidev-workspace-starter/og-image.png?v=<hash>"
|
|
59
59
|
*/
|
|
60
60
|
function resolveImageUrl(slide, domain) {
|
|
61
61
|
const { hasOgImage, path: slidePath, baseUrl, frontmatter } = slide;
|
|
62
62
|
const seoOgImage = frontmatter.seoMeta?.ogImage;
|
|
63
63
|
const background = frontmatter.background;
|
|
64
|
-
if (hasOgImage)
|
|
65
|
-
const
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
64
|
+
if (hasOgImage) {
|
|
65
|
+
const imagePath = `og-image.png?v=${Date.now()}`;
|
|
66
|
+
try {
|
|
67
|
+
const path = IS_DEVELOPMENT ? pathJoin(slidePath, imagePath) : pathJoin(baseUrl, slidePath, imagePath);
|
|
68
|
+
return new URL(path, domain).href;
|
|
69
|
+
} catch (error) {
|
|
70
|
+
console.error("Failed to resolve og-image.png path:", error);
|
|
71
|
+
return "https://cover.sli.dev";
|
|
72
|
+
}
|
|
70
73
|
}
|
|
71
74
|
if (seoOgImage) {
|
|
72
75
|
if (isUrl(seoOgImage)) return seoOgImage;
|
package/dist/plugin-slides.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { existsSync, readFileSync, readdirSync, watch } from "fs";
|
|
1
|
+
import { cpSync, existsSync, readFileSync, readdirSync, watch } from "fs";
|
|
2
2
|
import { basename, join, resolve } from "path";
|
|
3
3
|
import { parse } from "yaml";
|
|
4
4
|
import { spawn } from "child_process";
|
|
@@ -210,6 +210,34 @@ function slidesPlugin() {
|
|
|
210
210
|
let devServers = [];
|
|
211
211
|
return {
|
|
212
212
|
name: "vite-plugin-slides",
|
|
213
|
+
async closeBundle() {
|
|
214
|
+
try {
|
|
215
|
+
const config = loadConfig();
|
|
216
|
+
const slidesDirs = resolveSlidesDirs(config);
|
|
217
|
+
for (const slidesDir of slidesDirs) {
|
|
218
|
+
if (!existsSync(slidesDir)) continue;
|
|
219
|
+
const slideDirs = readdirSync(slidesDir, { withFileTypes: true }).filter((dirent) => dirent.isDirectory()).filter((dirent) => !(config.exclude || []).includes(dirent.name)).map((dirent) => dirent.name);
|
|
220
|
+
for (const slideDir of slideDirs) {
|
|
221
|
+
const slideDistPath = join(slidesDir, slideDir, "dist");
|
|
222
|
+
const assetsPath = join(slideDistPath, "assets");
|
|
223
|
+
if (!existsSync(assetsPath)) continue;
|
|
224
|
+
const assetFiles = readdirSync(assetsPath);
|
|
225
|
+
const ogImageFile = assetFiles.find((file) => /^og-image-[a-zA-Z0-9]+\.png$/.test(file));
|
|
226
|
+
if (ogImageFile) {
|
|
227
|
+
const sourceFile = join(assetsPath, ogImageFile);
|
|
228
|
+
const destFile = join(slideDistPath, "og-image.png");
|
|
229
|
+
try {
|
|
230
|
+
cpSync(sourceFile, destFile, { force: true });
|
|
231
|
+
} catch (error) {
|
|
232
|
+
console.warn(`⚠ Failed to copy og-image for ${slideDir}:`, error);
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
} catch (error) {
|
|
238
|
+
console.warn("⚠ og-image post-build error:", error);
|
|
239
|
+
}
|
|
240
|
+
},
|
|
213
241
|
async configureServer(server) {
|
|
214
242
|
const watchers = [];
|
|
215
243
|
const config = loadConfig();
|
package/package.json
CHANGED
|
@@ -28,7 +28,7 @@ function isUrl(str: string | undefined): boolean {
|
|
|
28
28
|
* returns: "http://localhost:3001/og-image.png"
|
|
29
29
|
*
|
|
30
30
|
* Example (production mode with og-image.png):
|
|
31
|
-
* returns: "https://my-slides.com/slidev-workspace-starter/og-image.png"
|
|
31
|
+
* returns: "https://my-slides.com/slidev-workspace-starter/og-image.png?v=<hash>"
|
|
32
32
|
*/
|
|
33
33
|
export function resolveImageUrl(slide: SlideInfo, domain: string): string {
|
|
34
34
|
const { hasOgImage, path: slidePath, baseUrl, frontmatter } = slide;
|
|
@@ -37,10 +37,12 @@ export function resolveImageUrl(slide: SlideInfo, domain: string): string {
|
|
|
37
37
|
|
|
38
38
|
// Priority 1: og-image.png (if exists)
|
|
39
39
|
if (hasOgImage) {
|
|
40
|
+
const imagePath = `og-image.png?v=${Date.now()}`;
|
|
40
41
|
try {
|
|
41
42
|
const path = IS_DEVELOPMENT
|
|
42
|
-
?
|
|
43
|
-
: pathJoin(baseUrl,
|
|
43
|
+
? pathJoin(slidePath, imagePath)
|
|
44
|
+
: pathJoin(baseUrl, slidePath, imagePath);
|
|
45
|
+
|
|
44
46
|
return new URL(path, domain).href;
|
|
45
47
|
} catch (error) {
|
|
46
48
|
console.error("Failed to resolve og-image.png path:", error);
|