Google-api-nodejs-client: Library failing to work in the browser due to fs.readFile

Created on 27 Jul 2019  路  15Comments  路  Source: googleapis/google-api-nodejs-client

I"m trying to use this library in the browser, which I think is supported, but the googleapis-common library uses the Node.js fs library (and readFile, in particular, here https://github.com/googleapis/nodejs-googleapis-common/blob/master/src/discovery.ts#L27) and this causes it not to work in the browser.

The beginning of the stack trace is as follows (rest in this gist):

TypeError: The "original" argument must be of type Function
promisify
node_modules/util/util.js:605
  602 | var kCustomPromisifiedSymbol = typeof Symbol !== 'undefined' ? Symbol('util.promisify.custom') : undefined;
  603 | 
  604 | exports.promisify = function promisify(original) {
> 605 |   if (typeof original !== 'function') throw new TypeError('The "original" argument must be of type Function');
  606 | 
  607 |   if (kCustomPromisifiedSymbol && original[kCustomPromisifiedSymbol]) {
  608 |     var fn = original[kCustomPromisifiedSymbol];
View compiled
./node_modules/googleapis-common/build/src/discovery.js
node_modules/googleapis-common/build/src/discovery.js:30
  27 | 
  28 | const endpoint_1 = require("./endpoint");
  29 | 
> 30 | const readFile = util.promisify(fs.readFile);
  31 | 
  32 | class Discovery {
  33 |   /**
View compiled
__webpack_require__
/Users/isaachodes/workspace/scheme/client/webpack/bootstrap:781
  778 | };
  779 | 
  780 | // Execute the module function
> 781 | modules[moduleId].call(module.exports, module, module.exports, hotCreateRequire(moduleId));
      | ^  782 | 
  783 | // Flag the module as loaded
  784 | module.l = true;
View compiled
fn
/Users/isaachodes/workspace/scheme/client/webpack/bootstrap:149
  146 |         );
  147 |         hotCurrentParents = [];
  148 |     }
> 149 |     return __webpack_require__(request);
      | ^  150 | };
  151 | var ObjectFactory = function ObjectFactory(name) {
  152 |     return {

Environment details

  • OS: Mac OSX 10.14
  • Node.js version: v6.9.0
  • npm version: v12.6.0
  • googleapis version: 41.0.1

Steps to reproduce

  1. import { google } from 'googleapis'; in an app being packaged for the browser
  2. console.log(google); somewhere
p2 bug web webpack

Most helpful comment

@ihodes does adding something like the following to your webpack.config.js do the trick:

module.exports = {
    resolve: {
        extensions: ['.js'],
        alias: {
            fs: path.resolve(__dirname, 'src/mock-fs.js')
        }
    }
};

where modck-fs.js is:

module.exports = {
  readFileSync () {}
}

All 15 comments

Is there a workaround for this?

@rinose Not without editing the library itself, or monkey patching, as far as I know.

@bcoe given #1740, should this issue have a "bug" label?

@ihodes we've fixed this issue in a few upstream libraries before, but it's a bit of a losing battle until we get slightly better integration tests in place.

Have labeled this as a bug, which I think is appropriate :+1: I'd like us to start introducing webpackablility as one of the integration tests for a variety of our libraries.

@bcoe would you recommend people do something different in the meantime because this could take a while to fix (and if so, what would you recommend?) or will this be fixed so soon that you'd recommend just waiting?

I'm stuck with this issue too. Any workaround till fix is stable?

Same here

@ihodes does adding something like the following to your webpack.config.js do the trick:

module.exports = {
    resolve: {
        extensions: ['.js'],
        alias: {
            fs: path.resolve(__dirname, 'src/mock-fs.js')
        }
    }
};

where modck-fs.js is:

module.exports = {
  readFileSync () {}
}

@bcoe This worked for me, except for one thing, it crashes on fs.readFile, not fs.readFileSync. I had to edit mock-fs.js to contain readFile instead of readFileSync and it all worked! Thank you!

Side note: I'm using customize-cra so I had to add it to my config-overrides.js like this:

...
addWebpackResolve({
    extensions: ['.js'],
    alias: {
      fs: path.resolve(__dirname, 'src/mock-fs.js')
    }
  }),
...

@ihodes does this approach work for you as well?

Apologies, I've moved my work to the backend for now, so don't have an easy way to test this, but would imagine it would as well. Thank you for finding a work-around, though!

I also experience this issue and I had to replace readFileSync with readFile but now I have different error:
./node_modules/google-auth-library/build/src/auth/googleauth.js
Module not found: Can't resolve 'fs' in '/node_modules/google-auth-library/build/src/auth'. Did anyone else encounter the same?

@abohomol one of our users wrote this blog post on the topic of webpacking our libraries:

https://blog.angularindepth.com/google-apis-with-angular-214fadb8fbc5

I think it's a good starting point for running googleapis in the browser.

readFile

Thanks! this work for me on Quasar Framework

in quasar.config.js add an alias;

const path = require('path')
// ...
cfg.resolve.alias = {
  ...cfg.resolve.alias, // This adds the existing alias
  fs: path.resolve(__dirname, 'src/mock-fs.js')
}

The mock-fs.js;

module.exports = {
  readFile () {}
}

@abohomol same issue

@abohomol same issue

Check my solution!

Was this page helpful?
0 / 5 - 0 ratings