feat: manage Chromium installation in engine
Engine CI / test (push) Waiting to run

This commit is contained in:
2026-08-30 18:51:35 +08:00
parent fef7459650
commit e3b0b2d576
17 changed files with 139 additions and 3 deletions
+1 -1
View File
@@ -20,5 +20,5 @@ jobs:
- run: pnpm verify - run: pnpm verify
- name: Verify committed Git distribution - name: Verify committed Git distribution
run: git diff --exit-code -- dist-cli run: git diff --exit-code -- dist-cli
- run: pnpm exec playwright install --with-deps chromium - run: node dist-cli/cli.js install-browser --with-deps
- run: pnpm test:e2e - run: pnpm test:e2e
+3
View File
@@ -122,6 +122,7 @@ export default {
pnpm dev -- <slug|slides.md> pnpm dev -- <slug|slides.md>
pnpm present -- <slug> pnpm present -- <slug>
pnpm check pnpm check
pnpm exec easy-slides install-browser
pnpm build pnpm build
pnpm export -- <slug> --format pdf pnpm export -- <slug> --format pdf
pnpm export -- <slug> --format png pnpm export -- <slug> --format png
@@ -130,6 +131,8 @@ pnpm export -- <slug> --format pptx
`dev` 提供 VS Code/浏览器实时预览。`present` 监听局域网,打印观众地址、带同步密码的演示者二维码和手机遥控入口。`build` 扫描全部非 draft 演示,生成博客式首页与 `/<slug>/` 静态站点。 `dev` 提供 VS Code/浏览器实时预览。`present` 监听局域网,打印观众地址、带同步密码的演示者二维码和手机遥控入口。`build` 扫描全部非 draft 演示,生成博客式首页与 `/<slug>/` 静态站点。
`build` 的最终排版检查会启动引擎版本匹配的 Chromium。首次构建前运行 `pnpm exec easy-slides install-browser`Linux CI 建议运行 `pnpm exec easy-slides install-browser --with-deps`,同时安装 Chromium 所需的系统依赖。`easy-slides init` 生成的 GitHub Pages workflow 已自动包含这一步,内容仓库不需要直接依赖或调用 `playwright-chromium`
## 主题与演示能力 ## 主题与演示能力
CLI 会自动加载其版本匹配的 `slidev-theme-easy-jyy`,内容仓库不需要复制主题源码。 CLI 会自动加载其版本匹配的 `slidev-theme-easy-jyy`,内容仓库不需要复制主题源码。
+4
View File
@@ -30,6 +30,9 @@ switch (command) {
case 'init': case 'init':
await import("./init.js"); await import("./init.js");
break; break;
case 'install-browser':
await import("./install-browser.js");
break;
case undefined: case undefined:
case 'help': case 'help':
case '--help': case '--help':
@@ -46,6 +49,7 @@ function printHelp() {
用法: 用法:
easy-slides init [directory] [--engine <package-spec>] easy-slides init [directory] [--engine <package-spec>]
easy-slides install-browser [--with-deps]
easy-slides dev [slug|slides.md] easy-slides dev [slug|slides.md]
easy-slides present <slug> easy-slides present <slug>
easy-slides build easy-slides build
+1 -1
View File
@@ -1 +1 @@
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../scripts/cli.ts"],"names":[],"mappings":";AACA,OAAO,IAAI,MAAM,WAAW,CAAA;AAE5B,MAAM,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAA;AACrC,MAAM,OAAO,GAAG,OAAO,CAAC,KAAK,EAAE,CAAA;AAC/B,MAAM,SAAS,GAAG,OAAO,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAA;AAC3C,IAAI,SAAS,IAAI,CAAC,EAAE,CAAC;IACnB,MAAM,IAAI,GAAG,OAAO,CAAC,SAAS,GAAG,CAAC,CAAC,CAAA;IACnC,IAAI,CAAC,IAAI;QACP,MAAM,IAAI,KAAK,CAAC,eAAe,CAAC,CAAA;IAClC,OAAO,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,CAAC,CAAA;IAC5B,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAA;AACnC,CAAC;AACD,OAAO,CAAC,IAAI,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,GAAG,OAAO,CAAC,CAAA;AAE7D,QAAQ,OAAO,EAAE,CAAC;IAChB,KAAK,KAAK;QACR,MAAM,MAAM,CAAC,UAAU,CAAC,CAAA;QACxB,MAAK;IACP,KAAK,SAAS;QACZ,MAAM,MAAM,CAAC,cAAc,CAAC,CAAA;QAC5B,MAAK;IACP,KAAK,OAAO;QACV,MAAM,MAAM,CAAC,YAAY,CAAC,CAAA;QAC1B,MAAK;IACP,KAAK,OAAO;QACV,MAAM,CAAC,MAAM,MAAM,CAAC,YAAY,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAA;QAC7C,MAAK;IACP,KAAK,QAAQ;QACX,MAAM,MAAM,CAAC,aAAa,CAAC,CAAA;QAC3B,MAAK;IACP,KAAK,MAAM;QACT,MAAM,MAAM,CAAC,WAAW,CAAC,CAAA;QACzB,MAAK;IACP,KAAK,SAAS,CAAC;IACf,KAAK,MAAM,CAAC;IACZ,KAAK,QAAQ,CAAC;IACd,KAAK,IAAI;QACP,SAAS,EAAE,CAAA;QACX,MAAK;IACP;QACE,OAAO,CAAC,KAAK,CAAC,QAAQ,OAAO,EAAE,CAAC,CAAA;QAChC,SAAS,EAAE,CAAA;QACX,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAA;AACxB,CAAC;AAED,SAAS,SAAS;IAChB,OAAO,CAAC,GAAG,CAAC;;;;;;;;;;;iCAWmB,CAAC,CAAA;AAClC,CAAC"} {"version":3,"file":"cli.js","sourceRoot":"","sources":["../scripts/cli.ts"],"names":[],"mappings":";AACA,OAAO,IAAI,MAAM,WAAW,CAAA;AAE5B,MAAM,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAA;AACrC,MAAM,OAAO,GAAG,OAAO,CAAC,KAAK,EAAE,CAAA;AAC/B,MAAM,SAAS,GAAG,OAAO,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAA;AAC3C,IAAI,SAAS,IAAI,CAAC,EAAE,CAAC;IACnB,MAAM,IAAI,GAAG,OAAO,CAAC,SAAS,GAAG,CAAC,CAAC,CAAA;IACnC,IAAI,CAAC,IAAI;QACP,MAAM,IAAI,KAAK,CAAC,eAAe,CAAC,CAAA;IAClC,OAAO,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,CAAC,CAAA;IAC5B,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAA;AACnC,CAAC;AACD,OAAO,CAAC,IAAI,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,GAAG,OAAO,CAAC,CAAA;AAE7D,QAAQ,OAAO,EAAE,CAAC;IAChB,KAAK,KAAK;QACR,MAAM,MAAM,CAAC,UAAU,CAAC,CAAA;QACxB,MAAK;IACP,KAAK,SAAS;QACZ,MAAM,MAAM,CAAC,cAAc,CAAC,CAAA;QAC5B,MAAK;IACP,KAAK,OAAO;QACV,MAAM,MAAM,CAAC,YAAY,CAAC,CAAA;QAC1B,MAAK;IACP,KAAK,OAAO;QACV,MAAM,CAAC,MAAM,MAAM,CAAC,YAAY,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAA;QAC7C,MAAK;IACP,KAAK,QAAQ;QACX,MAAM,MAAM,CAAC,aAAa,CAAC,CAAA;QAC3B,MAAK;IACP,KAAK,MAAM;QACT,MAAM,MAAM,CAAC,WAAW,CAAC,CAAA;QACzB,MAAK;IACP,KAAK,iBAAiB;QACpB,MAAM,MAAM,CAAC,sBAAsB,CAAC,CAAA;QACpC,MAAK;IACP,KAAK,SAAS,CAAC;IACf,KAAK,MAAM,CAAC;IACZ,KAAK,QAAQ,CAAC;IACd,KAAK,IAAI;QACP,SAAS,EAAE,CAAA;QACX,MAAK;IACP;QACE,OAAO,CAAC,KAAK,CAAC,QAAQ,OAAO,EAAE,CAAC,CAAA;QAChC,SAAS,EAAE,CAAA;QACX,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAA;AACxB,CAAC;AAED,SAAS,SAAS;IAChB,OAAO,CAAC,GAAG,CAAC;;;;;;;;;;;;iCAYmB,CAAC,CAAA;AAClC,CAAC"}
+1
View File
@@ -93,6 +93,7 @@ jobs:
node-version: 22 node-version: 22
cache: pnpm cache: pnpm
- run: pnpm install --frozen-lockfile - run: pnpm install --frozen-lockfile
- run: pnpm exec easy-slides install-browser --with-deps
- run: pnpm check - run: pnpm check
env: env:
PRESENTER_TOKEN: \${{ secrets.PRESENTER_TOKEN }} PRESENTER_TOKEN: \${{ secrets.PRESENTER_TOKEN }}
+1 -1
View File
@@ -1 +1 @@
{"version":3,"file":"init.js","sourceRoot":"","sources":["../scripts/init.ts"],"names":[],"mappings":"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"} {"version":3,"file":"init.js","sourceRoot":"","sources":["../scripts/init.ts"],"names":[],"mappings":"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"}
+1
View File
@@ -0,0 +1 @@
export {};
+16
View File
@@ -0,0 +1,16 @@
import { spawn } from 'node:child_process';
import { createBrowserInstallCommand } from "./lib/browser-install.js";
const { command, args } = createBrowserInstallCommand(process.argv.slice(2));
const child = spawn(command, args, { stdio: 'inherit' });
child.once('error', (error) => {
console.error(`无法启动 Chromium 安装程序:${error.message}`);
process.exitCode = 1;
});
child.once('exit', (code, signal) => {
if (signal) {
process.kill(process.pid, signal);
return;
}
process.exitCode = code ?? 1;
});
//# sourceMappingURL=install-browser.js.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"install-browser.js","sourceRoot":"","sources":["../scripts/install-browser.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAA;AAC1C,OAAO,EAAE,2BAA2B,EAAE,MAAM,0BAA0B,CAAA;AAEtE,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,GAAG,2BAA2B,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAA;AAC5E,MAAM,KAAK,GAAG,KAAK,CAAC,OAAO,EAAE,IAAI,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC,CAAA;AAExD,KAAK,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,KAAK,EAAE,EAAE;IAC5B,OAAO,CAAC,KAAK,CAAC,sBAAsB,KAAK,CAAC,OAAO,EAAE,CAAC,CAAA;IACpD,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAA;AACtB,CAAC,CAAC,CAAA;AAEF,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE;IAClC,IAAI,MAAM,EAAE,CAAC;QACX,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,MAAM,CAAC,CAAA;QACjC,OAAM;IACR,CAAC;IACD,OAAO,CAAC,QAAQ,GAAG,IAAI,IAAI,CAAC,CAAA;AAC9B,CAAC,CAAC,CAAA"}
+5
View File
@@ -0,0 +1,5 @@
export interface BrowserInstallCommand {
command: string;
args: string[];
}
export declare function createBrowserInstallCommand(args: string[]): BrowserInstallCommand;
+23
View File
@@ -0,0 +1,23 @@
import { createRequire } from 'node:module';
import path from 'node:path';
const require = createRequire(import.meta.url);
export function createBrowserInstallCommand(args) {
const unsupported = args.filter(argument => argument !== '--with-deps');
const withDepsCount = args.filter(argument => argument === '--with-deps').length;
if (unsupported.length > 0)
throw new Error(`install-browser 不支持参数:${unsupported.join(' ')}`);
if (withDepsCount > 1)
throw new Error('install-browser 的 --with-deps 只能指定一次');
const packageJson = require.resolve('playwright-chromium/package.json');
const playwrightCli = path.join(path.dirname(packageJson), 'cli.js');
return {
command: process.execPath,
args: [
playwrightCli,
'install',
...(withDepsCount === 1 ? ['--with-deps'] : []),
'chromium',
],
};
}
//# sourceMappingURL=browser-install.js.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"browser-install.js","sourceRoot":"","sources":["../../scripts/lib/browser-install.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AAC3C,OAAO,IAAI,MAAM,WAAW,CAAA;AAE5B,MAAM,OAAO,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;AAO9C,MAAM,UAAU,2BAA2B,CAAC,IAAc;IACxD,MAAM,WAAW,GAAG,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,CAAC,QAAQ,KAAK,aAAa,CAAC,CAAA;IACvE,MAAM,aAAa,GAAG,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,CAAC,QAAQ,KAAK,aAAa,CAAC,CAAC,MAAM,CAAA;IAEhF,IAAI,WAAW,CAAC,MAAM,GAAG,CAAC;QACxB,MAAM,IAAI,KAAK,CAAC,yBAAyB,WAAW,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAA;IACnE,IAAI,aAAa,GAAG,CAAC;QACnB,MAAM,IAAI,KAAK,CAAC,sCAAsC,CAAC,CAAA;IAEzD,MAAM,WAAW,GAAG,OAAO,CAAC,OAAO,CAAC,kCAAkC,CAAC,CAAA;IACvE,MAAM,aAAa,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,EAAE,QAAQ,CAAC,CAAA;IAEpE,OAAO;QACL,OAAO,EAAE,OAAO,CAAC,QAAQ;QACzB,IAAI,EAAE;YACJ,aAAa;YACb,SAAS;YACT,GAAG,CAAC,aAAa,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;YAC/C,UAAU;SACX;KACF,CAAA;AACH,CAAC"}
+4
View File
@@ -32,6 +32,9 @@ switch (command) {
case 'init': case 'init':
await import('./init.ts') await import('./init.ts')
break break
case 'install-browser':
await import('./install-browser.ts')
break
case undefined: case undefined:
case 'help': case 'help':
case '--help': case '--help':
@@ -49,6 +52,7 @@ function printHelp() {
用法: 用法:
easy-slides init [directory] [--engine <package-spec>] easy-slides init [directory] [--engine <package-spec>]
easy-slides install-browser [--with-deps]
easy-slides dev [slug|slides.md] easy-slides dev [slug|slides.md]
easy-slides present <slug> easy-slides present <slug>
easy-slides build easy-slides build
+1
View File
@@ -101,6 +101,7 @@ jobs:
node-version: 22 node-version: 22
cache: pnpm cache: pnpm
- run: pnpm install --frozen-lockfile - run: pnpm install --frozen-lockfile
- run: pnpm exec easy-slides install-browser --with-deps
- run: pnpm check - run: pnpm check
env: env:
PRESENTER_TOKEN: \${{ secrets.PRESENTER_TOKEN }} PRESENTER_TOKEN: \${{ secrets.PRESENTER_TOKEN }}
+18
View File
@@ -0,0 +1,18 @@
import { spawn } from 'node:child_process'
import { createBrowserInstallCommand } from './lib/browser-install.ts'
const { command, args } = createBrowserInstallCommand(process.argv.slice(2))
const child = spawn(command, args, { stdio: 'inherit' })
child.once('error', (error) => {
console.error(`无法启动 Chromium 安装程序:${error.message}`)
process.exitCode = 1
})
child.once('exit', (code, signal) => {
if (signal) {
process.kill(process.pid, signal)
return
}
process.exitCode = code ?? 1
})
+32
View File
@@ -0,0 +1,32 @@
import { createRequire } from 'node:module'
import path from 'node:path'
const require = createRequire(import.meta.url)
export interface BrowserInstallCommand {
command: string
args: string[]
}
export function createBrowserInstallCommand(args: string[]): BrowserInstallCommand {
const unsupported = args.filter(argument => argument !== '--with-deps')
const withDepsCount = args.filter(argument => argument === '--with-deps').length
if (unsupported.length > 0)
throw new Error(`install-browser 不支持参数:${unsupported.join(' ')}`)
if (withDepsCount > 1)
throw new Error('install-browser 的 --with-deps 只能指定一次')
const packageJson = require.resolve('playwright-chromium/package.json')
const playwrightCli = path.join(path.dirname(packageJson), 'cli.js')
return {
command: process.execPath,
args: [
playwrightCli,
'install',
...(withDepsCount === 1 ? ['--with-deps'] : []),
'chromium',
],
}
}
+26
View File
@@ -10,8 +10,34 @@ import { joinBase, normalizeSiteBase } from '../scripts/lib/site-base.ts'
import { StaticOverflowAuditor, auditStaticDecks } from '../scripts/lib/static-overflow.ts' import { StaticOverflowAuditor, auditStaticDecks } from '../scripts/lib/static-overflow.ts'
import { hasPresenterToken, hashPresenterToken } from '../scripts/lib/token.ts' import { hasPresenterToken, hashPresenterToken } from '../scripts/lib/token.ts'
import { auditBuiltDecks } from '../scripts/lib/overflow-audit.ts' import { auditBuiltDecks } from '../scripts/lib/overflow-audit.ts'
import { createBrowserInstallCommand } from '../scripts/lib/browser-install.ts'
import { resolveImageSource } from '../packages/slidev-theme-easy-jyy/utils/resolve-image.ts' import { resolveImageSource } from '../packages/slidev-theme-easy-jyy/utils/resolve-image.ts'
describe('browser installation', () => {
it('uses the Chromium-only Playwright CLI bundled with the engine', () => {
const command = createBrowserInstallCommand([])
expect(command.command).toBe(process.execPath)
expect(command.args.at(-3)).toMatch(/playwright-chromium[/\\]cli\.js$/)
expect(command.args.slice(-2)).toEqual(['install', 'chromium'])
})
it('supports Linux system dependency installation and rejects unknown options', () => {
expect(createBrowserInstallCommand(['--with-deps']).args.slice(-3)).toEqual([
'install',
'--with-deps',
'chromium',
])
expect(() => createBrowserInstallCommand(['--firefox'])).toThrow('不支持参数')
expect(() => createBrowserInstallCommand(['--with-deps', '--with-deps'])).toThrow('只能指定一次')
})
it('includes browser installation in generated CI workflows', async () => {
const source = await readFile(path.join(process.cwd(), 'scripts/init.ts'), 'utf8')
expect(source).toContain('pnpm exec easy-slides install-browser --with-deps')
})
})
function overflowingList(title: string, count: number) { function overflowingList(title: string, count: number) {
return `# ${title}\n\n${Array.from({ length: count }, (_, index) => `- ${index + 1} `).join('\n')}\n` return `# ${title}\n\n${Array.from({ length: count }, (_, index) => `- ${index + 1} `).join('\n')}\n`
} }