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

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

About this issue

  • Original URL
  • State: closed
  • Created 5 years ago
  • Reactions: 25
  • Comments: 15 (4 by maintainers)

Commits related to this issue

Most upvoted comments

@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 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 👍 I’d like us to start introducing webpackablility as one of the integration tests for a variety of our libraries.

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!