puppeteer-extra
puppeteer-extra copied to clipboard
[Bug] Using puppeteer-extra plugins (stealth and adblock) doesn't compile when using Vue and Electron
Describe the bug
Trying to start an Electron.js
program with Vue.js
and using puppeteer-extra plugins doesn't work. When starting with a puppeteer instance using stealth and adblock plugin, the program crashes.
INFO Launching Electron...
App threw an error during load
Error: Cannot find module 'kind-of'
at webpackEmptyContext (webpack:///./node_modules/clone-deep_sync?:2:10)
at Function.getter [as typeOf] (webpack:///./node_modules/lazy-cache/index.js?:39:29)
at cloneDeep (webpack:///./node_modules/clone-deep/index.js?:14:17)
at mergeDeep (webpack:///./node_modules/merge-deep/index.js?:19:16)
at new PuppeteerExtraPlugin (webpack:///./node_modules/puppeteer-extra-plugin/dist/index.esm.js?:59:22)
at new StealthPlugin (webpack:///./node_modules/puppeteer-extra-plugin-stealth/index.js?:74:5)
at Object.defaultExport [as default] (webpack:///./node_modules/puppeteer-extra-plugin-stealth/index.js?:171:31)
at eval (webpack:///./node_modules/japscandl/js/src/utils/browser.js?:46:53)
at Object../node_modules/japscandl/js/src/utils/browser.js (C:\Users\gario\Desktop\vue\japdl-vue\dist_electron\index.js:3077:1)
at __webpack_require__ (C:\Users\gario\Desktop\vue\japdl-vue\dist_electron\index.js:20:30)
So I searched and the error seems to come from 'merge-deep' used in package 'puppeteer-extra-plugin' index.esm.js
.
The problem resolves if I remove the line, but it probably creates other bugs elsewhere.
Code Snippet
class PuppeteerExtraPlugin {
constructor(opts) {
this._debugBase = debug(`puppeteer-extra-plugin:base:${this.name}`);
this._childClassMembers = [];
// error is because of this line, using merge \/
this._opts = merge(this.defaults, opts || {});
this._debugBase('Initialized.');
}
When using
import puppeteer from "puppeteer-extra";
import StealthPlugin from "puppeteer-extra-plugin-stealth";
import AdblockerPlugin from "puppeteer-extra-plugin-adblocker";
import { Browser } from "puppeteer";
puppeteer
.use(StealthPlugin())
.use(AdblockerPlugin({ blockTrackers: true }));
const getBrowser = async (visible: boolean, chromePath: string): Promise<Browser> => {
const browser = await puppeteer
.launch({
headless: !visible,
executablePath: chromePath,
});
await browser.newPage();
return browser;
}
// in background.js
getBrowser(true, chromePath).then((browser) => {
browser.close();
});
Infos
Using vue 3.0.0 electron 12.0.9
Instantiated project with vue cli
$ npx envinfo@latest --system --binaries --npmPackages '(puppeteer|playwright*|automation-extra*|@extra*)' System: OS: Windows 10 10.0.19042 CPU: (12) x64 AMD Ryzen 5 5600X 6-Core Processor Binaries: Node: 14.15.1 - C:\Program Files\nodejs\node.EXE npm: 6.14.8 - C:\Program Files\nodejs\npm.CMD
Using this code seems to do the same thing without causing the bug:
constructor(opts) {
this._debugBase = debug(`puppeteer-extra-plugin:base:${this.name}`);
this._childClassMembers = [];
this._opts = this.defaults;
Object.entries(opts).forEach((array) => {
this._opts[array[0]] = array[1];
});
this._debugBase('Initialized.');
}
Running in to this exact problem as well in my electron vue app. Hoping this gets resolved ASAP
Fixed this. Solution was to use the unlazy-loader package for webpack and import all the evasions manually
Could you explain how you did that please ?
Could you explain how you did that please ?
Sure.
Add the unlazy-loader package to your project. Configure it in vue.config.js
like this:
module.exports = {
pluginOptions: {
electronBuilder: {
...
chainWebpackMainProcess: config => {
config.module
.rule('unlazy-loader')
.test(/\.js$/)
.use('unlazy-loader')
.loader('unlazy-loader')
.end()
}
}
}
}
Then in the file you're trying to use puppeteer in, import it and load the plugins like so:
import puppeteerVanilla from 'puppeteer';
import { addExtra } from 'puppeteer-extra';
import StealthPlugin from 'puppeteer-extra-plugin-stealth';
import AcceptLanguagePlugin from 'puppeteer-extra-plugin-stealth/evasions/accept-language';
import ChromeRuntimePlugin from 'puppeteer-extra-plugin-stealth/evasions/chrome.runtime';
import ConsoleDebugPlugin from 'puppeteer-extra-plugin-stealth/evasions/console.debug';
import IFrameContentWindowPlugin from 'puppeteer-extra-plugin-stealth/evasions/iframe.contentWindow';
import MediaCodecsPlugin from 'puppeteer-extra-plugin-stealth/evasions/media.codecs';
import NavigatorLanguagesPlugin from 'puppeteer-extra-plugin-stealth/evasions/navigator.languages';
import NavigatorPermissionsPlugin from 'puppeteer-extra-plugin-stealth/evasions/navigator.permissions';
import NavigatorPlugins from 'puppeteer-extra-plugin-stealth/evasions/navigator.plugins';
import WebdriverPlugin from 'puppeteer-extra-plugin-stealth/evasions/navigator.webdriver';
import UserAgentPlugin from 'puppeteer-extra-plugin-stealth/evasions/user-agent';
import WebglVendorPlugin from 'puppeteer-extra-plugin-stealth/evasions/webgl.vendor';
import WindowOuterDimensionsPlugin from 'puppeteer-extra-plugin-stealth/evasions/window.outerdimensions';
(async () => {
const plugins = [
StealthPlugin(),
ChromeRuntimePlugin(),
IFrameContentWindowPlugin(),
MediaCodecsPlugin(),
NavigatorLanguagesPlugin(),
NavigatorPermissionsPlugin(),
NavigatorPlugins(),
WebdriverPlugin(),
WebglVendorPlugin(),
WindowOuterDimensionsPlugin(),
UserAgentPlugin(),
AcceptLanguagePlugin(),
ConsoleDebugPlugin()
];
const puppeteer = addExtra(puppeteerVanilla);
const browser = await puppeteer.launch();
for (const plugin of plugins) {
await plugin.onBrowser(browser);
}
const page = await browser.newPage();
for (const plugin of plugins) {
await plugin.onPageCreated(page);
}
...
})
Basically just followed all the suggestions on this post: https://github.com/berstend/puppeteer-extra/issues/93
It appears to be an issue with webpack and not an inherent issue with puppeteer-extra. Hope this helps!
If this problem has already been solved, please incorporate it as soon as possible.
Could you explain how you did that please ?
Sure.
Add the unlazy-loader package to your project. Configure it in
vue.config.js
like this:module.exports = { pluginOptions: { electronBuilder: { ... chainWebpackMainProcess: config => { config.module .rule('unlazy-loader') .test(/\.js$/) .use('unlazy-loader') .loader('unlazy-loader') .end() } } } }
Then in the file you're trying to use puppeteer in, import it and load the plugins like so:
import puppeteerVanilla from 'puppeteer'; import { addExtra } from 'puppeteer-extra'; import StealthPlugin from 'puppeteer-extra-plugin-stealth'; import AcceptLanguagePlugin from 'puppeteer-extra-plugin-stealth/evasions/accept-language'; import ChromeRuntimePlugin from 'puppeteer-extra-plugin-stealth/evasions/chrome.runtime'; import ConsoleDebugPlugin from 'puppeteer-extra-plugin-stealth/evasions/console.debug'; import IFrameContentWindowPlugin from 'puppeteer-extra-plugin-stealth/evasions/iframe.contentWindow'; import MediaCodecsPlugin from 'puppeteer-extra-plugin-stealth/evasions/media.codecs'; import NavigatorLanguagesPlugin from 'puppeteer-extra-plugin-stealth/evasions/navigator.languages'; import NavigatorPermissionsPlugin from 'puppeteer-extra-plugin-stealth/evasions/navigator.permissions'; import NavigatorPlugins from 'puppeteer-extra-plugin-stealth/evasions/navigator.plugins'; import WebdriverPlugin from 'puppeteer-extra-plugin-stealth/evasions/navigator.webdriver'; import UserAgentPlugin from 'puppeteer-extra-plugin-stealth/evasions/user-agent'; import WebglVendorPlugin from 'puppeteer-extra-plugin-stealth/evasions/webgl.vendor'; import WindowOuterDimensionsPlugin from 'puppeteer-extra-plugin-stealth/evasions/window.outerdimensions'; (async () => { const plugins = [ StealthPlugin(), ChromeRuntimePlugin(), IFrameContentWindowPlugin(), MediaCodecsPlugin(), NavigatorLanguagesPlugin(), NavigatorPermissionsPlugin(), NavigatorPlugins(), WebdriverPlugin(), WebglVendorPlugin(), WindowOuterDimensionsPlugin(), UserAgentPlugin(), AcceptLanguagePlugin(), ConsoleDebugPlugin() ]; const puppeteer = addExtra(puppeteerVanilla); const browser = await puppeteer.launch(); for (const plugin of plugins) { await plugin.onBrowser(browser); } const page = await browser.newPage(); for (const plugin of plugins) { await plugin.onPageCreated(page); } ... })
Basically just followed all the suggestions on this post: #93
It appears to be an issue with webpack and not an inherent issue with puppeteer-extra. Hope this helps!
thanks,it works for me.
Hello, what ended up working for me was making sure to include any merge-deep dependencies as an external and to declare the node_modules path relative to your package.json in your package.json as an 'extraResource'.
@JasonHoku can you share an example of your package.json?