Skip to content

4.9.0 implementation error: Cannot find module "electron-chrome-extensions" #167

@Corchoneitor

Description

@Corchoneitor

Hi Samuel!

We're trying to upgrade electron-chrome-extensions from 3.9.0 (with manifest v2 support) to the latest 4.9.0 version (with manifest v3). However, we're experiencing difficulties with the implementation. We are getting errors when building our app in dev and production mode.

First, we were having this error when building the dev environment.

Image

We were forced to add these lines to chainWebpackMainProcess webpack property to fix it:

config.externals({
    'electron-chrome-extensions': 'commonjs2 electron-chrome-extensions',
    'electron-chrome-extensions/browser-action': 'commonjs2 electron-chrome-extensions/browser-action',
});

That helped us sort the library implementation in the dev environment.

But when we try to compile our app in production mode, we get this error:

Image

We tried sorts of different approaches: using extraFiles, asarUnpack, etc., and also tried multiple modulePath combinations and paths. Still couldn't sort this out.
This is our new implementation. "Packaging the preload script" example did not help.

extensions.ts

import { ElectronChromeExtensions } from "electron-chrome-extensions";

// Older version (manifest v2).
const extensions = new ElectronChromeExtensions({
  license: "GPL-3.0",
  session: sesssion,
  modulePath: global.isDev
    ? path.join(__dirname, "../node_modules/electron-chrome-extensions")
    : path.join(
        __dirname,
        "../app.asar.unpacked/node_modules/electron-chrome-extensions"
      ),
  // ...
});

vue.config.js

/* eslint-disable @typescript-eslint/no-var-requires */
const path = require("node:path");
const CopyWebpackPlugin = require("copy-webpack-plugin");
const TerserPlugin = require("terser-webpack-plugin");

// Automatically import the components used in the app
const Components = require("unplugin-vue-components/webpack");
const { AntDesignVueResolver } = require("unplugin-vue-components/resolvers");

module.exports = {
  configureWebpack: {
    devServer: {
      watchOptions: {
        aggregateTimeout: 3000,
      },
    },
    devtool: "source-map",
    entry: { app: "./src/renderer/main.ts" },
    target: "electron-renderer",
    optimization: {
      minimize: process.env.NODE_ENV !== "development",
      minimizer: [
        new TerserPlugin({
          sourceMap: false,
          terserOptions: {
            compress: {
              drop_console: true,
            },
          },
        }),
      ],
    },
    plugins: [
      Components.default({
        dts: true,
        resolvers: [
          AntDesignVueResolver({
            importStyle: false,
          }),
        ],
      }),
    ],
    module: {
      rules: [
        {
          test: /\.(?:js|mjs|cjs)$/,
          exclude: [
            {
              test: path.resolve(__dirname, "node_modules"),
              exclude: path.resolve(__dirname, "node_modules/@formbricks/js"),
            },
          ],
          use: {
            loader: "babel-loader",
            options: {
              presets: [
                "@vue/cli-plugin-babel/preset",
                [
                  "@babel/preset-env",
                  {
                    targets: {
                      node: "current",
                    },
                  },
                ],
              ],
            },
          },
        },
      ],
    },
  },
  pluginOptions: {
    electronBuilder: {
      chainWebpackMainProcess: (config) => {
        config.plugin("copy").use(CopyWebpackPlugin, [
          {
            patterns: [
              {
                from: "node_modules/some-package/src/gcm/*.proto",
                to: "[name].[ext]",
              },
              {
                from: "node_modules/some-package/src/*.proto",
                to: "[name].[ext]",
              },
            ],
          },
        ]);
      },
      preload: {
        login: "src/preloads/login.js",
        main: "src/preloads/main.js",
        app: "src/preloads/app.js",
      },
      nodeIntegration: true,
      mainProcessTypeChecking: false,
      outputDir: "dist",
      mainProcessFile: "src/main/index.ts",
      rendererProcessFile: "src/renderer/main.ts",
      customFileProtocol: "./",
      builderOptions: {
        productName: "MyApp",
        appId: "com.myapp",
        electronVersion: "37.2.5",
        extraFiles: [
          {
            from: "public/native_extensions",
            to: "resources/native_extensions",
          },
          // Older version (manifest v2).
          {
            from: "node_modules/electron-chrome-extensions",
            to: "resources/app.asar.unpacked/node_modules/electron-chrome-extensions",
          },
        ],
        publish: [
          {
            provider: "github",
            owner: "myowner",
            repo: "myrepo",
          },
        ],
        mac: {
          icon: "build/icons/icon.icns",
          category: "public.app-category.productivity",
          artifactName: "MyApp-${version}-mac.${ext}",
          target: [
            {
              target: "default",
              arch: "universal",
            },
          ],
          hardenedRuntime: true,
          gatekeeperAssess: false,
          entitlements: "build/entitlements.mac.plist",
        },
        win: {
          icon: "build/icons/icon.ico",
          publisherName: "My Company",
          artifactName: "MyApp-${version}-win-${arch}.${ext}",
          target: ["nsis"],
        },
        linux: {
          icon: "build/icons",
          category: "Network",
          artifactName: "MyApp-${version}-linux-x64.${ext}",
          target: ["AppImage", "deb"],
        },
      },
    },
  },
};

If it helps, here is our previous implementation:

old_vue.config.js

/* eslint-disable @typescript-eslint/no-var-requires */
const path = require("node:path");
const CopyWebpackPlugin = require("copy-webpack-plugin");
const TerserPlugin = require("terser-webpack-plugin");

// Automatically import the components used in the app
const Components = require("unplugin-vue-components/webpack");
const { AntDesignVueResolver } = require("unplugin-vue-components/resolvers");

module.exports = {
  configureWebpack: {
    devServer: {
      watchOptions: {
        aggregateTimeout: 3000,
      },
    },
    devtool: "source-map",
    entry: { app: "./src/renderer/main.ts" },
    target: "electron-renderer",
    optimization: {
      minimize: process.env.NODE_ENV !== "development",
      minimizer: [
        new TerserPlugin({
          sourceMap: false,
          terserOptions: {
            compress: {
              drop_console: true,
            },
          },
        }),
      ],
    },
    plugins: [
      Components.default({
        dts: true,
        resolvers: [
          AntDesignVueResolver({
            importStyle: false,
          }),
        ],
      }),
    ],
    module: {
      rules: [
        {
          test: /\.(?:js|mjs|cjs)$/,
          exclude: [
            {
              test: path.resolve(__dirname, "node_modules"),
              exclude: path.resolve(__dirname, "node_modules/@formbricks/js"),
            },
          ],
          use: {
            loader: "babel-loader",
            options: {
              presets: [
                "@vue/cli-plugin-babel/preset",
                [
                  "@babel/preset-env",
                  {
                    targets: {
                      node: "current",
                    },
                  },
                ],
              ],
            },
          },
        },
      ],
    },
  },
  pluginOptions: {
    electronBuilder: {
      chainWebpackMainProcess: (config) => {
        config.plugin("copy").use(CopyWebpackPlugin, [
          {
            patterns: [
              {
                from: "node_modules/some-package/src/gcm/*.proto",
                to: "[name].[ext]",
              },
              {
                from: "node_modules/some-package/src/*.proto",
                to: "[name].[ext]",
              },
            ],
          },
        ]);
      },
      preload: {
        login: "src/preloads/login.js",
        main: "src/preloads/main.js",
        app: "src/preloads/app.js",
      },
      nodeIntegration: true,
      mainProcessTypeChecking: false,
      outputDir: "dist",
      mainProcessFile: "src/main/index.ts",
      rendererProcessFile: "src/renderer/main.ts",
      customFileProtocol: "./",
      builderOptions: {
        productName: "MyApp",
        appId: "com.myapp",
        electronVersion: "37.2.5",
        extraFiles: [
          {
            from: "public/native_extensions",
            to: "resources/native_extensions",
          },
          // Older version (manifest v2).
          {
            from: "node_modules/electron-chrome-extensions",
            to: "resources/app.asar.unpacked/node_modules/electron-chrome-extensions",
          },
        ],
        publish: [
          {
            provider: "github",
            owner: "myowner",
            repo: "myrepo",
          },
        ],
        mac: {
          icon: "build/icons/icon.icns",
          category: "public.app-category.productivity",
          artifactName: "MyApp-${version}-mac.${ext}",
          target: [
            {
              target: "default",
              arch: "universal",
            },
          ],
          hardenedRuntime: true,
          gatekeeperAssess: false,
          entitlements: "build/entitlements.mac.plist",
        },
        win: {
          icon: "build/icons/icon.ico",
          publisherName: "My Company",
          artifactName: "MyApp-${version}-win-${arch}.${ext}",
          target: ["nsis"],
        },
        linux: {
          icon: "build/icons",
          category: "Network",
          artifactName: "MyApp-${version}-linux-x64.${ext}",
          target: ["AppImage", "deb"],
        },
      },
    },
  },
};

Any help would be appreciated. Let me know if you need more information.

Thanks.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions