How to include dependencies in J2V8 - node.js

How to include dependencies in J2V8? I would like to use certain dependencies in the javascript file for instance the crypto package.
var crypto = require('crypto');
function foo(){ return crypto.createHash('md5').update('Apple').digest("hex");}
However, I got the following error saying require keyword is undefined.
undefined:1: ReferenceError: require is not defined
var crypto = require('crypto');
^
ReferenceError: require is not defined at <anonymous>:1:14
com.eclipsesource.v8.V8ScriptExecutionException
at com.eclipsesource.v8.V8._executeVoidScript(Native Method)
Can anyone tell me how to import an package into J2V8?

Unless you're working with Node, require is not a feature. Usually, you want to use a bundler like webpack to pack your structured source code into one large file so that it can be understood by browsers. This way you can use require and npm packages for your frontend code, which makes development easier, and a bundler turns it with every build (or live update) into a different format, that's hard to read for humans, but is valid Javascript.

I have had success using node modules in J2v8, please check out this blog :http://eclipsesource.com/blogs/2016/07/20/running-node-js-on-the-jvm/
NodeJs nodeJS = NodeJs.createNodeJs();
After registering callbacks
nodeJs.exec(File thescripttoexecute)
Make sure you have the proper path to the node modules in the require() command.

You may have to make a nodejs package that takes dependencies and exports what you need. Then, You have to execute npm install manually.
or You can just npm install what-you-need.
Create Node JS Runtime, and use require with your your-package-dir/index.js or exact location of module that you need. like this:
V8Object module = nvm.require(file);
Now you can call the function likes:
module.executeJSFunction("test");
To deliver entire dependencies you have to bundlize module directory your self.
What if you have to support cross-platform, refer https://www.npmjs.com/package/node-pre-gyp also.

Related

Dynamic require not supported in React Native

I have just tried to use wasm bindings in a react-native project. But the wasm bindings require access to node modules like fs so I used rn-nodeify as a work-around to get the React Native representation of fs and to be able to use require. That worked fine but I think that the wasm bindings are incompatible with react native, because I get the error Dynamic require defined at line 10; not supported by Metro. The error is talking about the line below:
//line 10
const { TextDecoder, TextEncoder, inspect } = require(String.raw`util`);
The bindings I'm using are from this package #iota/identity-wasm
Steps to reproduce
If you want to reproduce this issue I have created a sample RN Project that throws the error by startup.
git clone https://github.com/JonasHiltl/DigitalIdentityNodeified.git
cd ./DigitalIdentityNodeified
npm install
npx react-native start
npx react-native run-android
I'm interested to know what exactly a dynamic require is and if it's possible to replace the dynamic require with a normal one.
Sadly you cannot use require dynamicly in react-native :/
You will have to make a require for every single thing you will need.
Check out this for example:
Dynamic require not supported in React Native

Loading Nodejs Module at runtime in electron app

Currently I am playing around with electron using vue-cli-plugin-electron-builder along side a simple vue project. This is the project https://github.com/nklayman/vue-cli-plugin-electron-builder .
vue create my-project
cd my-project
vue add electron-builder
npm run electron:serve
My goal is to add a simple plugin-like architecture. The app serves only base functionality but can be extended with "plugins". Those plugins therefore are not included in the built, but will be loaded at runtime by electron. I would prefere when those plugins just behave like node modules ( module.exports = ) with its own dependencies ( probably with a package.json file inside ). I would locate those plugins at app.getPath('userData') + '/Plugins.
I looked at a few approaches on how to tackle this problem :
1. Using Nodejs vm module
First, I tried using Nodejs vm module to read and execute a script from an external file, all at runtime. It works great so far, although I would not be able to use external dependencies inside those loaded scripts. If I want to use external dependencies inside the plugin scripts, those dependencies must have been included in the electron build beforehand. Somehow defeats the whole purpose of having plugins ... only vanilla js + nodejs base modules would be possible .
2. using global.require
I saw this solution in another SO answer.
Using node require with Electron and Webpack
Webpack/electron require dynamic module
They say to use global.require but it throws an error saying global.require is not a function. The solution looked promising first, but somehow I can't get it to work.
3. simply use require
Of course I had to try it. When I try to require an external module from a non-project location it won't find the module, even if the path is correct. Again, the path I am trying to locate the module should be at app.getPath("userData"), not in the projects root directory. When however, I locate the plugins inside the root directory of the project it gets included in the built. This again defeats the purpose of having plugins.
Goal
So far, I haven't found a viable solution to this. I simply want my electron app to be extendible with basic node modules at runtime ( following a pre-defined schema to simplify ) . Of course there is atom, made with electron, using their own apm manager to install and load plugins, but this seems way to overpowered. Its enough for me to only have plugin files located locally, to have a public "marketplace" is no goal. Also, it's ok if the app has to reload / restart to load plugins.
Any ideas ?
After more and more research I stumbled over 2 packages :
https://www.npmjs.com/package/live-plugin-manager
https://github.com/getstation/electron-package-manager
both integrating npm to programmatically handle package installation at runtime. I settled for live-plugin-manager for now since its better documented and even allow package installation from local file system.
Pro
I was able to integrate the system out-of-the-box into a vanilla electron app. Works like a charm.
Cons
.I was not able to use it inside a vue electron boilerplate (like the one I said I was using in OP), since webpack is interferring with the require environment. But there sure is a solution to this.
Update : I was able to get it to work eventually inside a webpack bundled electron vue boilerplate. I accidentally mixed import and require . The following code works for me using live-plugin-manager
// plugin-loader.js
const path = require('path');
const { PluginManager } = require('live-plugin-manager');
const pluginInstallFolder = path.resolve(app.getPath('userData'), '.plugins');
const pluginManager = new PluginManager();
module.exports = async (pkg) => {
// installs pkg from npm
await pluginManager.install(pkg);
const package = pluginManager.require(pkg);
return package
}
// main.js
const pluginLoader = require('./plugin-loader');
pluginLoader("moment").then((moment) => {
console.log(moment().format());
})
This will install "moment" package from npm during runtime into a local directory and load it into the app, without bundling it into the executable files.

Browserify - JsSip

I have a new project where I'm using browserify to convert node modules into an sdk that can run inside the browser.
I'm requiring a number of other npm packages like:
var log4js = require('log4js');
That run fine and give me no problems in the browser, however JsSip just will not cooperate. When I do
var JsSIP = require('jssip');
I get
plivowebsdk.js:2 Uncaught Error: Cannot find module '../../package.json'
Looking through the code, it's obvious when it makes this call
var pkg = require('../../package.json');
is where it bombs out. Clearly it cannot find the package.json file, which it uses to pull out version information. I know JsSip is actually built with browersify itself (or used to be) so that it can run in either node or a browser. Is this causing a conflict?
Still sort of new to browserify, is their a configuration option or transformation I can perform to get around this?
Turned out the be browserify errors, re did the build process using the gulp recipes for browersify and works as expected.

Do all npm packages need an export?

I am new to nodejs packages and what I understood was that to share code you had to do a module.export (in addition to adding a package.json)
For example bootstrap-select does not have an export function but is available on npm.
So my question is do all modules require an export and also can I do a require('bootstrap-select') in my code?
no, all npm modules do not require an export. npm is now being used more generally for not only javascript packages intended for use under node.js but front end code for browsers, CSS libraries, etc. At the very least, an npm package could just deliver a payload of files not even including any javascript, such as some images, some CSS, some HTML, etc.
So you can only do require('some-module') if that package has either an index.js file or has set the main property in it's package.json file properly.
However if you are authoring a javascript module for node.js, then yes you'll need to export something in order for your module to load properly.
No, npm modules do not require doing something with module.exports. If you do not touch that object, requireing your module will return an empty object (since that is the default for module.exports. However, this can be useful if your module is only intended to be required for side effects, rather than a return value.
For example, the module you linked to modifies global state by attaching a jQuery event handler.
As per i know ,
1.All npm modules are not required to build an app.
2.If we use var bootStrap = require('bootstrap-select'); using bootStrap variable you can access bootStrap module.
so we can pass that object in anywhere of your code
3.To install a dependency modules,
In package.json give dependency block as like this
"dependencies": {
"express": "2.3.12",
"jade": "latest",
"redis": "0.6.0"
}
you can change and edit your packages. then enter a command npm install in command prompt it will install only dependency modules.
If i made any mistakes please correct me Thanks.

Use a node module from casperjs

Is it possible to install a node module, installed via npm, and then require it from a casperjs script?
(I see lots of posts and tools for running casper or phantom from inside node.js, but that is not what I'm trying to do.)
The casperjs docs seem to say it is possible, but only show with hand-written toy modules that don't really do anything. The real-world module I'm trying to install is imap, but at this point I cannot get any module to work, even built-in ones like net. Simple example:
npm install imap
echo "var test = require('imap');" > test.js
casperjs test.js
Gives me:
CasperError: Can't find module imap
/usr/local/src/casperjs/bin/bootstrap.js:263 in patchedRequire
test.js:1
(I can see the imap module from npm ls, and I can use it fine from a node.js script.)
Or alternatively with a built-in module:
echo "var test = require('net');" > test.js
casperjs test.js
Complains "Can't find module net"
I have npm --version of 1.4.14 and nodejs --version of v0.10.29. Are either of those too old, I wonder? (Casper is 1.1.0-beta, and Phantom is 1.9.7, both of which are the latest versions.)
PhantomJS and SlimerJS (the engines that are used for CasperJS) are not Node.js modules. They can be installed through npm for convenience. They have a different base infrastructure of modules which is distinct from Node.js.
You will not be able to use imap or any module that depends on the net module. As Fanch points out, there are modules that can work inside the phantomjs runtime.
If a module only uses some functionality of some native node.js module, you could try to change the implementation to use the API that phantomjs provides. I don't think this is easy though. Most of the time you will run into a wall.
In the case of imap, it is pretty hopeless. You cannot even re-implement the require("net").Socket, because WebSockets are not supported in phantomjs (at least in 1.9.7).
Here an example with the colors module :
var colors = require('colors');
casper.test.begin('\n*Colors module*\n', function suite(test) {
casper.start()
.thenOpen('https://www.google.fr/', function() {
console.log("test require\n".zebra);
console.log("test require\n".rainbow);
console.log("test require\n".red.underline.bold);
})
.run(function() {
test.done();
});
});
node-modules
colors
testnode.js
casperjs test testnode.js
output :
It seems it's not as simple when the required module has dependencies.
In my case, I wanted to load underscorejs. Underscore is a series of functions and don't have complicated interactions with javascript objects, so there is no problem just requiring the javascript file and then having access to its functions.
I started by finding the root to my nodejs installation (from the CLI):
node --help
Which led me to finding my node path:
echo $NODE_PATH
Which was at:
/usr/local/lib/node_modules/
Underscore was at
/usr/local/lib/node_modules/underscore/underscore.js
So my final require statement in my CasperJS script was.
var _ = require('/usr/local/lib/node_modules/underscore/underscore.js');
Now in my script I test to see if underscorejs is loaded:
this.echo(_.now());
And I see the current time.
CAVEAT: Since this is running asynchronously, if you put your _.now() statement right after the require, it will give you an undefined object error. As a note, I'm using Casper 1.1, which uses PhantomJS's native require() function. If you are using < Casper 1.1, I don't think require will work.
UPDATE:
Since this is the case, I use CasperJS then() function to load my utilities synchronously, making sure to declare my variables within the global scope. Here's how that looks:
//at the top of the file-ish, declare variables that will hold loaded libraries.
var utils, _;
var casper = require('casper').create(); //create casper
casper.start('http://example.com'); //start casper at URL.
casper.then(function loadRequires(){ //load the requirements
utils = require('utils', function(){this.echo('utils loded')});
_ = require('/usr/local/lib/node_modules/underscore/underscore.js');
});
casper.then(function myAwesomeStuff() {
this.echo(_.now()); //now, access the loaded requirements
utils.dump('this stuff is soooo awesome!!!!!!!!!!!!!!!!!!!!');
//do stuff on the page you opened in the start function here.
);
});
You can read more about the Casper prototype and the then() method at the API docs: http://casperjs.readthedocs.org/en/latest/modules/casper.html#casper-prototype

Resources