brianc / node-postgres

PostgreSQL client for node.js.
https://node-postgres.com
MIT License
12.19k stars 1.22k forks source link

when using babel, pg-native is always required (and fails if not present) #838

Open nahuel opened 9 years ago

nahuel commented 9 years ago

I'm not sure if this is a Babel or a node-postgres bug, steps to reproduce:

export PATH=$PATH:/tmp/iojs-v3.0.0-linux-x64/bin/:./node_modules/.bin
mkdir t
cd t
npm install babel pg

# create a t.js file with this ES6 content:
import * as pg from "pg";
console.log(pg);

# now execute: 
babel t.js > t-es5.js
node t-es5.js 

Error: Cannot find module 'pg-native'
    at Function.Module._resolveFilename (module.js:338:15)
    at Function.Module._load (module.js:280:25)
    at Module.require (module.js:364:17)
    at require (module.js:380:17)
    at Object.<anonymous> (/tmp/o/node_modules/pg/lib/native/index.js:1:76)
    at Module._compile (module.js:456:26)
    at Object.Module._extensions..js (module.js:474:10)
    at Module.load (module.js:356:32)
    at Function.Module._load (module.js:312:12)
    at Module.require (module.js:364:17)

Babel generates the following code in t-es5.js:

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 _pg = require("pg");

var pg = _interopRequireWildcard(_pg);

console.log(pg);

The exception is happening in the _interopRequireWildcard(_pg) call. This doesn't happens with other libraries, so I'm not sure if a Babel or a node-postgres bug.

olegsmetanin commented 8 years ago

+1 using webpack + babel + typescript ERROR in ./~/pg/lib/native/index.js Module not found: Error: Cannot resolve module 'pg-native' in /Volumes/DATA/SOA/2015/github/typescript_babel_react_express_dev/node_modules/pg/lib/native @ ./~/pg/lib/native/index.js 1:13-33

olegsmetanin commented 8 years ago

comment this lines in node_modules/pg/lib/index.js if(typeof process.env.NODE_PG_FORCE_NATIVE != 'undefined') { //module.exports = new PG(require('./native')); } else { module.exports = new PG(Client);

//lazy require native module...the native module may not have installed // module.exports.defineGetter("native", function() { // delete module.exports.native; // module.exports.native = new PG(require('./native')); // return module.exports.native; // }); }

artem1 commented 8 years ago

pg define getter in module.exports https://github.com/brianc/node-postgres/blob/master/lib/index.js#L76

  //lazy require native module...the native module may not have installed
  module.exports.__defineGetter__("native", function() {
    delete module.exports.native;
    module.exports.native = new PG(require('./native'));
    return module.exports.native;
  });

when babel rewrite code, him not found __esModule property in module and make copy of module props to new hash. in copy process pg.native called unintentionally. has no idea, how to fix this

function _interopRequireWildcard(obj) { //obj is pg module
  if (obj && obj.__esModule) {  //<===== test to something
    return obj; 
  } else { 
    var newObj = {}; 
    if (obj != null) { 
      for (var key in obj) { 
        if (Object.prototype.hasOwnProperty.call(obj, key)) 
          newObj[key] = obj[key];  //<== call getter here
      } 
    } 
    newObj["default"] = obj; 
    return newObj; 
  } 
}
thaumant commented 8 years ago

This might help you:

import pg from 'pg'
jmont commented 8 years ago

Any progress with this issue?

langpavel commented 8 years ago

I'm not experiencing this issue. I also using import pg from 'pg'. This can be solution I think.

nybble73 commented 8 years ago

import pg from 'pg' does not work for me - I am seeing the pg-native error.

langpavel commented 8 years ago

@nybble73 What code generates babel for `import pg from 'pg'? Which versions?

This issue can be fixed only by wrapping pg.native getter to try/catch.

langpavel commented 8 years ago

@brianc Should I prepare pull request?

My suggestion is return null if require('pg-native') fail

Another option is return this itself and write once an error to stdout

brianc commented 8 years ago

sure thing - pull request always welcome!

On Wed, Feb 24, 2016 at 3:08 PM, Pavel Lang notifications@github.com wrote:

@brianc https://github.com/brianc Should I prepare pull request? My suggestion is return null if require('pg-native') fail

— Reply to this email directly or view it on GitHub https://github.com/brianc/node-postgres/issues/838#issuecomment-188453312 .

swarajgiri commented 7 years ago

Still facing the same issue on "pg": "^6.1.5".

catamphetamine commented 7 years ago

I'm too facing it, using Webpack and AWS Lambda. This comment workaround worked (just the alias/pg-native.js part): https://github.com/elastic-coders/serverless-webpack/issues/78#issuecomment-271336996

ughitsaaron commented 7 years ago

Still having this issue bundling with webpack. Installing pg-native fixes the issue.

craiggoldstone commented 7 years ago

I also couldn't bundle pg in my Typescript + Webpack2 + Lambda project until I installed pg-native and set the webpack config output: 'node'. Small example project: https://github.com/craigsnyders/serverless-typescript-starter

I'm also unclear if this is an issue with node-postgres or webpack. Normally webpack will resolve all dependant modules perfectly. For reference, here's the webpack error when I haven't got pg-native in my package.json

ERROR in ./~/pg/lib/native/index.js
Module not found: Error: Can't resolve 'pg-native' in '/Users/csnyders/workspace/serverless-typescript-starter/node_modules/pg/lib/native'
 @ ./~/pg/lib/native/index.js 9:13-33
 @ ./~/pg/lib/index.js
 @ ./src/hello.ts
 @ ./src/handler.ts
Kuchiriel commented 7 years ago

See this: https://github.com/elastic-coders/serverless-webpack/issues/78

jonaskello commented 6 years ago

I also get the same error with pg 7.4.3 using webpack and typescript.

 ModuleNotFoundError: Module not found: Error: Can't resolve 'pg-native' in '/xxx/node_modules/pg/lib/native'
adieuadieu commented 6 years ago

Another solution (if using webpack), is to add new webpack.IgnorePlugin(/^pg-native$/) to your webpack config's plugins array. E.g.

const webpackConfig = {
  ...
  resolve: { ... },
  plugins: [
    new webpack.IgnorePlugin(/^pg-native$/)
  ],
  output: { ... },
  ...
}
amit-dhara commented 5 years ago

@adieuadieu 's solution worked. need to make sure you have installed webpack and imported in config file. Also, give and comma ( , ) after "plugin [ ... ]" and before "output:"

npm install --save webpack

var webpack = require('webpack'); const webpackConfig = { ... resolve: { ... }, plugins: [ new webpack.IgnorePlugin(/^pg-native$/) ], output: { ... } ... }

marcoippolito commented 4 years ago

@brianc @amit-dhara @adieuadieu I'm experiencing the same problem. I installed

"pg": "^8.0.2",
"pg-hstore": "^2.3.3",
"sequelize": "^5.21.6",

npm@6.14.4 and Node: 12.15.0

this is the pg.js I'm using:

const { Pool } = require('pg');
const pool = new Pool();
module.exports = {
  query: (text, params, callback) => {
    return pool.query(text, params, callback);
  },
}

I also specified in webpack.config.js :

{
    "mode": "development",
    plugins: [
      new webpack.IgnorePlugin(/^pg-native$/, /^dns$)
    ],

When compiling:

npm run serve
 ERROR  Failed to compile with 2 errors                                         

These dependencies were not found:

* dns in ./node_modules/pg/lib/connection-parameters.js
* pg-native in ./node_modules/pg/lib/native/client.js

To install them, you can run: npm install --save dns pg-native

How to solve the problem?

Marco

GeorgeWL commented 4 years ago

This still seems to be an issue, so unsure why it was closed

charmander commented 4 years ago

@GeorgeWL The original issue was closed with a fix. If you’re seeing something new or something that appears to be the same, please include details.

GeorgeWL commented 4 years ago

Seeing the same, using this alongside webpack, webpack fails to correctly compile it when using TypeScript.

The workaround of adding pg-native to a webpack ignorePlugin still seems to fix it.

moltar commented 4 years ago

I think the original issue asks about babel, which seems to be still an issue. E.g. when using parcel, get the same errors:

🚨  /.../node_modules/pg/lib/native/client.js:11:21: Cannot resolve dependency 'pg-native'
antonycms commented 4 years ago

Nothing worked for me, so I created a manual fix myself

create a fix.js file at the root of the project:

const fs = require('fs');
const path = require('path');

const pgClientPath = path.resolve(__dirname, 'node_modules', 'pg', 'lib', 'native', 'client.js');

fs.readFile(pgClientPath, 'utf8', function(err, data) {
  if (err) {
    return console.log(err);
  }

  const result = data.replace("var Native = require('pg-native')", 'var Native = null');

  fs.writeFile(pgClientPath, result, 'utf8', function(err) {
    if (err) return console.log(err);
  });
});

to run the patch file whenever you update or install a new dependency, add it to the package.json file:

"scripts:": {
  "postinstall": "node fix.js"
}

If you are using sequelize, make the following configuration in the configuration part:

import * as pg from 'pg';  // import pg

const database = 'myDB';
const dialect = 'postgres';
const host = 'locahost';
const port = 5432;
const username = 'myUser';
const password = 'myPass';

export default {
  dialect,
  dialectModule: pg,
  username,
  password,
  database,
  host,
  port,

  define: {
    timestamps: true,
    underscored: true,
    underscoredAll: true,
  },
};
kickthedragon commented 4 years ago

@antonycms thanks so much! struggled with this issue and your solution works like a charm!

sdegroot commented 3 years ago

An alternative workaround is to create a local pg-native package and reference it from your package.json

{
  "name": "your-module",
  "private": true,
  "dependencies": {
    "pg": "^8.3.3",
    "pg-native": "file:./modules/pg-native",
  }
}

The index.js file in the pg-native folder only has to contain

module.exports = null;

and a basic package.json file like this:

{
  "name": "pg-native",
  "private": true,
  "main": "index.js"
}
GeorgeWL commented 3 years ago

is this actually fixed? or has it been closed due to workarounds?

jaylattice commented 3 years ago

npm install --save pg-native fixes this error, since pg specifies pg-native as an optional peer dependency.

GeorgeWL commented 3 years ago

npm install --save pg-native fixes this error, since pg specifies pg-native as an optional peer dependency.

that's not a fix, that's a workaround. keyword: optional

jaylattice commented 3 years ago

¯\(ツ)\/¯ anything that unblocks me is a fix.

dj-doMains commented 3 years ago

Just in case anyone is using serverless-bundle to use webpack with the serverless framework, here's the workaround:

custom:
  bundle:
    ignorePackages:
      - pg-native
brianc commented 3 years ago

The old api of using a getter to require the native bindings was not a good idea, but it's been around for ages and ages. Unfortunately it's a backwards compatiblity break to change it but one I'm happy to do - I've put this into the 9.0 milestone so it'll go out w/ our next major version release where we break backwards compatibility.

louisbuchbinder commented 3 years ago

Here is a workaround if you are using webpack

pg-native.js

module.exports = null;

webpack.config.js

   ...,
    resolve: {
      alias: {
        'pg-native': path.join(__dirname, 'pg-native'),
      },
    },
    ...,
zhangyuwu123 commented 3 years ago

nice it‘s worked for me thx @antonycms

edwinspire commented 2 years ago

@sdegroot Thank you, you have served me. https://github.com/edwinspire/pgapi-base/tree/main/src/server/class/pg-native

larshp commented 2 years ago

I added following in my webpack config to workaround the issue,

    new IgnorePlugin({
      resourceRegExp: /^pg-native$/,
      contextRegExp: /./,
    }),
merlindru commented 1 year ago

An alternative workaround is to create a local pg-native package and reference it from your package.json

{
  "name": "your-module",
  "private": true,
  "dependencies": {
    "pg": "^8.3.3",
    "pg-native": "file:./modules/pg-native",
  }
}

The index.js file in the pg-native folder only has to contain

module.exports = null;

and a basic package.json file like this:

{
  "name": "pg-native",
  "private": true,
  "main": "index.js"
}

Thank you!!! Easiest way to do it, no webpack required.