Node-postgres: importing as es6 module creates error

Created on 2 Oct 2020  路  12Comments  路  Source: brianc/node-postgres

importing as es6 module creates following error;
Cannot find module 'pg-native'
to see this error just import in a module. ( import pg from 'pg'; )

I made a stack trace in pg module. It seems that internal esm loader is setting native property, which is forcing module to load 'pg-native'.

trace is as follows;
at PG.get ( {{appPath}} /node_modules/pg/lib/index.js:36:15)
at ModuleWrap. (internal/modules/esm/translators.js:165:24)
at ModuleJob.run (internal/modules/esm/module_job.js:146:23)
at async Loader.import (internal/modules/esm/loader.js:165:24)
at async Object.loadESM (internal/process/esm_loader.js:68:5)

Most helpful comment

Should not load module IMHO.

I agree with you. bad api design from a long forgotten age of the wild west of node.js. I'll try to remove it in [email protected]

All 12 comments

I noticed this, as well.

https://github.com/nodejs/node/blob/v14.x/lib/internal/modules/esm/translators.js#L162-L166

That seems to indicate that part of node's esm translation is reading all of the exported values from the pg module.

https://github.com/brianc/node-postgres/blob/master/packages/pg/lib/index.js#L32-L53

That shows that whenever pg.native is read, it triggers an import which, if pg-native is not installed, throws that error.

I'm not sure what a solution would be, but I wanted to offer what I found.

Is this property really needed ? if I need to use native driver I can simply;
import pg from 'pg-native';
if not, I can;
import pg from 'pg';
why would any body need to switch between implementations during a running program ? There must be some reason, but I don't get it. If there is a need for using different drivers, this canbe done on Database Access Layer. Like using different drivers in Knex etc.

I am also having the same issue together with webpack.

TypeError: Context creation failed: Native is not a constructor"
1: "    at new module.exports (webpack-internal:///./node_modules/pg/lib/native/client.js:20:17)"
2: "    at BoundPool.newClient (webpack-internal:///./node_modules/pg-pool/index.js:201:20)"
3: "    at BoundPool.connect (webpack-internal:///./node_modules/pg-pool/index.js:195:10)"
4: "    at eval (webpack-internal:///./node_modules/typeorm/driver/postgres/PostgresDriver.js:997:30)"
5: "    at new Promise (<anonymous>)"
6: "    at PostgresDriver.eval (webpack-internal:///./node_modules/typeorm/driver/postgres/PostgresDriver.js:996:39)"
7: "    at step (webpack-internal:///./node_modules/tslib/tslib.es6.js:124:23)"
8: "    at Object.eval [as next] (webpack-internal:///./node_modules/tslib/tslib.es6.js:105:53)"
9: "    at eval (webpack-internal:///./node_modules/tslib/tslib.es6.js:98:71)"
10: "    at new Promise (<anonymous>)"

There must be some reason, but I don't get it.

backwards compatibility with older versions of pg. Node postgres has been around quite a bit longer than webpack or babel...some of the API designs are crufty now but have remained because the cost to change them is large...with over a million installs a month any breaking changes must be weighed very carefully. I will consider removing this property in [email protected] but I'm not sure when that will be released. I agree this property isn't super useful and is causing problems while not helping out anything (other than maintaining backwards compatiblity).

if I need to use native driver I can simply;
import pg from 'pg-native';

technically you would do import pg from 'pg/native' pg-native is a sub-package of pg that doesn't have the same API as the js client.

OK, I get it, we must live with this 'native' property for now. But it is outputting errors on a simple import.
I guess it is trying to load module on reading the property. Just reading the property should not change state. Should not load module IMHO.

Should not load module IMHO.

I agree with you. bad api design from a long forgotten age of the wild west of node.js. I'll try to remove it in [email protected]

@lassesteffen I had a similar problem that I described in the issue #2349. This issue I linked is pg version 8.3.3. In version 8.4.0 the error changed from this.Client is not a constructor to Native is not a constructor.

 Unable to connect to the database (empresa_1). Retrying (2)... -> (TypeError: Native is not a constructor
    at new module.exports (G:\ERP 2.0 - Web\ibs-auth\dist\apps\backend\main.js:378360:17)
    at BoundPool.newClient (G:\ERP 2.0 - Web\ibs-auth\dist\apps\backend\main.js:378131:20)
    at BoundPool.connect (G:\ERP 2.0 - Web\ibs-auth\dist\apps\backend\main.js:378125:10)
    at G:\ERP 2.0 - Web\ibs-auth\dist\apps\backend\main.js:63581:30
    at new Promise (<anonymous>)
    at PostgresDriver.<anonymous> (G:\ERP 2.0 - Web\ibs-auth\dist\apps\backend\main.js:63580:39)
    at step (G:\ERP 2.0 - Web\ibs-auth\dist\apps\backend\main.js:5466:23)
    at Object.next (G:\ERP 2.0 - Web\ibs-auth\dist\apps\backend\main.js:5447:53)
    at G:\ERP 2.0 - Web\ibs-auth\dist\apps\backend\main.js:5440:71
    at new Promise (<anonymous>)
    at Module.__awaiter (G:\ERP 2.0 - Web\ibs-auth\dist\apps\backend\main.js:5436:12)
    at PostgresDriver.createPool (G:\ERP 2.0 - Web\ibs-auth\dist\apps\backend\main.js:63558:24)
    at PostgresDriver.<anonymous> (G:\ERP 2.0 - Web\ibs-auth\dist\apps\backend\main.js:62828:51)
    at step (G:\ERP 2.0 - Web\ibs-auth\dist\apps\backend\main.js:5466:23)
    at Object.next (G:\ERP 2.0 - Web\ibs-auth\dist\apps\backend\main.js:5447:53)
    at G:\ERP 2.0 - Web\ibs-auth\dist\apps\backend\main.js:5440:71)

Looking at the webpack version 4.0 documentation, CJS modules (as './native'seems to me) need the defaultproperty to get the value of module.exports. Temporarily I'm using the solution I described in the issue #2349 until I find a better one.

Ran into this today. Can we just remove the console.error? Until v9 it would still attempt to import pg-native but at least it wouldn't be so noisy when it inevitably fails.

Edit: Made it easy in case you agree 鉃★笍 https://github.com/brianc/node-postgres/pull/2372

@jmcantrell Curious why the thumbs down, in general I don't think libraries should be logging to stdout/err unless given explicit permission to do so. For a program that relies on those channels it can be a real pain to avoid unwanted output.

@caseywebdev I would much rather know that the module was trying to require pg-native than not. In general, I agree with you, but the thumbs down was simply to say that I disagree with the suggestion to just remove it.

I would much rather know that the module was trying to require pg-native than not.

With this logic you'd have it also log Attempting to load pg-native, when certainly seems too noisy.

It's quite simple to recreate this logging functionality if that's really what's desired:

import pg from 'pg';

// If I'm expecting pg-native via `pg.native`...
if (!pg.native) console.error('Failed to load pg-native.');

Commenting here for anyone else that like me just updated an older project to Node 14 and enabled ES Modules at the same time and spent a good hour scratching their head with this error message and with database connections that are just hanging... This error message is just a red-herring, it doesn't actually cause any problems, and it's not the same bug.

Node 14 requires you to update to pg 8.x, see this ticket: #2338

Was this page helpful?
0 / 5 - 0 ratings

Related issues

gpanainte picture gpanainte  路  3Comments

chrisjensen picture chrisjensen  路  4Comments

gregallenvt picture gregallenvt  路  3Comments

ClueLessEggHead picture ClueLessEggHead  路  3Comments

ossdev07 picture ossdev07  路  3Comments