Giter Club home page Giter Club logo

electron-native-plugin's Introduction

electron-native-plugin

This is a plugin for WebPack version 4 and higher. It is used to bundle Node native modules for the Electron platform. It was developed mainly to provide this ability for the electron-angular-webpack project. It consists of three separate NPM packages:

  1. electron-native-plugin
  2. electron-native-loader
  3. electron-native-patch-loader

The role of these packages is given further in the text.

Installation

I presume you have Node and NPM installed. Then it is necessary to install node-gyp which is a Node native module compiler.

npm install --save-dev node-gyp

For the use with this plugin the node-gyp installation needs to be local.

Next it is necessary to install a C++ compiler and Python 2.7 specific for your platform. Windows users can use this package to install them. If you use Linux or MacOS, please consult the manual of your distribution to install GCC or CLang tool-chain.

npm install --global windows-build-tools

It might be necessary to setup some environment variables, please consult windows-build-tools page.

Then we need electron-rebuild NPM package. This can be installed by the following command.

npm install --save-dev electron-rebuild

Next it is necessary to install WebPack if you have not done already.

npm install --save-dev webpack

Finally we can install electron-native-plugin packages.

npm install --save-dev electron-native-plugin
npm install --save-dev electron-native-loader
npm install --save-dev electron-native-patch-loader

The other two plugins, electron-native-loader and electron-native-patch-loader, will be installed automatically as its peer dependencies.

Types of native modules

The electron-native-plugin supports compilation and bundling of two types of native modules:

  • library native modules
  • project native modules

Library native modules are the modules present in your node_modules directory. They will be most of the time 3rd-party modules that just need to be recompiled for the Electron's V8 machine. The most common scenario is that you will just install such a module via NPM and it will get then compiled by node-gyp during the NPM post-install stage.

Project native modules are the ones you write yourself and are present in the src directory of your project. If you want to integrate a library that takes longer to compile in C++, the recommended scenario is as follows:

  1. Prepare a project for your native library outside your Electron project and compile it as a static library.
  2. In your post-build process copy the static library with the necessary header files to your Electron project.
  3. Write in your Electron project the necessary C/C++ code for the interface with Electron, best using the Nan library.
  4. Recompile and link using Webpack just the interface for Electron.

Algorithm used to compile library native modules

This subclause describes briefly what in fact electron-native-plugin is doing when compiling library native modules.

  1. When the webpack launches the plugin starts by parsing your package.json file.
  2. Then it reads your dependencies and checks which modules are the native ones. The devDependencies section is obviously ignored.
  3. The next step the plugin performs is to run electron-rebuild command for each native module to convert it for the use with the Electron V8 machine.
  4. Next it will write a substitution map into a file. This map is simply a key/value pair between the old NodeJS file and the Electron native module file.
  5. This map is then read by electron-native-loader which is used to update the references in your project to the Electron binaries which are then bundled by WebPack.

How to setup webpack.config.js

To setup this set of NPM modules for the use in WebPack is quite simple. First load and add the ElectronNativePlugin as follows:

const Webpack = require('webpack');
const ElectronNativePlugin = require("electron-native-plugin");
...
plugins: 
    [
        new ElectronNativePlugin(),
        new Webpack.IgnorePlugin(/node-gyp/)
    ]
...

Finally setup the module rules as follows:

...
 module: 
    {
        rules: [
            {
                test: /\.js$/,
                use: 
                [
                    "electron-native-patch-loader",
                    {
                        loader: "electron-native-loader",
                        options: {
                            outputPath: outputPath  // Set here your defined path 
                                                    // for the output bundles, e.g. "./dist"
                        }
                    }
                ]
            },
            { 
                test: /\.node$/, 
                use: "electron-native-loader" 
            }
        ]
    }
...

Note: DO NOT FORGET to set the output path in the options of electron-native-loader. It must be the root output path where you place your JS bundles and assets. It is marked by the comment in the figure above.

Configuration of project native modules

The subclause above described just the minimum configuration of the plugin. If you intend to use compilation of project native modules, the configuration is a little more complicated. Let's see the figure below:

new ElectronNativePlugin({
        forceRebuild: false,
        outputPath: "./electron/native-modules/aa/bb", // a default relative output path for all native modules
        userModules: 
        [
            "./cc/bb/aa",   // path to the binding.gyp file 
            { 
                source: "./native-module/",     // path to the binding.gyp file
                debugBuild: false,              // we are overriding the default debugBuild settings
                outputPath: "./greeting-module/" // this is a relative path to the path of output bundles, 
                                                 // we override the default
            }
        ],
        debugBuild: true        // yes, do debug builds
    }),

Let's describe the options one by one:

  • forceRebuild - when it is true, the electron-rebuild command is forced to do the rebuild in every case
  • outputPath - specifies the default relative path to the root output directory for the native modules
  • debugBuild - when is set to true, debug binaries are generated
  • userModules - specifies the array of project native module configuration
  • optionalDependencies - when it is true, all native node modules in the optionalDependencies section are rebuilt, too.

The project module configuration can be specified either by a string or an object. When a string is used, then it is assumed it is a path to the project's binding.gyp file. The object notation is described below.

User module or project module has the following properties:

  • source - specifies the path where the binding.gyp file is placed
  • debugBuild - overwrites the default debug build settings
  • outputPath - overwrites the default output path settings

Things get a bit tough

Some Node native libraries are not directly compatible with Webpack and cannot be so easily bundled. It is maily due to the fact that they load dependencies in various ways which WebPack cannot detect and parse. One of the examples is sqlite3 database. As a rescue to solve this incompatibility comes electron-native-patch-loader NPM module. It works simply by text replacement of the JS source files based on its JSON configuration. Its description is found at electron-native-patch-loader page.

electron-native-plugin's People

Contributors

evonox avatar kegesch avatar

Stargazers

 avatar  avatar

Watchers

 avatar  avatar  avatar

Forkers

kegesch

electron-native-plugin's Issues

Native module could not be located

Hey there, thanks for this plugin. I currently have a great struggle to use native node modules in my electron app.
So i started a new project an wanted setup a boilerplate.
I tried to use your plugin and used a example native node module to test it.
Unfortunately after rebuilding the module it will be copied to my specified build folder, but it is renamed wrongly. To be more pecise: I am using the module "node-mac-notifier" which expects Notification.node at the build folder (besides the bundle). But your plugin generates a node-mac-notifier.node file. And therefore electron produces this error:

Uncaught Error: Could not locate the bindings file. Tried:
 → /Users/.../build/Notification.node
 → /Users/.../build/Debug/Notification.node
 → /Users/.../build/Release/Notification.node
 → /Users/.../out/Debug/Notification.node
 → /Users/.../Debug/Notification.node
 → /Users/.../out/Release/Notification.node
 → /Users/.../Release/Notification.node
 → /Users/.../build/default/Notification.node
 → /Users/.../compiled/10.2.0/darwin/x64/Notification.node
    at bindings (bindings.js:93)
    at Object../node_modules/node-mac-notifier/index.js (index.js:5)
    at __webpack_require__ (bootstrap:724)
    at fn (bootstrap:101)
    at Module../src/index.tsx (index.tsx:1)
    at __webpack_require__ (bootstrap:724)
    at fn (bootstrap:101)
    at Object.0 (index.tsx:14)
    at __webpack_require__ (bootstrap:724)
    at ./node_modules/ansi-html/index.js.module.exports (bootstrap:791)

You can look at my webpack.conf at https://github.com/Y0nnyy/electron-react-boilerplate/tree/native-module.
Am i missing something?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.