puppeteer-extra icon indicating copy to clipboard operation
puppeteer-extra copied to clipboard

[Bug] Using puppeteer-extra plugins (stealth and adblock) doesn't compile when using Vue and Electron

Open Seysa opened this issue 3 years ago • 10 comments

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

Seysa avatar May 26 '21 22:05 Seysa

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.');
    }

Seysa avatar May 26 '21 23:05 Seysa

Running in to this exact problem as well in my electron vue app. Hoping this gets resolved ASAP

jakerieger avatar Jun 07 '21 03:06 jakerieger

Fixed this. Solution was to use the unlazy-loader package for webpack and import all the evasions manually

jakerieger avatar Jun 11 '21 08:06 jakerieger

Could you explain how you did that please ?

Seysa avatar Jun 11 '21 08:06 Seysa

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!

jakerieger avatar Jun 11 '21 12:06 jakerieger

If this problem has already been solved, please incorporate it as soon as possible.

kurohoan avatar Jun 29 '21 02:06 kurohoan

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.

imtiger avatar Jul 23 '22 05:07 imtiger

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 avatar Dec 13 '22 14:12 JasonHoku

@JasonHoku can you share an example of your package.json?

impactcolor avatar Jan 24 '24 22:01 impactcolor