如何在Puppeteer加载Chrome扩展前执行初始化设置代码
解决方案
方案1:浏览器启动完成后再加载扩展(无需修改扩展源码)
这是最直接的实现方式,核心是先启动不带扩展的浏览器完成初始化,再通过Chrome DevTools Protocol(CDP)动态加载扩展,要求Chrome版本≥112。
实现步骤
- 启动浏览器时先不加载目标扩展,禁用所有扩展避免提前触发逻辑:
const browser = await puppeteer.launch({ headless: false, ignoreDefaultArgs: ['--disable-extensions'], args: ['--disable-extensions'] });
- 打开临时页面执行你的初始化操作(设置localStorage、注入mock等):
const initPage = await browser.newPage(); await initPage.goto('chrome://newtab/'); await initPage.evaluate(() => { // 示例:写入localStorage配置 localStorage.setItem('custom_config', JSON.stringify({ test: true })); // 示例:注入全局jest mock window.jest = { fn: () => () => {}, mock: {} }; });
- 通过CDP的Extension API动态加载已解压的扩展:
const cdpSession = await browser.target().createCDPSession(); const { extensionId } = await cdpSession.send('Extension.loadUnpacked', { path: 'dist/chrome', failOnError: true });
加载完成后扩展会正常触发安装、启动逻辑,此时你的前置初始化操作已经全部执行完毕。
方案2:拦截扩展初始化流程(需修改扩展源码,兼容性更强)
如果你可以调整扩展的代码,可以通过加前置等待逻辑的方式,等Puppeteer完成初始化后再执行扩展原有逻辑,无需依赖高版本Chrome的CDP接口。
实现步骤
- 在扩展的入口脚本(通常是background service worker、popup入口或content script的最顶部)添加等待初始化标记的逻辑:
// 仅在测试环境开启该逻辑,生产环境可移除 if (process.env.NODE_ENV === 'test') { await new Promise(resolve => { const checkTimer = setInterval(() => { if (localStorage.getItem('puppeteer_init_done') === '1') { clearInterval(checkTimer); resolve(); } }, 30); }); } // 原有扩展的初始化逻辑放在后面
- Puppeteer启动时保留你原有的加载扩展的配置,启动完成后先打开页面执行初始化操作,最后写入初始化标记触发扩展继续执行:
const browser = await puppeteer.launch({ args: [ '--disable-extensions-except=dist/chrome', '--load-extension=dist/chrome', ], headless: false, ignoreDefaultArgs: ['--disable-extensions'], }); // 执行初始化操作 const initPage = await browser.newPage(); await initPage.evaluate(() => { localStorage.setItem('custom_config', 'test_value'); window.mockApi = () => ({ code: 200 }); // 写入初始化完成标记 localStorage.setItem('puppeteer_init_done', '1'); });
内容的提问来源于stack exchange,提问作者mark
相关产品推荐
相关产品推荐

