Native modules support #12

Closed
hgupta9 opened this Issue Mar 16, 2015 · 13 comments

Projects

None yet

6 participants

@hgupta9
Contributor
hgupta9 commented Mar 16, 2015

Does enclose support native modules? Can it be packaged along with the executable or is it not supported at all?

@igorklopov
Owner

Enclose cannot package a native module inside executable. But it supports if you distribute a native module near the executable and require that native module at runtime. You may try serialport example: https://github.com/igorklopov/enclose/tree/master/examples/44-serialport

@igorklopov
Owner

Btw, enclose supports if you require pure node modules without recompilation. I mean you can use stock node-gyp and this issue electron/electron#713 will not bother you in enclose

@hgupta9
Contributor
hgupta9 commented Mar 17, 2015

Thats great! I'll try it out and let you know. Thanks for building this project!!

@hgupta9
Contributor
hgupta9 commented Mar 17, 2015

I'm getting some errors while packaging my app with enclose. I have compile.js, my index.js and couple of .node native module files in the same folder.

The .node binary files are built with node version 0.8.xx, and I have node version 0.8.xx installed.

My main code file index.js uses the node files with the following statements

var a = require('./a');
var b = require('./b');

(a.node and b.node are the native modules.)

For compile.js I have modified your serial port example:

try {
  require.resolve("./a");
} catch(error) {
  console.log("Failed to require('a')");
  console.log("Please run 'npm install' here");
  process.exit(1);
}

(and similar lines for module b.node)

The error:

{ was_required_as: './a',
file: 'D:\enclose\examples\test\index.js'
,
directory: 'D:\enclose\examples\test' }
undefined:0

Error: Cannot find module './a' from 'D:\enclose\examples\test'
at
at load ()
at
at
at FSReqWrap.oncomplete (fs.js:99:15)

@igorklopov
Owner

Unfortunately 0.8.x is too outdated to support. EncloseJS is similar to node 0.12 or (you can switch) iojs runtime environment. It means only modules compiled against 0.12 (or iojs) are compatible with EncloseJS. ALSO i see was_required_as - it old output format. Seems that you use outdated EncloseJS too. Please run npm update enclose

@hgupta9
Contributor
hgupta9 commented Mar 19, 2015

Thanks, I'll compile my modules for Node 0.12 and get back to you. Just for anyone reading this thread, I'm having trouble porting my native module from 0.8 to 0.12 so I'm using NAN to simplify the porting process.

NAN is the Native Abstraction layer for Node, and provides a set of C++ templates that enables you to compile for newer node versions WITHOUT changing your module source code, because they have tackled the inconsistencies and changes within the templates.

https://github.com/rvagg/nan

@hgupta9
Contributor
hgupta9 commented Mar 20, 2015

I managed to make native modules work with encloseJS. Great job!

  • I downloaded the latest encloseJS
  • I compiled all modules for Node 0.12
  • I placed .node files in same dir as compiled executable

Only issue is that when I run the app, it creates a copy of the .node files.
Eg: Suppose we have utils.node, it creates utils.MYSERVER.exe.node, which is a copy of the node file. Why does it create this copy?

@igorklopov
Owner

It is not a copy. If you compare, you will see differences. There is a problem with node native modules in win32 - they require executable name to be 'node.exe'. EncloseJS patches the IAT of native module before dlopen and binds it to 'myserver.exe'. And the patched module is placed near original one. If you dont like it, rename/replace original utils.node with utils.myserver.exe.node - EncloseJS will detect it is already patched and dont create a new file.

@hgupta9
Contributor
hgupta9 commented Mar 20, 2015

Fantastic! You have put so many advanced features into EncloseJS. Great job.

@hgupta9 hgupta9 closed this Mar 22, 2015
@serkanp
serkanp commented Apr 26, 2015

i have problem with native modules.. such as sqlite3
my app.js:
var fs=require('fs')
var path=require('path')
console.log(path.resolve(__dirname))
var moment=require('moment')
console.log(moment().format())
console.log('try loading sqlite3')
try {
require.resolve("sqlite3");
} catch(error) {
console.log("Failed to require('sqlite3')");
console.log("Please run 'npm install' here");
process.exit(1);
}

console.log('seems sqlite can be loaded')

var sqlite=require('sqlite3')

my package.json:
{
"name": "deneme",
"version": "1.0.0",
"description": "",
"main": "index.js",
"dependencies": {
"moment": "^2.10.2",
"sqlite3": "^3.0.5"
},
"devDependencies": {
"moment": "^2.10.2",
"sqlite3": "^3.0.5"
},
"scripts": {
"test": "echo "Error: no test specified" && exit 1"
},
"author": "",
"license": "ISC"
}

enclose output:
E:\deneme>enclose --x64 app.js

e:\deneme\node_modules\sqlite3\lib\sqlite3.js
warning Cannot resolve 'require(binding_path)'
Use a string literal as argument for 'require', or leave it
as is and specify the resolved file name in 'scripts' option

e:\deneme\node_modules\moment\moment.js
warning Cannot resolve 'require('./locale/' + name)'
Use a string literal as argument for 'require', or leave it
as is and specify the resolved file name in 'scripts' option

e:\deneme\node_modules\sqlite3\node_modules\node-pre-gyp\lib\node-pre-gyp.js
warning Cannot resolve 'require('./' + command)'
Use a string literal as argument for 'require', or leave it
as is and specify the resolved file name in 'scripts' option

e:\deneme\node_modules\sqlite3\node_modules\node-pre-gyp\lib\node-pre-gyp.js
warning Cannot resolve 'require('./' + c)'
Use a string literal as argument for 'require', or leave it
as is and specify the resolved file name in 'scripts' option

e:\deneme\node_modules\sqlite3\node_modules\node-pre-gyp\lib\pre-binding.js
warning Cannot resolve 'require(package_json_path)'
Use a string literal as argument for 'require', or leave it
as is and specify the resolved file name in 'scripts' option

i get this when i run app.exe:
E:\deneme>app.exe
e:\thebox\deneme
2015-04-26T23:26:47+03:00
try loading sqlite3
seems sqlite can be loaded
undefined:0

Error: Cannot find module 'e:\thebox\deneme\node_modules\sqlite3\lib\binding\nod
e-v14-win32-x64\node_sqlite3.node'
at Error (native)
at O ()
at c ()
at Object.Math.Enclose.+e+:++t+h+e+b+o+x++d+e+n+e+m+e++n+o+d+e+_+m+o+d+u+
l+e+s++s+q+l+i+t+e+3++l+i+b++s+q+l+i+t+e+3+.+j+s.dev ()
at u ()
at O ()
at c ()
at Object.Math.Enclose.+e+:++t+h+e+b+o+x++d+e+n+e+m+e++a+p+p+.+j+s.dev (<
anonymous>)
at u ()
at

@jlEMEE
jlEMEE commented Nov 17, 2015

Great idea !
I got that issue :
any idea ?

image

@Bambofy
Bambofy commented Jan 3, 2016

Hello, I ran into a similar problem of it reporting that it needs updating when trying to enclose my scripts.

2016-01-03_01-56-34

Any ideas?

(ran enclose on a fresh install from npm)

@AmitRaj07

My team has made a server application, which is running on RHEL6. We run this application in the development environment through the clear source code file (like main.js etc.) and we are also using the bcrypt module in this application. But my management has decided not to put source code in production, they wanted to put an executable (compiled version of the code) on production, so that an unauthorised person cannot see the code or do some malfunction activity.

Is it a good way to put executable (compiled version of the code) of a Node.js application or it will be better if we put source code in production?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment