Node-oracledb: Doesn't work with babel

Created on 6 Sep 2016  路  10Comments  路  Source: oracle/node-oracledb

node-oracledb doesn't work when compiling ES6 modules with Babel. I'm using TypeScript + Babel, but I don't believe the use of TypeScript is relevant in this bug.

The following ES6 code doesn't work:

import * as OracleDB from "oracledb";

export const getConnection = () => {
    const promise = OracleDB.getConnection({
        user: "user",
        password: "pw",
        connectString
    }).then(conn => {

    });
};

If I don't use _interopRequireWildcard the function works.

Doesn't work (compiled ES5 JavaScript):

var _oracledb = require("oracledb");

function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }

var OracleDB = _interopRequireWildcard(_oracledb);

The following works:

var OracleDB = require("oracledb");

Answer the following questions:

  1. What error(s) you are seeing?
TypeError: Cannot read property 'Promise' of undefined
    at Object.getConnection (/Users/pahorsma/dev/app/node_modules/oracledb/lib/util.js:96:24)

The error originates from this line:
https://github.com/oracle/node-oracledb/blob/master/lib/util.js#L96

  1. What _exact_ command caused the problem (e.g. what command did you try to install with)?
 OracleDB.getConnection()
  1. What environment variables did you set? How _exactly_ did you set them?
    None
  2. What is your version of Node.js?
    6.4.0
  3. What is your version of the Oracle client (e.g. Instant Client)? How was it installed? Where it is installed?
    instantclient 12.1.0.2.0
  4. What is your OS and version?
    Mac OS X 10.11.6
  5. What compiler version did you use?
    Latest XCode
question

Most helpful comment

@panuhorsmalahti Could you please try changing this line:

import * as OracleDB from "oracledb";

to this:

import OracleDB from "oracledb";

That's shorthand for this:

import {default as OracleDB} from "oracledb";

Either one should work. It's a way of telling Babel to import the default export. When using the asterisk as you were doing before, Babel used _interopRequireWildcard instead of _interopRequireDefault. It seems that _interopRequireWildcard enumerates the properties of the export to create a new object. Not all properties are enumerable which lead to the error you saw.

All 10 comments

For the non-Babel readers (like me), can you give some more context, some setup hints, and working & non working testcases?

Here's a minimal setup to reproduce the error:

First install babel-cli:

npm install -g babel-cli

Save the following as test.js:

import * as OracleDB from "oracledb";
OracleDB.getConnection();

Run the file with babel-node test.js.

The output:

pahorsma app $ babel-node test.js 
/Users/pahorsma/dev/app/node_modules/oracledb/lib/util.js:96
    if (!self._oracledb.Promise || typeof arguments[arguments.length - 1] === 'function') {
                       ^

TypeError: Cannot read property 'Promise' of undefined
    at Object.getConnection (/Users/pahorsma/dev/app/node_modules/oracledb/lib/util.js:96:24)
    at Object.<anonymous> (/Users/pahorsma/dev/app/test.js:2:10)
    at Module._compile (module.js:556:32)
    at loader (/usr/local/lib/node_modules/babel-cli/node_modules/babel-register/lib/node.js:146:5)
    at Object.require.extensions.(anonymous function) [as .js] (/usr/local/lib/node_modules/babel-cli/node_modules/babel-register/lib/node.js:156:7)
    at Module.load (module.js:473:32)
    at tryModuleLoad (module.js:432:12)
    at Function.Module._load (module.js:424:3)
    at Function.Module.runMain (module.js:590:10)
    at /usr/local/lib/node_modules/babel-cli/lib/_babel-node.js:151:24

This ES6 code can be compiled to ES5 with babel.

A working test case simply uses ES5 modules:

var OracleDB = require("oracledb");
OracleDB.getConnection();

@panuhorsmalahti After looking into this a little, I think it has to do with the way that import in Babel differs from require when it comes to circular references (which is essentially what self._oracledb is in the error).

We should be able to put together a solution. In the meantime, please use require.

@dmcghan are you tracking this?

@cjbj Yes, I have a note to look into the with the next round of enhancements.

@dmcghan ping

@panuhorsmalahti Could you please try changing this line:

import * as OracleDB from "oracledb";

to this:

import OracleDB from "oracledb";

That's shorthand for this:

import {default as OracleDB} from "oracledb";

Either one should work. It's a way of telling Babel to import the default export. When using the asterisk as you were doing before, Babel used _interopRequireWildcard instead of _interopRequireDefault. It seems that _interopRequireWildcard enumerates the properties of the export to create a new object. Not all properties are enumerable which lead to the error you saw.

@panuhorsmalahti ping?

The import OracleDB from "oracledb"; form works fine (at least with TypeScript + Babel)! Thank you.

@panuhorsmalahti thanks for the feedback.

Was this page helpful?
0 / 5 - 0 ratings