auth0 / lock

Auth0's signin solution
https://auth0.com/docs/libraries/lock
Other
1.13k stars 556 forks source link

BREAKING CHANGE: webpack < 5 used to include polyfills for node.js core modules by default. #1999

Closed miki995 closed 3 years ago

miki995 commented 3 years ago

Describe the problem

After upgrading angular to version 12, which uses webpack 5 I got the following error,


./node_modules/auth0-lock/lib/i18n.js:24:12-27 - Error: Module not found: Error: Can't resolve 'util' in 'C:\Users\mikim\WebstormProjects\reynapro-plugin\
node_modules\auth0-lock\lib'

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: { "util": require.resolve("util/") }'
        - install 'util'
If you don't want to include a polyfill, you can use an empty module like this:
        resolve.fallback: { "util": false }

What was the expected behavior?

The angular application should compile, but it does not because of auth0-lock dependencies...

Reproduction

Go to this repo: https://github.com/miki995/test-auth0-lock-angular12

This is brand new project with angular 12, just run npm run start command, this will appear:

image

Where possible, please include the sample app:

Environment

frederikprijck commented 3 years ago

Hey,

Thanks for reporting.

I believe the linked repository is not using Lock, did you forget to commit some changes?

Important to note here is that for Angular, we recommend using our Angular SDK: https://github.com/auth0/auth0-angular.

That said, if you use any dependency with Webpack that relies on native Node things, you could specify the polyfills yourself, as mentioned by the error message.

However, we can have a look and see if there is anything we can do from the library side, @stevehobbsdev any thoughts? If we would decide to keep it as is, I guess we can improve documentation around Webpack 5 (or general recommendation about the native node things it relies on).

miki995 commented 3 years ago

Hi, @frederikprijck , yes, I forgot to commit.

Regarding the library for angular, I wanted to use it but couldn't find some methods that are provided in auth0-js like checkSession?

Can you help me a bit? I found this: https://community.auth0.com/t/equivalent-functionality-to-webauth-checksession-from-auth0-js-in-auth0-angular-for-sso/60980

frederikprijck commented 3 years ago

Hey @miki995 ,

Could you elaborate on why you need this? Our Angular SDK uses CheckSession internally so you shouldn't have to worry about it, but I am always interested to hear your use case why you want to explicitly call this.

I tried the sample you linked, but I do not get the same error. Running npm run start works fine, but I get run-time errors that are resolved when I use the following custom webpack config:

const webpack = require('webpack');

module.exports = {
  node: {
    global: true
  },
  plugins: [
    new webpack.ProvidePlugin({
      process: 'process/browser',
    }),
  ]
};

Be sure to also use npm install process.

How to use this custom webpack config is explained here: https://www.digitalocean.com/community/tutorials/angular-custom-webpack-config

Once I do this, I can see there are other issues with the sample application that are not related to any of our SDKs

Any chance you can update the sample app to reflect the error you mentioned ? I also believe the path added in the tsconfig is not something u need.

Thanks.

stevehobbsdev commented 3 years ago

@miki995 I've responded to the community post - thanks for pointing it out!

If you'd actually prefer to integrate auth0-angular which uses the Universal Login experience (which is our hosted login page), we'd be happy to help answer any questions over at the auth0-angular repo. The key difference is that it uses our hosted login page, whereas this repository requires you to host the login page within your own app. Just wanted to make you aware of the differences.

@frederikprijck has provided some things to try in his previous post - please let us know whether you're able to progress and whether we can go ahead and close the issue.

miki995 commented 3 years ago

@stevehobbsdev Yes, exactly, we are hosting it ourselves. I will have some delay in checking it because it is not priority for us at the moment, but for sure I will get back. And I think we can use auth0-angular...

UPDATE: I removed auth0-lock, auth0-js and using only auth0-angular.

It was really not a challenge to remove it at the end.

billyjov commented 3 years ago

@miki995 Do you have an example using no redirection with auth0-angular and newest Angular v12 ?

dpraul commented 3 years ago

Hello! I know the author closed this issue since they have diverted the issue, but the problem is still present in auth-lock.

The issue is that in webpack > 5, webpack will no longer provide polyfills for node.js core modules to the webpack build.

As far as I can tell, the issue lies in auth-lock with the following two imports: https://github.com/auth0/lock/blob/d139cf01c8234b07caf265e051f39d3eab08f7ed/src/i18n.js#L3 https://github.com/auth0/lock/blob/a30b27eee69654ecb30a023a15dc4c9dd5914c2a/src/ui/input/password/password_strength.jsx#L4

util is a part of the node.js core library, so webpack 5 won't provide a polyfill for it.

Since auth0-lock only uses the format API from the util module, could it use an alternative, or inline a polyfill? The source code from browserify (which is, I believe, what webpack < 5 provided as a polyfill), is fairly small

frederikprijck commented 3 years ago

Hey @dpraul,

Even tho I agree we can add the polyfill to lock, this would change things for webpack < 5 users. I also believe Webpack5 dropping the polyfills is more a tooling thing as opposed to it requiring a code change in the libs being affected by that.

If you are using webpack 5 and you need the polyfills behavior for some (or all) node modules as it used to be the case < 5, you can update your webpack config to restore that behavior on a per-module base, see https://webpack.js.org/configuration/resolve/#resolvefallback

Basically, for utils you want:

module.exports = {
  resolve: {
    fallback: {
      util: require.resolve('util'),
    },
  },
};

Doing so would restore the existing behavior for webpack 5 users, without impacting webpack < 5 users or without adding code to the SDK because one of the existing bundlers has decided to drop auto polyfilling.

As you can see in the docs, restoring these polyfills in Webpack 5 is exactly what resolve.fallback is for.

On top of that, I think it is important to keep in mind webpack is not the only bundler out there and people can be using this with other bundlers. Leaving these things to the bundler ensures it doesn't conflict.

Happy to discuss further if you believe otherwise.

dpraul commented 3 years ago

Hi @frederikprijck - thanks for taking the time to respond, I really appreciate it. :)

My personal take on this is the opposite of yours - leaving this up to bundlers to handle creates inconsistencies, especially for polyfilling something like the node core modules, which don't necessarily have a consistent API. In fact, the polyfill that Webpack 4 previously supplied for util.format specifically mentions that it is not consistent with the core library. If Lock were to instead supply a format method (which wouldn't have to be a polyfill, or even the same method as in the Node core module), you could ensure consistency across any bundler.

That said, an issue more relevant to this conversation is something you pointed at in a previous comment, which is that the Angular CLI doesn't provide any out-of-the-box support for customizing the Webpack config, so any Lock user upgrading to Angular 12 will have to add a decent amount of dependencies + customization to their build pipeline to support the upgrade (something we're in the process of removing as it complicates upgrades and new employee onboarding). I suppose that the @auth0/auth0-angular package exists to solve this particular issue, but I'm sure I'm not the only one who cannot migrate off Lock just yet.

That's all just my 2c - you'll obviously know what's best for Lock, just figured I'd contribute my opinion :)


Regardless, if you're like me and already have custom webpack integrated into your Angular build pipeline, here are the full changes I needed to make to get Lock working with Angular 12:

  1. Install util and process: yarn add util process or npm install util process (these are the polyfills webpack 4 previously provided)
  2. Add the following to your webpack.config.js:
    const { ProvidePlugin } = require('webpack');
    module.exports = {
      resolve: {
        fallback: {
          util: require.resolve('util'),
        },
      },
      plugins: [
        new ProvidePlugin({ process: 'process/browser' }), // util requires this internally
      ],
    };
frederikprijck commented 3 years ago

Hi @dpraul

My personal take on this is the opposite of yours - leaving this up to bundlers to handle creates inconsistencies, especially for polyfilling something like the node core modules, which don't necessarily have a consistent API

It has been working succesfuly like that for a very long time. Now that Webpack 5 decided to make some internal changes, it stopped working. However, for that reason they provide a way for you to still make these kind of things work just as before.

I suppose that the @auth0/auth0-angular package exists to solve this particular issue, but I'm sure I'm not the only one who cannot migrate off Lock just yet.

I dont think the Angular SDK exists for solving any of that, but yes, that SDK is the one we generally recommend for Angular applications. I understand you cant migrate off Lock, but I don't think you need to. With only a few changes, as mentioned above, everything should work just as before, without any changes to the SDK.

That said, an issue more relevant to this conversation is something you pointed at in a previous comment, which is that the Angular CLI doesn't provide any out-of-the-box support for customizing the Webpack config, so any Lock user upgrading to Angular 12 will have to add a decent amount of dependencies + customization to their build pipeline to support the upgrade (something we're in the process of removing as it complicates upgrades and new employee onboarding).

I am not sure we are talking about the same. I am referring to using @angular-builders/custom-webpack, see: https://www.npmjs.com/package/@angular-builders/custom-webpack It is a single dependency, and a few small changes inside the angular.json file. It makes further upgrading of Angular as easy as without using it. What you do want to avoid, is take control over the entire build process by using an entire custom webpack config. But @angular-builders/custom-webpack allows you to stick to the Angular CLI while being able to add any kind of extra configuration for webpack.

thduttonuk commented 3 years ago

We are getting this upgrading to Angular 12. I feel auth0 need to fix this without the need for @angular-builders/custom-webpack

stevehobbsdev commented 3 years ago

@thduttonuk We will look at addressing it in the future if this issue becomes more widespread. In the meantime, the short steps mentioned above should get you moving.

zimejin commented 3 years ago

This is an issue for us as well.

cscleison commented 3 years ago

It has been working succesfuly like that for a very long time. Now that Webpack 5 decided to make some internal changes, it stopped working. However, for that reason they provide a way for you to still make these kind of things work just as before.

@frederikprijck Not a very solid argument, isn't it? From what I read, webpack provided polyfills for compatibility reasons only. If the library is meant to run in node, then I agree you can depend on "node things". If the lib is meant to run in the browser, it's the lib's responsibility to declare it's own dependencies - and not expect node core modules to be present at runtime, right?

frederikprijck commented 3 years ago

We will look into what we can do to avoid the changes in Webpack 5 that are causing the mentioned problems.

KostaD02 commented 3 years ago

Hi guys , whole day trying to fix , any solution ?

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:

stevehobbsdev commented 3 years ago

Hi all, I've raised #2030 which should fix this - we chose to just inline the function. I've tested it against the repo app from the original post and it now appears to work fine, but please test against your own case if you get the chance.

hanjeahwan commented 3 years ago

Hi, when this fix will get release ? I see latest version ^11.30.4 tag source code same using required util instead of inline function

stevehobbsdev commented 3 years ago

Hoping to get a release out today, I was just waiting for a couple of bits to drop in 👍