browserify bundle electron app main process file - node.js

I am building a electron app and currently using browserify for the renderer (web page) files like any other javascript front end. I would like to also use browserify to bundle the main process files. However, browswerify is unable to find the electron built in modules like clipboard, ipc, browser-window, app, etc...
In my main.js file which serves as the entry point for the electron app. I have:
const ipc = require('ipc');
const clipboard = require('clipboard');
const BrowserWindow = require('browser-window');
const app = require('app');
const yargs = require('yargs');
the const yargs loads fine as it is in the node_modeuls folder and browserify can resolve that. However the othe four items cannot be found by browserify and therefore fail my build.
[11:49:17] Finished 'development' after 17 ms
Error: Cannot find module 'ipc' from '<path>'
Error: Cannot find module 'clipboard' from '<path>'
Error: Cannot find module 'browser-window' from '<path>'
Error: Cannot find module 'app' from '<path>'
Any suggestions?

With browserify you can set the options 'ignoreMissing' and 'detectGlobals' which allow browserify to ignore built int modules that eventually get loaded automatically in the electron app.
browserify({
entries: './src/main.js',
extensions: ['.js'],
ignoreMissing: true,
detectGlobals: false,
bare: true,
debug: false
})

Related

How to point webpack to a specific node_modules folder

I am trying to build a grpc web client and I need to pack the code to resolve the require statements.
I have compiled the protos to js and it works if I have them in the current folder where I have installed the node modules.
The problem is if I have the compiled proto in some other place and I require them from there, webpack looks for the node modules in that path.
From my client.js
working version:
const {StopRequest, StopReply} = require('./work_pb.js');
Problematic version:
const {StopRequest, StopReply} = require('../../../messages/proto/output/work_pb.js');
In this last case it looks for the node modules in ../../../messages/proto/output/.
The node modules are installed in the current path where my client.js is and from where I ran npx webpack client.js.
ERROR in /home/xxx/yyy/zzz/messages/proto/output/work_pb.js
Module not found: Error: Can't resolve 'google-protobuf' in '/home/xxx/yyy/zzz/messages/proto/output'
# /home/xxx/yyy/zzz/messages/proto/output/work_pb.js 11:11-37
# ./client.js
How do I tell webpack to look in the current path for the node modules and not in the path of the compiled proto?
You can specify resolve.modules to customize the directory, where Webpack searches for modules with absolute import paths:
// inside webpack.config.js
const path = require('path');
module.exports = {
//...
resolve: {
modules: [path.resolve(__dirname, 'node_modules'), 'node_modules']
}
};
This will let node_modules inside your project root (where webpack config resides) take precedence over the default setting "node_modules", which resolves paths via node module resolution algorithm.
More infos: Webpack docs: Module Resolution

TypeError: Cannot read property 'getAppPath' of undefined

We're using Electron "electron": "^5.0.2"
The code that is having the error is in the main process. It calls our backend services. I was trying to add a constant for the API path the same way we were including constants elsewhere (note: the solution here might be to use an environment variable). The issue is that electron is giving a error when it is trying to access the appPath() method. This same code works elsewhere in the app.
TypeError: Cannot read property 'getAppPath' of undefined
const {app} = require('electron');
const path = require('path');
const constants = require(path.join(app.getAppPath(), 'src/constants'));
When the browser window is created we're setting nodeIntegration to true
window = new BrowserWindow({
webPreferences: {nodeIntegration: true}
});
Try:
const app = require('electron')
app.remote.app.getPath()
If that doesn't work you should try checking if main.js is:
included in package.json
NOT being required by your frontend JS or index.html
of course, make sure electron is installed as a dev dependency
if you are running into while trying to packaging the app you should run the code that uses app in a conditional, app isn't available while packaging but will be available in the prod

Module not found : 'child process'

I'm developing a ReactJS app with Babel and Webpack. I am using the create-react-app facebook script so it handles the Webpack´s configuration. My problem is that I created a js file and add:
var childProcess = require('child_process');
But when I want to compile the new version i get the following error :
Module not found: 'child_process'.
I don't know what to do with this . I have read that adding custom configurations to the webpack.config.js may be the solution but i am using create react app so I don't have the Webpack configuration. I tried running npm run eject and create my own webpack.config.js but it doesn't work.
I hope somebody could help me.
You need to configure the correct target inside the webpack configuration: https://webpack.github.io/docs/configuration.html#target
module.exports = {
entry: './path/to/my/entry/file.js',
...
target: 'node',// we can use node.js modules after adding this configuration
};

Node's and Electron's modules from inside Angular2

I am developing an Electron application using Angular2.
In the electron's main.js I am referencing/loading the NG App:
const {app, BrowserWindow} = require('electron')
const path = require('path')
const url = require('url')
let win
function createWindow () {
win = new BrowserWindow({width: 800, height: 600})
// load the index.html of the NG app:
win.loadURL(url.format({
pathname: path.join(__dirname, '/../../dist/index.html'),
protocol: 'file:',
slashes: true
}))
[...]
This works like a charm. However, I'd now like to access node's and electron's modules from inside the NG part.
When I try to import e.g.: the fs module like:
import * as fs from "fs";
It still compiles but whenever I call fs.readFile(...) it says:
__WEBPACK_IMPORTED_MODULE_2_fs__.readFile is not a function
When I think about it, this does not and can not work since the modules are not inside the node_modules folder (right?).
What do I need to do to make them available inside the NG part?
In case this is still relevant -
I don't know of an "official" way for this yet. but there are work-around solutions - mainly around requiring electron/other modules in index.html and accessing window['electron'] -
<script>
window.electron = require('electron');
</script>
or creating an angular services accessing the electron object.
declare const window: ElectronWindow;
export class ChildProcessService {...}
You can see an implementaion of this Here
ElectronWindow refers to a custom interface you can create and add a require() function to for handling typings.
use window.require(*some-node-module*) to store modules
You cannot call Electron / Node modules directly from inside Angular. Instead, check out the Electron remote API.

huge files size when browserifying angular

I am just trying gulp + angular + browserify app and got a huge browserified file, about 2M. While all it does just require angular and a sample controller.
// setup gulp task
gulp.task('browserify', function() {
gulp.src([util.format('%s/app/main.js', JS_BASE_DIR)])
.pipe(browserify({
insertGlobals: true,
debug: true
}))
// Bundle to a single file
.pipe(concat('bundle.js'))
// Output it to our dist folder
.pipe(gulp.dest(util.format('%s/js/', BUILD_BASE_DIR)));
});
//in the main.js
(function() {
'use strict';
var angular = require('angular');
var indexCtrl = require('./controllers/indexCtrl');
var app = angular.module('wohu.app', []);
app.controller('ctrl', indexCtrl);
})();
angular is installed via
npm install angular
The bundle.js is not minified but it shouldn't be that huge. Wonder what the problem is.
Browserify will include a source map in the bottom of the file which can make it seem HUGE. You can strip this out (and you should) for production. You can use exorcist for this (https://www.npmjs.com/package/exorcist) which pulls the source map into an external file for you and can be hooked up to your build process (I use Grunt but will work for Gulp too).

Resources