mirror of
https://github.com/yaklang/yaklang-chrome-extension.git
synced 2026-09-22 03:10:43 +08:00
82 lines
3.0 KiB
JavaScript
82 lines
3.0 KiB
JavaScript
import { createInterface } from 'node:readline';
|
|
import { spawn } from 'node:child_process';
|
|
import { access, mkdir, realpath } from 'node:fs/promises';
|
|
import { constants } from 'node:fs';
|
|
import { resolve } from 'node:path';
|
|
|
|
const root = process.cwd();
|
|
const output = resolve(root, '.output/chrome-mv3-dev');
|
|
const manifest = resolve(output, 'manifest.json');
|
|
const profile = resolve(root, '.wxt/chrome-wsl-profile');
|
|
const chrome = process.env.CHROME_PATH || '/usr/bin/google-chrome';
|
|
|
|
await access(chrome, constants.X_OK).catch(() => {
|
|
throw new Error(`Chrome is not executable: ${chrome}. Set CHROME_PATH to override it.`);
|
|
});
|
|
await mkdir(profile, { recursive: true });
|
|
const resolvedChrome = await realpath(chrome);
|
|
const isBrandedChrome = resolvedChrome.startsWith('/opt/google/chrome/');
|
|
|
|
const wxt = spawn(process.execPath, [resolve(root, 'node_modules/wxt/bin/wxt.mjs')], {
|
|
cwd: root,
|
|
env: process.env,
|
|
stdio: ['inherit', 'pipe', 'pipe'],
|
|
});
|
|
|
|
const pipeLines = (stream, destination) => {
|
|
const reader = createInterface({ input: stream });
|
|
reader.on('line', (line) => {
|
|
if (!line.includes('Cannot open browser when using WSL')) destination.write(`${line}\n`);
|
|
});
|
|
};
|
|
pipeLines(wxt.stdout, process.stdout);
|
|
pipeLines(wxt.stderr, process.stderr);
|
|
|
|
const waitForManifest = async () => {
|
|
for (let attempt = 0; attempt < 200; attempt += 1) {
|
|
if (wxt.exitCode !== null) throw new Error(`WXT exited before producing ${manifest}`);
|
|
try {
|
|
await access(manifest, constants.R_OK);
|
|
return;
|
|
} catch {
|
|
await new Promise((resolveWait) => setTimeout(resolveWait, 100));
|
|
}
|
|
}
|
|
throw new Error(`Timed out waiting for ${manifest}`);
|
|
};
|
|
|
|
let chromeProcess;
|
|
const shutdown = async (signal) => {
|
|
if (chromeProcess?.exitCode === null) chromeProcess.kill(signal);
|
|
if (wxt.exitCode === null) wxt.kill(signal);
|
|
};
|
|
process.once('SIGINT', () => void shutdown('SIGINT'));
|
|
process.once('SIGTERM', () => void shutdown('SIGTERM'));
|
|
|
|
try {
|
|
await waitForManifest();
|
|
const chromeArgs = [
|
|
`--user-data-dir=${profile}`,
|
|
'--disable-gpu',
|
|
'--no-first-run',
|
|
'--no-default-browser-check',
|
|
];
|
|
if (!isBrandedChrome || process.env.WXT_AUTO_LOAD_EXTENSION === '1') {
|
|
chromeArgs.push(`--disable-extensions-except=${output}`, `--load-extension=${output}`, 'about:blank');
|
|
} else {
|
|
chromeArgs.push('chrome://extensions');
|
|
}
|
|
chromeProcess = spawn(chrome, chromeArgs, { cwd: root, env: process.env, stdio: 'inherit' });
|
|
if (isBrandedChrome && process.env.WXT_AUTO_LOAD_EXTENSION !== '1') {
|
|
process.stdout.write(`\nOpened official Chrome with the persistent WXT profile.\nChrome 137+ ignores --load-extension in branded builds. On first run, enable Developer mode and load:\n${output}\nProfile: ${profile}\n`);
|
|
} else {
|
|
process.stdout.write(`\nOpened ${chrome} with the WXT development extension.\nProfile: ${profile}\n`);
|
|
}
|
|
} catch (error) {
|
|
await shutdown('SIGTERM');
|
|
throw error;
|
|
}
|
|
|
|
await new Promise((resolveExit) => wxt.once('exit', resolveExit));
|
|
if (chromeProcess?.exitCode === null) chromeProcess.kill('SIGTERM');
|