Node-oracledb: NJS-045: cannot load a node-oracledb binary when building with TypeScript, commanderjs and Webpack

Created on 10 Feb 2020  Â·  8Comments  Â·  Source: oracle/node-oracledb

See https://www.oracle.com/corporate/security-practices/assurance/vulnerability/reporting.html for how to report security issues.

  1. Is it an error or a hang or a crash?
    Error

  2. What error(s) you are seeing?

Error: NJS-045: cannot load a node-oracledb binary for Node.js 13.8.0 (linux x64)
Looked for /build/Release/oracledb-4.2.0-linux-x64.node, /build/Release/oracledb.node, /build/Debug/oracledb.node, /node_modules/oracledb/build/Release/oracledb-4.2.0-linux-x64.node, /node_modules/oracledb/build/Release/oracledb.node
Node-oracledb installation instructions: https://oracle.github.io/node-oracledb/INSTALL.html

  1. Run node and show the output of:
> process.platform
'linux'
> process.version
'v10.16.3'
> process.arch
'x64'
> require('oracledb').versionString
'4.2.0'
> require('oracledb').oracleClientVersionString
'19.3.0.0.0'

Description of the problem

Hi all guys, i have read all of the #1156 to see if anything can help me, but not.

I'm trying to build a CLI using commanderjs and TypeScript 3.6.4. I don't use node-oracledb directly, instead, i use sworm to handle that for me.

Here is my tsconfig.json

{
  "compilerOptions": {
    "target": "es6",
    "module": "commonjs",
    "types": ["reflect-metadata"],
    "outDir": "lib",
    "moduleResolution": "node",
    "experimentalDecorators": true,
    "emitDecoratorMetadata": true,
    "inlineSourceMap": true,
    "lib": ["es2017"]
  }
}

Here is my webpack.config.js

const path = require('path');

module.exports = {
  entry: ['./node_modules/oracledb/index.js', './dist/index.js'],
  target: 'node',
  output: {
    path: path.join(__dirname, 'build'),
    filename: 'build.js',
  },
};

And, here is my package.json

{
  "name": "@e3labs/sync-erp-connector",
  "version": "0.0.12",
  "description": "",
  "main": "lib/index.js",
  "bin": {
    "sync-erp-connector": "bin/sync-erp-connector"
  },
  "scripts": {
    "test": "NODE_ENV=test mocha -r ts-node/register src/**/*.spec.ts",
    "clean": "rm -rf dist/ build/ lib/",
    "build": "yarn clean && tsc",
    "build:docs": "typedoc --out docs ./src --ignoreCompilerErrors --mode modules",
    "build:docker": "docker build . -t sync-erp-connector",
    "build:webpack": "webpack --config webpack.config.js",
    "publish:docker": "docker push sync-erp-connector",
    "format": "yarn prettier -- --config .prettierrc --write 'src/**/*.ts'",
    "format:test": "yarn prettier -- --config .prettierrc -c 'src/**/*.ts'",
    "server": "node dist/index.js",
    "cmd:global": "yarn build && yarn build:webpack && yarn global add $PWD && sync-erp-connector doctor -f $PWD/.env",
    "lint": "tslint -c tslint.json 'src/**/*.ts'",
    "start:dev": "node --inspect=0.0.0.0:9229 -r ts-node/register ./src/index.ts",
    "dev": "nodemon",
    "release": "standard-version --release-as"
  },
  "license": "ISC",
  "dependencies": {
    "axios": "^0.19.0",
    "body-parser": "^1.19.0",
    "commander": "^4.1.1",
    "compression": "^1.7.4",
    "cors": "^2.8.5",
    "dotenv": "^8.2.0",
    "express": "^4.17.1",
    "express-validator": "^6.2.0",
    "http-status-codes": "^1.3.2",
    "inversify": "^5.0.1",
    "inversify-express-utils": "^6.3.2",
    "jsonwebtoken": "^8.5.1",
    "log-symbols": "^3.0.0",
    "nodemon": "^1.19.1",
    "oracledb": "^4.2.0",
    "pjson": "^1.0.9",
    "prettier": "^1.18.2",
    "pretty-quick": "^2.0.0",
    "reflect-metadata": "^0.1.13",
    "source-map-support": "^0.5.13",
    "sworm": "^3.8.0",
    "winston": "^3.2.1"
  },
  "devDependencies": {
    "@commitlint/cli": "^8.2.0",
    "@commitlint/config-conventional": "^8.2.0",
    "@e3labs/isa-data-dictionary": "^0.1.117",
    "@types/body-parser": "^1.17.1",
    "@types/express": "^4.17.1",
    "@types/node": "12",
    "@types/winston": "^2.4.4",
    "copy-webpack-plugin": "^5.1.1",
    "husky": "^3.0.9",
    "string-replace-loader": "^2.2.0",
    "ts-loader": "^6.2.1",
    "ts-node": "^8.4.1",
    "tslint": "^5.20.0",
    "tslint-config-prettier": "^1.18.0",
    "tslint-misc-rules": "^3.5.1",
    "typedoc": "^0.15.0",
    "typescript": "^3.6.4",
    "webpack": "^4.41.2",
    "webpack-cli": "^3.3.9"
  },
  "husky": {
    "hooks": {
      "pre-commit": "yarn lint --fix && pretty-quick --staged",
      "commit-msg": "commitlint -E HUSKY_GIT_PARAMS"
    }
  },
  "engines": {
    "node": ">= 10.16"
  }
}

What's the catch?

Everything runs fine (locally) if i create a build of javascript files using tsc (typescript) and a bundle with webpack. Everything is okay if a use yarn global add $PWD to install and test my CLI in my machine.

The problem is when i publish the package and other people try to use my newly CLI.

To release a new version, i do the following:

  • yarn clean clean the build, lib and dist folders
  • yarn build runs tsc for me and generates a dist/ folder with JavaScript files
  • yarn build:webpack look for files in dist/ folder and generate a single bundle.js
  • npm publish self explanatory

When my webpack.config.js don't includes oracledb in their entry file list, i get:

Error: oracledb driver not found, please install it with: npm install oracledb

When i include oracledb in my webpack, i get:

Error: NJS-045: cannot load a node-oracledb binary for Node.js 13.8.0 (linux x64)

So, i tryied to only use JS files created by TypeScript.

The same happens:

Error: NJS-045: cannot load a node-oracledb binary for Node.js 13.8.0 (linux x64)

oracledb don't know how to find the binaries in a CLI execution context

help wanted question

All 8 comments

Did you review the discussion in https://github.com/oracle/node-oracledb/issues/1156 ?

Hi @cjbj sorry for the late response.

Yes, i saw that discussion, and i saw a solution proposed by you. But i'm waiting for a new release to update my project and test that. Thanks!

@WandersonAlves OK! But any testing or comments you can make now, will make sure that the final release does what you need.

Hi @cjbj i was able to build with the current fixes!

But my program runs and closes immediately with status code 1.
I don't think this has any relations with oracledb.

I'll continue to investigate this

Updating:

I have found the following error

➜ ./bin/sync-erp-connector start -f .env
19:21:56 info:main: ------------------- Command: start -------------------


19:21:56 verbose:main: Starting...
19:21:56 info:main: Configuring server
19:21:56 verbose:main: Bootstraping server
19:21:56 info:main: Trying to connect to SQL database
TypeError: nodbUtil.callbackify is not a function
    at Object._extend (/home/popoto/Desktop/dev/e3/isa-v2/sync-erp-connector/node_modules/oracledb/lib/oracledb.js:102:35)
    at Object.<anonymous> (/home/popoto/Desktop/dev/e3/isa-v2/sync-erp-connector/node_modules/oracledb/lib/oracledb.js:380:14)
    at Module._compile (internal/modules/cjs/loader.js:778:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:789:10)
    at Module.load (internal/modules/cjs/loader.js:653:32)
    at tryModuleLoad (internal/modules/cjs/loader.js:593:12)
    at Function.Module._load (internal/modules/cjs/loader.js:585:3)
    at Module.require (internal/modules/cjs/loader.js:692:17)
    at require (internal/modules/cjs/helpers.js:25:18)
    at Object.<anonymous> (/home/popoto/Desktop/dev/e3/isa-v2/sync-erp-connector/node_modules/oracledb/index.js:1:18) Promise {
  <rejected> TypeError: nodbUtil.callbackify is not a function
      at Object._extend (/home/popoto/Desktop/dev/e3/isa-v2/sync-erp-connector/node_modules/oracledb/lib/oracledb.js:102:35)
      at Object.<anonymous> (/home/popoto/Desktop/dev/e3/isa-v2/sync-erp-connector/node_modules/oracledb/lib/oracledb.js:380:14)
      at Module._compile (internal/modules/cjs/loader.js:778:30)
      at Object.Module._extensions..js (internal/modules/cjs/loader.js:789:10)
      at Module.load (internal/modules/cjs/loader.js:653:32)
      at tryModuleLoad (internal/modules/cjs/loader.js:593:12)
      at Function.Module._load (internal/modules/cjs/loader.js:585:3)
      at Module.require (internal/modules/cjs/loader.js:692:17)
      at require (internal/modules/cjs/helpers.js:25:18)
      at Object.<anonymous> (/home/popoto/Desktop/dev/e3/isa-v2/sync-erp-connector/node_modules/oracledb/index.js:1:18) }

Below is my webpack config:

const path = require('path');
const CopyPlugin = require('copy-webpack-plugin');

module.exports = {
  entry: ['./node_modules/oracledb/index.js','./lib/index.js'],
  target: 'node',
  output: {
    path: path.join(__dirname, 'build'),
    filename: 'build.js',
  },
  plugins: [
    new CopyPlugin([
      {
        // Copy the binary Oracle DB driver to dist.
        from: path.resolve(__dirname, 'node_modules/oracledb/build'),
        to: 'node_modules/oracledb/build',
      },
    ]),
  ],
  externals: {
    'sqlite3': 'sqlite3', //without this, i get a error about 'aws-sdk' not found
  },
};

My build process is:

  • First, build typescript files to javascript
  • Then, runs webpack and generates a single .js file
  • Expose a .bin to allow to run on terminal

So, webpack is messing around the require on oracledb.js:22 that requires "./utils.js"?

Oh, nvm. i was just copying&pasting lib/oracledb.js. There's other fixes/changes in the files :smile:

In case it helps, I cloned and updated the webpack example of @MisterMX. It is in https://github.com/cjbj/node-oracledb-webpack-example

Node-oracledb 5 was just released with some improved support for webpack. You still need a CopyPlugin See https://github.com/oracle/node-oracledb/issues/1156#issuecomment-598017250.

On some platforms the new initialization options might be handy, too.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

eunier picture eunier  Â·  4Comments

PaulBrookes picture PaulBrookes  Â·  4Comments

nicholas-ochoa picture nicholas-ochoa  Â·  3Comments

JocelynDalle picture JocelynDalle  Â·  3Comments

sanfords picture sanfords  Â·  3Comments