electron-forge npm run make native modules pah is error

Created on 13 May 2020  路  14Comments  路  Source: electron-userland/electron-forge

1339 # Issue Details

  • Electron Forge Version:
    "@electron-forge/cli": "^6.0.0-beta.39",
  • Electron Version:
    8.1.1
  • Operating System:
    MacBook Pro (13-inch, 2017, Two Thunderbolt 3 ports)

Expected Behavior

i run cmd as npm run start, it work. but it can not work, when i run cmd as npm run make.
native modules can not find.
I expected it can work when i run npm run make.

Additional Information

i run cm as npm run make, it can make a package.dmg. I install it and open it. It happen error, some messages:

Uncaught Error: Cannot open /Users/qile/git/klive-teacher/teacher-package/src/lib/pdfmanager.node: Error: dlopen(/Users/qile/git/klive-teacher/teacher-package/src/lib/pdfmanager.node, 1): image not found

test

native modules path is error, it is not relative path, it is absolute path in my mac. I do not know how to resolve it.

my electron-forge conifg:

module.exports = {
  "packagerConfig": {
    "packageManager": "npm",
    "icon": "./make/xx",
    "asar": false,
    "overwrite": true,
    "extraResource": ["./src/lib/jar/", "./src/lib/jre/"]
  },
  "makers": [
    {
      "name": "@electron-forge/maker-squirrel",
      "config": {
        "name": "xx"
      }
    },
    {
      "name": "@electron-forge/maker-dmg",
      "platforms": [
        "darwin"
      ],
      "config": {
        "name": "xx",
        "icon": "./make/xx.ico"
      }
    },
    {
      "name": "@electron-forge/maker-deb",
      "config": {}
    },
    {
      "name": "@electron-forge/maker-rpm",
      "config": {}
    }
  ],
  "plugins": [
    [
      "@electron-forge/plugin-webpack",
      {
        "mainConfig": "./webpack.main.config.js",
        "renderer": {
          "config": "./webpack.renderer.config.js",
          "entryPoints": [
            {
              "html": "./src/index.html",
              "js": "./src/renderer.ts",
              "name": "main_window"
            }
          ]
        }
      }
    ]
  ]
};

I look forward to your reply

thanks

Bug

Most helpful comment

I have the same issue as @this-spring, when creating a "child_process" inside electron-forge with webpack. The proposed node-loader removal @daijinru doesnt work in my case.

It works great in development with npm run start, but after building with npm run make and installng, the child process fails to load the required modules after installed.

Any ideas?

I resolve the problem by dynamically require.
requireDynamically by absolutely path.
like this:

const PdfAddon = requireDynamically(nodeUrl);
function requireDynamically(path)
{
    path = path.split('\\').join('/'); // Normalize windows slashes
    return eval(`require('${path}');`); // Ensure Webpack does not analyze the require statement
}

All 14 comments

Open this file:
/Contents/Resources/app/.webpack/renderer/main_window/index.js

find:
dlopen(/Users/qile/git/klive-teacher/teacher-package/src/lib/pdfmanager.node)

change to:
dlopen(require.resolve("../native_modules/build/Release/pdfmanager.node"))

if your native_modules is beside the main_window.
May be the node-loader got a problem that I am checking.

thanks your answer.
emmm, the method is a way to resolved the problem.
But this method does not fundamentally solve the problem. I can't change that file on everyone's computer. I think it may be that the webpack is not configured correctly, but I don't know how to configure it.

You can try to rm the node-loader in webpack.rule.js, just keep @marshallofsound/webpack-asset-relocator-loader.

node-loader uses process.dlopen(), can refer to:
https://nodejs.org/dist/latest-v12.x/docs/api/process.html#process_process_dlopen_module_filename_flags

The process.dlopen() method allows to dynamically load shared objects. It is primarily used by require() to load C++ Addons, and should not be used directly, except in special cases. In other words, require() should be preferred over process.dlopen(), unless there are specific reasons.

I have the same issue as @this-spring, when creating a "child_process" inside electron-forge with webpack. The proposed node-loader removal @daijinru doesnt work in my case.

It works great in development with npm run start, but after building with npm run make and installng, the child process fails to load the required modules after installed.

Any ideas?

I have the same issue as @this-spring, when creating a "child_process" inside electron-forge with webpack. The proposed node-loader removal @daijinru doesnt work in my case.

It works great in development with npm run start, but after building with npm run make and installng, the child process fails to load the required modules after installed.

Any ideas?

I resolve the problem by dynamically require.
requireDynamically by absolutely path.
like this:

const PdfAddon = requireDynamically(nodeUrl);
function requireDynamically(path)
{
    path = path.split('\\').join('/'); // Normalize windows slashes
    return eval(`require('${path}');`); // Ensure Webpack does not analyze the require statement
}

If it analyzing the path when run-time, removing the module from dependency (package.json) should reproduce the problem again.

I also have this problem.

When I remove the node-loader module as @daijinru suggests, the yarn package script outputs a bundle that works correctly (it loads from a relative path as expected), but it no longer works under yarn start. So I implemented a super stupid fix that seems to work:

const in_packager = process.env.npm_lifecycle_script.search(/package/) >= 0;

const rules = [
  (!in_packager ? {
    test: /\.node$/,
    use: 'node-loader',
  } :
  {
    test: /\.(m?js|node)$/,
    parser: { amd: false },
    use: {
      loader: '@marshallofsound/webpack-asset-relocator-loader',
      options: {
        outputAssetBase: 'native_modules',
      },
    },
  })
]

Any news about this issue? 馃槀 I have the problem as well.

Removing node-loader could require correctly but the main.js from yarn start cannot find the native module.

I can find my native module in native_modules in .webpack.

internal/modules/cjs/loader.js:887 Uncaught Error: Cannot find module './../native_modules/build/Release/MyNativeModule.node'
Require stack:
- electron/js2c/renderer_init
    at Module._resolveFilename (internal/modules/cjs/loader.js:887)
    at Function.o._resolveFilename (electron/js2c/renderer_init.js:33)
    at Module._load (internal/modules/cjs/loader.js:732)
    at Function.f._load (electron/js2c/asar_bundle.js:5)
    at Function.o._load (electron/js2c/renderer_init.js:33)
    at Module.require (internal/modules/cjs/loader.js:959)
    at require (internal/modules/cjs/helpers.js:88)
    at Object../node_modules/MyNativeModule/build/Release/MyNativeModule.node (MyNativeModule.node:1)
    at __webpack_require__ (bootstrap:789)
    at fn (bootstrap:100)

Printing __dirname on Console shows "{MyWorkSpace}/node_modules/electron/dist/Electron.app/Contents/Resources/electron.asar/renderer"

@felldiddy @JasinYip I got it working for a native module sharp to be loaded from a renderer process.

Example repo: https://github.com/aperkaz/electron-forge-sharp

All you have to do is modify the webpack config in: webpack.main.config.js to:

module.exports = {
  entry: "./src/main.js",
  module: {
    rules: require("./webpack.rules"),
  },
  externals: {
    sharp: "commonjs sharp",
  },
};

Thanks @aperkaz your suggestion looks like it's fixing my issues. I added the libraries (in my case keytar and registry-js) as externals + commonjs, no other config needed.

@felldiddy @JasinYip I got it working for a native module sharp to be loaded from a renderer process.

Example repo: https://github.com/aperkaz/electron-forge-sharp

All you have to do is modify the webpack config in: webpack.main.config.js to:

module.exports = {
  entry: "./src/main.js",
  module: {
    rules: require("./webpack.rules"),
  },
  externals: {
    sharp: "commonjs sharp",
  },
};

Are you sure you got it working in the renderer process? I've tried adding

  externals: {
    sharp: 'commonjs sharp',
  },

to both webpack.main.config.js and webpack.renderer.config.js , with and without node-loader (which doesn't seem to make _any_ difference in any case I've tried so far) and I'm still getting:

external "util":1 Uncaught ReferenceError: require is not defined
    at Object.util (index.js:108240)
    at __webpack_require__ (index.js:790)
    at fn (index.js:101)
    at Object../node_modules/sharp/lib/constructor.js (index.js:102641)
    at __webpack_require__ (index.js:790)
    at fn (index.js:101)
    at Object../node_modules/sharp/lib/index.js (index.js:103045)
    at __webpack_require__ (index.js:790)
    at fn (index.js:101)
    at Module.<anonymous> (index.js:6165)

@ivancuric I got it working in the render process 馃檪

I faced some issues when running it on windows, so I witched to electron-builder instead. Starter WIP

Thanks. I feel like I should drop electron-forge and set up things manually. Too much magic going on under the hood.

The solution of using externals will break packaging because the modules won't be copied to the native_modules folder :/

Was this page helpful?
0 / 5 - 0 ratings