nodejs : how to compile grpc with newer openssl? - node.js

I would like to compile grpc with newer openssl( >= 1.1.0 ) in nodejs project, but I have no idea how to get along with it.
Here is the package.json in the whole project.
{
"name": "fabcar",
"version": "1.0.0",
"description": "FabCar application implemented in JavaScript",
"engines": {
"node": ">=8",
"npm": ">=5"
},
"scripts": {
"lint": "eslint .",
"pretest": "npm run lint",
"test": "nyc mocha --recursive"
},
"engineStrict": true,
"author": "Hyperledger",
"license": "Apache-2.0",
"dependencies": {
"fabric-ca-client": "~1.4.0",
"fabric-network": "~1.4.0"
},
"devDependencies": {
"chai": "^4.2.0",
"eslint": "^5.9.0",
"mocha": "^5.2.0",
"nyc": "^13.1.0",
"sinon": "^7.1.1",
"sinon-chai": "^3.3.0"
},
"nyc": {
"exclude": [
"coverage/**",
"test/**"
],
"reporter": [
"text-summary",
"html"
],
"all": true,
"check-coverage": true,
"statements": 100,
"branches": 100,
"functions": 100,
"lines": 100
}
}
And in this project, the fabrc-ca-client, fabric-network will uses grpc.
here is some env:
$ npm version
{ npm: '6.4.1',
ares: '1.10.1-DEV',
cldr: '32.0',
http_parser: '2.8.0',
icu: '60.1',
modules: '57',
napi: '4',
nghttp2: '1.33.0',
node: '8.16.0',
openssl: '1.0.2r',
tz: '2017c',
unicode: '10.0',
uv: '1.23.2',
v8: '6.2.414.77',
zlib: '1.2.11' }
$ node -v
v8.16.0
Please help on compile grpc in nodejs with newer openssl(>=1.1.0).
I am using Ubuntu 18.04 and only need to building on linux.
Any advice would be greatful!
Thanks!

There are three major obstacles to building grpc with a different OpenSSL library. First, Node.js already exports the OpenSSL symbols for native modules to dynamically link against. This means that you won't be able to dynamically link your own OpenSSL library; it would cause symbol collision errors. You would need to statically link the library, and be sure to hide the symbols. This can require either explicitly linking the relevant .a file if you already have one, or compiling the library from source as part of the build process. This is not an issue when building for Windows or for Electron, so you should be able to get away with dynamically linking in those cases
Second, the OpenSSL headers are included in the Node headers that are included by default when building native addons like grpc. If you want to use your own version of OpenSSL, you will need to use your own headers for that version instead of those headers. We currently need to do this to use BoringSSL in the Windows library, so we have node-gyp download the headers, then we go in and delete the openssl directory, then build the library for real. You will likely need to do that in this situation too. This isn't an issue on Electron.
Third, grpc is written to use a variety of specific APIs in OpenSSL. Depending on which other version you want to use, there is a chance that it will not be compatible. I am not sure what the usable version range is here, but this is something to keep in mind.
If you can solve all of these problems, you will need to make some significant edits to grpc's binding.gyp file to accomplish this. If you are building OpenSSL from source, the existing boringssl target should be a good template. You can add a similar target for openssl and then have the grpc target depend on it. If you already have a .a file, you should be able to add a linker flag to the grpc target to link it. In either case, make sure to remove references to other OpenSSL headers in various parts of the file.

Related

How to include Node.js native modules while compiling to .exe

I'm using pkg to compile my Node.js project into an executable.
The project includes a native module called "node-printer".
Pkg has problems compiling this module, because when i run the executable i get this error:
pkg/prelude/bootstrap.js:1359
throw error;
^
.....
(internal/modules/cjs/loader.js:1218:10),Module.load (internal/modules/cjs/loader.js:1047:32)] {
code: 'MODULE_NOT_FOUND',
requireStack: [
'C:\\snapshot\\ckiosk\\node_modules\\printer\\lib\\printer.js',
'C:\\snapshot\\ckiosk\\controllers\\receiptController.js',
'C:\\snapshot\\ckiosk\\api\\ajax.js',
'C:\\snapshot\\ckiosk\\webApp.js',
'C:\\snapshot\\ckiosk\\main.js'
]
This is from the pkg readme:
Native addons (.node files) use is supported. When pkg encounters a .node file in a require call, it
will package this like an asset. In some cases (like with the bindings package), the module path is
generated dynamicaly and pkg won't be able to detect it. In this case, you should add the .node file
directly in the assets field in package.json.
Here is the pkg in my package.json file
"pkg": {
"scripts": [
"config/*.js"
],
"assets": [
"views/*",
"views/**/*",
"config/*",
"public/assets/**/*",
"node_modules/printer/lib/node_printer.node"
],
"targets": [
"node14-win"
]},
As you can see, i've included the node printer .node file in the assets, but the result is still the same.
What am i missing?
Turns out i have been using the wrong command to build.
I used this
pkg "main.js" -t node14-win -o build/ckiosk.exe
But to make use of the configuration in package.json we have to use
pkg .

Intellisense for module-alias Package

I am using this npm module (module-alias)
https://www.npmjs.com/package/module-alias in my Node project.
To make use of this package you have to set path aliases in the package.json file.
However, using this package comes with the disadvantage, that intellisense doesn't work anymore.
My question is how to enable intellisense with those path aliases?
The problem is that you did not register those aliases anywhere with your linter. I would gerenally suggest to use ESLint here (even if you use TypeScript as TSLint will be discontinued in favour of ESLint). My examples will include the TypeScript endings as well. If you definately want to make it work for JavaScript only you can skip the .ts .tsx extentensions in the eslint) So to make intellisense work do this in
.eslintrc.js
settings: {
"import/resolver": {
alias : {
map: [
["#","./src"]
],
extensions: [".js", ".jsx", ".ts", ".tsx"],
},
}
},
Note that in this case you will need the import Plugin for ESLint. If you don't already have it install it.
If you are using TypeScript you will also have to make that alias known to your compiler. So add this to your
tsconfig.json
"compilerOptions": {
"baseUrl": ".",
"paths": [
"#/*" : [
"src/*"
]
]
}

How to bundle node project into one file

Is there any WORKING way how to bundle node project into one single file (including dependencies) and how?
I am using babel (.babelrc)
{
"presets": ["#babel/preset-env"],
"plugins": [
[
"module-resolver",
{
"root": [
"./src"
],
"alias": {
"test": "./test",
"underscore": "lodash"
}
}
]
]
}
the answer is no. babel can not do what you want by itself. It is a tool for transforming one dialect of Javascript into another, based on rules defined in your .babelrc file. It is a compiler, not a linker (to borrow terms from the C world).
Using babel-plugin-module-resolver will not cause babel to transpile dependencies as if they were source files. It is simply a babel rule which modifies the paths passed to require() or import.
To include dependencies as well as source files you need to use both a compiler like babel and a bundler such as webpack or rollup.

Make babel exclude test files

On my build step I'm using babel to transpile the code to es5 (from src to dist). How do I make it exclude files ending in .test.js?
package.json
"scripts": {
"build": "babel src --out-dir dist",
.babelrc
{
"presets": [ "es2015" ],
"ignore": "\\.test\\.js"
}
Based on the documentation, you should be able to write .babelrc
{
"ignore": [
"**/*.test.js"
]
}
However, I was able to verify that this does not seem to work. I tried it with version 6.5.1 (babel-core 6.5.2).
At the same time, the following does work:
babel src --out-dir build --ignore '**/*.test.js'
That is the same glob pattern as written in the .babelrc file. If you install any glob library from npm you'll find that this glob pattern would work (that is how I came up with it...I do not currently use babel).
As of today, the following works in .babelrc
(babel-core: v6.26.3)
"ignore": [
"**/__tests__", // ignore the whole test directory
"**/*.test.js" // ignore test files only
]

How do I use TypeScript 1.6 with Visual Studio Code to get generators support?

I've been targeting ES6 for a while in Visual Studio Code, but when I try to switch to TypeScript, it throws errors such as:
Generators are only available when targeting ECMAScript 6
But my tsconfig.json does have the ES6 target:
{
"compilerOptions": {
"target": "ES6",
"module": "amd",
"sourceMap": true
}
}
So I tried npm install -g typescript#1.6.0-beta but it looks like VSCode doesn't care.
Generators are not currently supported.
How can I get TypeScript and generators to work properly together in VS Code?
Update
Changing typescript.tsdk to the 1.6 binary seems to fix IntelliSense errors, but this tasks.json still prints out error TS1220: Generators are only available when targeting ECMAScript 6 or higher.:
"version": "0.1.0",
"command": "/usr/local/lib/node_modules/typescript/bin/tsc",
"showOutput": "silent",
"windows": {"command": "tsc.exe"},
"isShellCommand": true,
"args": ["app.ts"],
"problemMatcher": "$tsc"
However, /usr/local/lib/node_modules/typescript/bin/tsc --target ES6 app.ts used manually in the terminal does work.
I know now!
1. IntelliSense
You can use the typescript.tsdk setting to point VSCode to TypeScript binaries. Upgrade your TypeScript to 1.6 and set the location properly.
You can do it either in your user/workspace settings, or per project in the .vscode/settings.json file. OS X example:
"typescript.tsdk": "/usr/local/lib/node_modules/typescript/lib"
2. Compiler
You also need to make sure your .vscode/tasks.json points to the new binary and makes the compiler operate in Explicit project mode, i.e. use tsconfig.json instead of taking a list of files to compile as an argument.
{
"version": "0.1.0",
"command": "/usr/local/lib/node_modules/typescript/bin/tsc",
"showOutput": "silent",
"windows": {"command": "tsc.exe"},
"isShellCommand": true,
"args": [], //do not pass any files to the compiler. This way it will use tsconfig.json where you can set target: "ES6"
"problemMatcher": "$tsc"
}
And finally tsconfig.json (in the project's root directory):
{
"compilerOptions": {
"target": "ES6", //The key, of course.
"module": "amd",
"sourceMap": true
},
"exclude": [
"node_modules",
".vscode"
]
}
Restart the editor afterwards!
You can change your user settings in VS Code and set "typescript.tsdk" to a custom location .
If you install the nightly (npm install -g typescript#next), you can point to that version of TypeScript's lib folder.
More
Reasons and setup instructions for using ts latest are covered here : https://basarat.gitbooks.io/typescript/content/docs/getting-started.html#typescript-version

Resources