Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

When importing some modules with multiple entry points in package.json, the server version is selected instead of the browser version #2329

Closed
2 tasks done
thekevinbrown opened this issue Mar 2, 2021 · 4 comments

Comments

@thekevinbrown
Copy link

Describe the bug

When I do this:

import { OktaAuth } from '@okta/okta-auth-js';
const oktaAuthClient = new OktaAuth(oktaAuthOptions);

I get this:

node_cache.js:38 Uncaught TypeError: Class extends value undefined is not a constructor or null
    at Object.<anonymous> (node_cache.js:38)
    at Object.<anonymous> (node_cache.js:767)
    at node_cache.js:769
    at chunk.2VCUNPV2.js?v=a7fa62e4:4
    at Object.<anonymous> (index.js:13)
    at index.js:17
    at chunk.2VCUNPV2.js?v=a7fa62e4:4
    at serverStorage.js:14

serverStorage should only be used when running in Node.

Testing a bit further, it definitely looks like vite is resolving to the server module, not the browser module for this dependency. In their package.json file:

  "main": "cjs/server/index.js",
  "module": "lib/server/index.js",
  "browser": "dist/okta-auth-js.umd.js",
  "react-native": "lib/server/index.js",
  "types": "lib/browser/index.d.ts",

I can work around it like this:

vite.config.ts

resolve: {
  alias: [
    {
      find: "@okta/okta-auth-js",
      replacement: require.resolve("@okta/okta-auth-js/dist/okta-auth-js.umd.js"),
    },
  ],
},

Can I make vite use the browser entry point so I get the browser version of the library in a less hacky, more supported way?

Reproduction

https://github.com/thekevinbrown/vite-okta-reproduction

System Info

  • vite version: "^2.0.1"
  • Operating System: Mac OS Big Sur
  • Node version: v12.16.1
  • Package manager (npm/yarn/pnpm) and version: yarn 1.22.5
@rschristian
Copy link
Contributor

if (browserEntry) {
// check if the package also has a "module" field.
if (typeof data.module === 'string' && data.module !== browserEntry) {
// if both are present, we may have a problem: some package points both
// to ESM, with "module" targeting Node.js, while some packages points
// "module" to browser ESM and "browser" to UMD.
// the heuristics here is to actually read the browser entry when
// possible and check for hints of UMD. If it is UMD, prefer "module"
// instead; Otherwise, assume it's ESM and use it.

This seems to be a purposeful decision, though you'll need to wait for one of the core team members to comment on what to do here. Vite is an ES-focused tool, might be time to upgrade rather than still relying on UMD

@thekevinbrown
Copy link
Author

That's interesting indeed, thanks for that!

I'm thinking it'd be nice to be able to override that behaviour for specific modules (like this one, where I don't control how it gets packaged and can't force them to update, but it works fine as a UMD module with vite already).

If the alias is the best way to do that configuration, I'm fine with that, more just wanted to check that it's definitely the best way to be doing this.

@yyx990803
Copy link
Member

Vite tries its best to guess package authors intentions but due to how both module and browser fields have non-standardized semantics, fixing this case would break other packages. The only solution is to use an alias here.

Also, ask the package to add conditional exports fields.

@thekevinbrown
Copy link
Author

In case anyone finds this issue in regards to Okta specifically, the conversation with them about how to better structure their package.json is here: okta/okta-auth-js#641

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

3 participants