Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dynamic import of native addons #685

Closed
hosnar opened this issue Mar 18, 2020 · 7 comments
Closed

Dynamic import of native addons #685

hosnar opened this issue Mar 18, 2020 · 7 comments

Comments

@hosnar
Copy link

hosnar commented Mar 18, 2020

Hi, i'm not sure this is the place to ask this, but i didn't know where else to do it.

I'm trying to require native node module in my Electron main process. This works fine on development where path is static:

const addon = require('./addon.node')

But when i package production build, my path isn't static anymore, since it differs by OS. So i must use dynamic path like this:

const addon = require(process.resourcesPath + '/native/addon.node')

When i run this packaged app i keep getting error:

Error: Cannot find module

Also, i'm using extraResources to move my addon to Resources folder when packaging.

I tried different workarounds, i also tried native-ext-loader and node-loader for webpack but it doesn't seem to help.

Any help would be greatly appreciated. Thank you.

@nklayman
Copy link
Owner

nklayman commented Mar 18, 2020

You will want to place your addon.node in the public folder. Then, you can access it in serve and build with path.join(__static, 'addon.node'). See the docs on static assets for more details. You will not need any special extraResources config with this method.

@hosnar
Copy link
Author

hosnar commented Mar 18, 2020

Thank you very much for your answer. But this still doesn't seem to work for me, i get this error:

Error: Cannot find module '/Applications/MyApp.app/Contents/Resources/app.asar/addon.node'

Path must be incorrect, since app.asar is not a directory.

Code i used:

const loadAddon = () => {
  if (!process.env.WEBPACK_DEV_SERVER_URL) {
    return require(path.join(__static, 'addon.node'))
  } else {
    // Dev
  }
}

const proc = loadAddon()

For webpack loader i'm using:

chainWebpackMainProcess: config => {
  config.module.rule('node').test(/\.node$/).use('node-loader').loader('node-loader')
}

And i've put addon.node in public directory.

Do you see anything i could be doing wrong? Thank you

@nklayman
Copy link
Owner

Looks like this is a duplicate of #334. Try the solution that worked there and see if that helps.

@hosnar
Copy link
Author

hosnar commented Mar 19, 2020

Thank you very much for you help! With the solution you linked, i could make it work like this:

const loadAddonFile = () => {
  const path = require('path')
  const filePath = `/addons/addon-${process.platform}.node`
  if (process.env.WEBPACK_DEV_SERVER_URL) {
    // eslint-disable-next-line
    return __non_webpack_require__(path.join(process.cwd(), filePath))
  } else {
    // eslint-disable-next-line
    return __non_webpack_require__(path.join(process.resourcesPath, filePath))
  }
}

const addon = loadAddonFile()

I used os.platform since addon is compiled for each OS. And i still ended up using extraResources as mentioned before, without webpack node loader. This probably isn't the best way to go about it but it was the only way i could make it work. So, just posting my solution, as it might help someone else, maybe.

Thanks again. Cheers

@nklayman
Copy link
Owner

Just a heads up, process.cwd() resolves to the dir you are in when you launch the executable, so I definitely wouldn't use it to get a path to a resource. Try using app.getPath instead.

@hosnar
Copy link
Author

hosnar commented Mar 22, 2020

Oh, ok. Thank you for the heads up, i'll fix it.

@netcore-jroger
Copy link

netcore-jroger commented Dec 17, 2020

I use __non_webpack_require__ function to dynamic load module. but it not support import syntax. so I use esm package wrap it. like this

const nonWebpackRequire = __non_webpack_require__('esm')(module);
for (let mainProcessFile of files) {
  nonWebpackRequire(mainProcessFile);
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants