Asana / node-asana

Official node.js and browser JS client for the Asana API v1
MIT License
264 stars 74 forks source link

Module can't be built in `create-react-app` project because of missing polyfills in webpack >5 #255

Open slobak opened 2 years ago

slobak commented 2 years ago

I assume the compiled browser version of this library is still usable, but including this module in builds (e.g. for a Typescript project) is now not possible out-of-the-box because it requires polyfills that webpack v5 no longer supplies by default.

Steps to reproduce

  1. Create a new app that builds a browser bundle with webpack, e.g. create-react-app
  2. npm install asana into the project and add import "asana" from asana
  3. npm run build

Expected: project builds Actual: compilation errors due to missing dependencies which once were polyfilled, e.g.:

ERROR in ./node_modules/asana/lib/auth/oauth_util.js 4:10-24
Module not found: Error: Can't resolve 'url' in '/Users/greg/src/hive707-tasks-widget/node_modules/asana/lib/auth'

BREAKING CHANGE: webpack < 5 used to include polyfills for node.js core modules by default.
This is no longer the case. Verify if you need this module and configure a polyfill for it.

If you want to include a polyfill, you need to:
    - add a fallback 'resolve.fallback: { "url": require.resolve("url/") }'
    - install 'url'
If you don't want to include a polyfill, you can use an empty module like this:
    resolve.fallback: { "url": false }
 @ ./node_modules/asana/lib/auth/base_browser_flow.js 4:16-39
 @ ./node_modules/asana/lib/auth/index.js 1:0-56
 @ ./node_modules/asana/index.js 3:0-36
 @ ./src/App.tsx 11:0-26 158:23-42
 @ ./src/index.tsx 7:0-24 11:33-36

Discussion I don't actually know yet what the "right" fix is to this library to help make the developer experience better, but some ideas are:

  1. Fixing the code to not depend on node core libraries (does it need to? With its current feature set maybe yes .. e.g. one dependency is fs for readline as part of one of the Oauth flows)
  2. Provide some kind of version of the module that is browser-compatible (e.g. make a new asana-browser module) and omit features that need core node dependencies.
  3. Finding a way so the specific build of this module in a browser context doesn't include core node dependencies, perhaps with improved configuration.

More on the issue here:

There are various workarounds. The one I found most straightforward to hack through is to install the npm module react-app-rewired and follow the short instructions to inject new configuration into webpack. Here is my specific config-overrides.js file that specifies the specific polyfills to use:

module.exports = function override(config, env) {
  config.resolve = {
    ...config.resolve,
    fallback: {
      ...config.resolve.fallback,
      buffer: require.resolve("buffer/"),
      fs: false,
      stream: require.resolve("stream-browserify/"),
      url: require.resolve("url/"),
      util: require.resolve("util/"),
    },
  };
  return config;
};