mirror of
https://github.com/heygen-com/hyperframes.git
synced 2026-09-03 04:38:33 +00:00
fix(cli): lazy-load @puppeteer/browsers to prevent debug package crash (#1185)
* fix(cli): lazy-load @puppeteer/browsers to prevent debug package crash
Convert the static `import { ... } from "@puppeteer/browsers"` in
browser/manager.ts to dynamic imports inside the async functions that
use them. This eliminates a module-load-time crash when the transitive
`debug` dependency is missing or corrupted.
Previously, every CLI command (including init, lint, docs, help) would
crash with "Cannot find package debug" if the debug package was absent —
even though only browser-related commands need @puppeteer/browsers.
Also add `debug` as a direct dependency so npm/bun always installs it
explicitly rather than relying on transitive resolution.
PostHog data: ~3,955 total-CLI-crash occurrences since May 29.
* fix(cli): simplify isLinuxArm to sync inline check and surface real load error
isLinuxArm() was async only to call detectBrowserPlatform() from
@puppeteer/browsers, but that function just checks process.platform +
process.arch under the hood. Replace with a direct inline check and make
the function sync — no behavioral change, removes an unnecessary async
boundary and an eager load of the package we're trying to lazy-load.
Also surface the real error from loadPuppeteerBrowsers() catch block instead
of hard-coding 'likely missing transitive dependency "debug"' — the actual
cause could be anything (missing package, corrupt install, wrong Node ABI).
This commit is contained in:
@@ -29,6 +29,7 @@
|
||||
"adm-zip": "^0.5.16",
|
||||
"citty": "^0.2.1",
|
||||
"compare-versions": "^6.1.1",
|
||||
"debug": "^4.4.0",
|
||||
"esbuild": "^0.25.12",
|
||||
"fontkit": "^2.0.4",
|
||||
"giget": "^3.2.0",
|
||||
|
||||
@@ -3,7 +3,20 @@ import { existsSync, readdirSync, rmSync } from "node:fs";
|
||||
import { basename } from "node:path";
|
||||
import { homedir } from "node:os";
|
||||
import { join } from "node:path";
|
||||
import { Browser, detectBrowserPlatform, getInstalledBrowsers, install } from "@puppeteer/browsers";
|
||||
|
||||
type PuppeteerBrowsers = typeof import("@puppeteer/browsers");
|
||||
|
||||
async function loadPuppeteerBrowsers(): Promise<PuppeteerBrowsers> {
|
||||
try {
|
||||
return await import("@puppeteer/browsers");
|
||||
} catch (err) {
|
||||
const cause = err instanceof Error ? err.message : String(err);
|
||||
throw new Error(
|
||||
`Failed to load @puppeteer/browsers: ${cause}\n` +
|
||||
`Fix: run \`npm install\` or \`bun install\` to restore missing packages, then retry.`,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const CHROME_VERSION = "131.0.6778.85";
|
||||
const CACHE_DIR = join(homedir(), ".cache", "hyperframes", "chrome");
|
||||
@@ -84,6 +97,7 @@ async function findFromCache(): Promise<BrowserResult | undefined> {
|
||||
// download-of-last-resort). This is the fallback path: only reached when
|
||||
// no puppeteer-cache binary exists.
|
||||
if (existsSync(CACHE_DIR)) {
|
||||
const { Browser, getInstalledBrowsers } = await loadPuppeteerBrowsers();
|
||||
const installed = await getInstalledBrowsers({ cacheDir: CACHE_DIR });
|
||||
const match = installed.find((b) => b.browser === Browser.CHROMEHEADLESSSHELL);
|
||||
if (match) {
|
||||
@@ -303,6 +317,8 @@ export async function ensureBrowser(options?: EnsureBrowserOptions): Promise<Bro
|
||||
const existing = await findBrowser();
|
||||
if (existing) return existing;
|
||||
|
||||
const { Browser, detectBrowserPlatform, install } = await loadPuppeteerBrowsers();
|
||||
|
||||
const platform = detectBrowserPlatform();
|
||||
if (!platform) {
|
||||
throw new Error(`Unsupported platform: ${process.platform} ${process.arch}`);
|
||||
@@ -338,7 +354,7 @@ export function clearBrowser(): boolean {
|
||||
}
|
||||
|
||||
export function isLinuxArm(): boolean {
|
||||
return detectBrowserPlatform() === "linux_arm";
|
||||
return process.platform === "linux" && process.arch === "arm64";
|
||||
}
|
||||
|
||||
export { CHROME_VERSION, CACHE_DIR };
|
||||
|
||||
Reference in New Issue
Block a user