next-auth icon indicating copy to clipboard operation
next-auth copied to clipboard

@auth/express No "exports" main defined

Open luchillo17 opened this issue 1 year ago • 1 comments

Environment

System: OS: Linux 5.15 Ubuntu 22.04.3 LTS 22.04.3 LTS (Jammy Jellyfish) CPU: (32) x64 13th Gen Intel(R) Core(TM) i9-13900KF Memory: 10.74 GB / 15.53 GB Container: Yes Shell: 5.8.1 - /usr/bin/zsh Binaries: Node: 20.11.0 - ~/.nvm/versions/node/v20.11.0/bin/node Yarn: 1.22.19 - ~/.nvm/versions/node/v20.11.0/bin/yarn npm: 10.2.4 - ~/.nvm/versions/node/v20.11.0/bin/npm pnpm: 8.15.1 - ~/.nvm/versions/node/v20.11.0/bin/pnpm Browsers: Chrome: 120.0.6099.224 npmPackages: @auth/core: ^0.26.3 => 0.26.3 @auth/express: ^0.5.0 => 0.5.0 @auth/mongodb-adapter: ^2.2.1 => 2.3.3

Reproduction URL

https://github.com/luchillo17/job-assessment-projects/tree/repro-%40auth/express-issue

Describe the issue

In a new Nrwl Nx monorepo, with NodeJS 20.11.0 (the latest LTS at the moment) Installed latest @auth/express package, the error at import & run is this:

➜  job-assessment-projects git:(main) nx run insurance-policy-manager:serve

> nx run insurance-policy-manager:serve:development

Build option outputFileName not set for insurance-policy-manager. Using fallback value of dist/apps/insurance-policy-manager/main.js.

> nx run insurance-policy-manager:build

chunk (runtime: main) main.js (main) 2.48 KiB [entry] [rendered]
webpack compiled successfully (c93181d72b2934c0)

 ——————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————

 >  NX   Successfully ran target build for project insurance-policy-manager (1s)
 
Debugger listening on ws://localhost:9229/34f83655-fca4-4cf9-abf8-0f9037c3eb6b
For help, see: https://nodejs.org/en/docs/inspector

Error: No "exports" main defined in /home/luchillo17/Projects/job-assessment-projects/node_modules/@auth/express/package.json
    at exportsNotFound (node:internal/modules/esm/resolve:303:10)
    at packageExportsResolve (node:internal/modules/esm/resolve:593:13)
    at resolveExports (node:internal/modules/cjs/loader:591:36)
    at Function.Module._findPath (node:internal/modules/cjs/loader:668:31)
    at Function.Module._resolveFilename (node:internal/modules/cjs/loader:1130:27)
    at Function.Module._load (node:internal/modules/cjs/loader:985:27)
    at Function.Module._load (/home/luchillo17/Projects/job-assessment-projects/node_modules/.pnpm/@[email protected]_@[email protected]_@[email protected]_@[email protected][email protected][email protected]/node_modules/@nx/js/src/executors/node/node-with-require-overrides.js:18:31)
    at Module.require (node:internal/modules/cjs/loader:1235:19)
    at require (node:internal/modules/helpers:176:18)
    at Array.__webpack_modules__ (/home/luchillo17/Projects/job-assessment-projects/dist/apps/insurance-policy-manager/main.js:76:18)

How to reproduce

  1. Clone reproduction url project
  2. Install packages with pnpm, or a package manager of your choice (I also repro this with npm).
  3. Run the project with nx run insurance-policy-manager:serve if you have Nx installed globally, or pnpm exec nx run insurance-policy-manager:serve or equivalent in your package manager.

Expected behavior

Just like the NextAuth which I can run properly in a different project, it should import properly and the server should serve in port 3000.

luchillo17 avatar Feb 10 '24 18:02 luchillo17

After trying a lot of things in other issues, like updating Node and updating the TSConfig in multiple ways for the module and target properties, I couldn't get it to work, for reference here's the package.json of the installed library:

@auth/[email protected] package.json
{
  "name": "@auth/express",
  "description": "Authentication for Express.",
  "version": "0.5.0",
  "type": "module",
  "files": [
    "*.js",
    "*.d.ts*",
    "lib",
    "providers",
    "src"
  ],
  "exports": {
    ".": {
      "types": "./index.d.ts",
      "import": "./index.js"
    },
    "./providers": {
      "types": "./providers/index.d.ts"
    },
    "./adapters": {
      "types": "./adapters.d.ts"
    },
    "./providers/*": {
      "types": "./providers/*.d.ts",
      "import": "./providers/*.js"
    },
    "./package.json": "./package.json"
  },
  "publishConfig": {
    "access": "public"
  },
  "dependencies": {
    "@auth/core": "0.25.0"
  },
  "devDependencies": {
    "@auth/core": "experimental",
    "@types/express": "^4.17.17",
    "@types/supertest": "^2.0.12",
    "supertest": "^6.3.3"
  },
  "peerDependencies": {
    "express": "^4.18.2"
  },
  "keywords": [
    "Express",
    "Auth.js"
  ],
  "author": "Rexford Essilfie <[email protected]>",
  "contributors": [
    "Rexford Essilfie <[email protected]",
    "Lachie Hill <[email protected]>"
  ],
  "repository": "https://github.com/nextauthjs/next-auth",
  "license": "ISC",
  "scripts": {
    "build": "pnpm clean && pnpm providers && tsc",
    "clean": "rm -rf lib index.* src/lib/providers",
    "test": "vitest -c ../utils/vitest.config.ts",
    "providers": "node ../utils/scripts/providers"
  }
}

luchillo17 avatar Feb 10 '24 19:02 luchillo17

I am having the same issue. Hoping this isn't a dead end for me and a bunch of work I'll have to throw away.

elkay avatar Feb 19 '24 04:02 elkay

Ok, was able to fix the error. Not sure why everything was working fine without this until suddenly the @auth/express package was added, but after starting a new project and not seeing the problem I was able to compare and fix my actual project by adding this to package.json:

"type": "module"

Hope this helps anyone else that may have the same problem with this particular package.

elkay avatar Feb 19 '24 06:02 elkay

@elkay You mean you changed the dependency package.json or your projects one? I was in the middle of an interview test so I had no luxury time to try more stuff to fix my issue.

luchillo17 avatar Feb 19 '24 06:02 luchillo17

The project one. Didn't have to change anything else, it just started working after that.

elkay avatar Feb 19 '24 15:02 elkay

Well that leaves me without much of a solution given I'm using an Nx monorepo, it would probably affect all my apps no?

luchillo17 avatar Feb 19 '24 16:02 luchillo17

I'm getting the same error too. Still no solution found?

tahayeslbg avatar Feb 20 '24 22:02 tahayeslbg

I got an idea specifically for Nx monorepos, turns out the build process is different if you generate a new app with node+express preset, than if you use the @nx/express application generator, specifically the former uses ESBuild while the latter uses Webpack.

I haven't tested this but I think the setup is way easier to move into ESM if we use the ESBuild setup, at the very least I could add the "type": "module" property in package.json & fix surfacing issues way easier in a new project, I haven't tested adding @auth/express yet though.

luchillo17 avatar Feb 21 '24 05:02 luchillo17

Facing same issue trying to use nextjs + expressjs

vanta240i avatar Feb 21 '24 06:02 vanta240i

@m1daz Wait what? why are you using Next and Express together? you usually pick 1 or the other since you can also do APIs in Next, do you mean 2 different projects? in Next you use next-auth (afaik the migration to @auth is still not done so @auth/next or so doesn't yet exist, and you need the beta branch for the app router).

https://authjs.dev/getting-started/introduction#about-authjs This has a link for the Next example app that then links to NextAuth.js. https://authjs.dev/reference/nextjs This is the latest docs for next-auth inside authjs.dev

luchillo17 avatar Feb 21 '24 06:02 luchillo17

@m1daz Wait what? why are you using Next and Express together? you usually pick 1 or the other since you can also do APIs in Next, do you mean 2 different projects? afaik in Next you use next-auth (afaik the migration to @auth is still not done so @auth/next or so doesn't yet exist, and you need the beta branch for the app router).

https://authjs.dev/getting-started/introduction#about-authjs This has a link for Next example app that then links to NextAuth.js. https://authjs.dev/reference/nextjs This is the latest docs for next-auth inside authjs.dev

Originally I did that because I wanted a non-serverless backend (I self-host) on top of nextjs. But now I thought about what my application really would entail (data processing & calculation) and I think maybe going serverless would be better.

vanta240i avatar Feb 21 '24 06:02 vanta240i

Ok so as far as I understand CommonJS modules cannot import ESM, but ESM can import CommonJS, which is why adding "type": "module" which turns your non-extension defined modules (ts and js) into ESM, which then can properly import @auth/express.

TS has an extensive documentation page about modules and explains the history, issues, and solutions around CommonJS, ESM, and how TS handles both. https://www.typescriptlang.org/docs/handbook/2/modules.html

I'm not sure if the @auth/express is true ESM or coincidentally the solution matches the ESM configuration. Still, the bottom line to fix this is to add "type": "module" to your package.json and fix any build issues that come with transforming your codebase to ESM.

luchillo17 avatar Feb 21 '24 06:02 luchillo17

To clarify, what I put above is a workaround, not a proper fix, I see @auth/express has an exports field so I would guess it's following the guidelines for modern libraries to compile to multiple targets, but that it's misconfigured and this issue happens, not really sure...

luchillo17 avatar Feb 21 '24 09:02 luchillo17

Having the same issue with @auth/mongodb-adapter. I know this was mentioned in another issue, but it's just not accurate. Everything was working fine on the old adapter. I believe it was next-auth/mongodb-adapter?

apeck14 avatar Feb 28 '24 16:02 apeck14

I am also experiencing this issue for @auth/drizzle-adapter, setting "type":"module" in package.json is, as mentioned, not an ideal fix as it can cause issues throughout the rest of the app. Has anyone since been able to fix this error by any other means?

FlynnHillier avatar Mar 25 '24 09:03 FlynnHillier

@balazsorban44, can you please advise ?

Oddadmix avatar Apr 14 '24 03:04 Oddadmix

anyone found a solution to this ?

Edit by maintainer bot: Comment was automatically minimized because it was considered unhelpful. (If you think this was by mistake, let us know). Please only comment if it adds context to the issue. If you want to express that you have the same problem, use the upvote 👍 on the issue description or subscribe to the issue for updates. Thanks!

CodeZak avatar Apr 26 '24 15:04 CodeZak

All @auth/* packages are ESM-only. We realize this may be a bit bigger of an issue with the express package as compared to the other (browser-only) ones.

To fix it, (1) you can of course write your node project with ESM (by adding "type": "module") to your root package.json, or (2) use node@22+ which added support for require(esm) packages (source).

Additionally, these recommendations I haven't personally tried but seen floating around, you could try using the esm package and/or renaming the file in which yuo import @auth/express to .mjs (if you don't have "type": "module" in your package.json).

For more info on esm/cjs in node: https://blog.logrocket.com/how-to-use-ecmascript-modules-with-node-js/

ndom91 avatar Apr 28 '24 10:04 ndom91

I have the same issue and found none of the mentioned workarounds working.

It's an ESM-only project that's running on CF Workers, but my dev server fails to import anything from @auth/core on startup.

 ERROR  No "exports" main defined in node_modules/@auth/core/package.json                   
                                                           
  at exportsNotFound (node:internal/modules/esm/resolve:294:10)
  at packageExportsResolve (node:internal/modules/esm/resolve:584:13)

Strangely if I add the imports to the project while the dev server is running, it works fine.

The only possible way I found to get it working if I modify the the exports field in node_modules/@auth/core/package.json Adding a default option for each exported entry solves the problem.

"exports": {
    ".": {
      "types": "./index.d.ts",
      "import": "./index.js",
      "default": "./index.js"
    },
    "./adapters": {
      "types": "./adapters.d.ts"
    },
    "./errors": {
      "types": "./errors.d.ts",
      "import": "./errors.js",
      "default": "./errors.js"
    },
    "./jwt": {
      "types": "./jwt.d.ts",
      "import": "./jwt.js",
      "default": "./jwt.js"
    },
    "./providers": {
      "types": "./providers/index.d.ts"
    },
    "./providers/*": {
      "types": "./providers/*.d.ts",
      "import": "./providers/*.js",
      "default": "./providers/*.js"
    },
    "./types": {
      "types": "./types.d.ts"
    }
  },

zsilbi avatar May 01 '24 08:05 zsilbi

I have the same issue and found none of the mentioned workarounds working.

It's an ESM-only project that's running on CF Workers, but my dev server fails to import anything from @auth/core on startup.

 ERROR  No "exports" main defined in node_modules/@auth/core/package.json                   
                                                           
  at exportsNotFound (node:internal/modules/esm/resolve:294:10)
  at packageExportsResolve (node:internal/modules/esm/resolve:584:13)

Strangely if I add the imports to the project while the dev server is running, it works fine.

The only possible way I found to get it working if I modify the the exports field in node_modules/@auth/core/package.json Adding a default option for each exported entry solves the problem.

"exports": {
    ".": {
      "types": "./index.d.ts",
      "import": "./index.js",
      "default": "./index.js"
    },
    "./adapters": {
      "types": "./adapters.d.ts"
    },
    "./errors": {
      "types": "./errors.d.ts",
      "import": "./errors.js",
      "default": "./errors.js"
    },
    "./jwt": {
      "types": "./jwt.d.ts",
      "import": "./jwt.js",
      "default": "./jwt.js"
    },
    "./providers": {
      "types": "./providers/index.d.ts"
    },
    "./providers/*": {
      "types": "./providers/*.d.ts",
      "import": "./providers/*.js",
      "default": "./providers/*.js"
    },
    "./types": {
      "types": "./types.d.ts"
    }
  },

I'm currently using patchfiles to handle this and it works perfectly for me; only gripe is that I have to do it for all @auth/* packages in my workspace.

Would it be possible to add the "default" export key in all exports in the future? Apologies for the naivety, not sure if this isn't currently being done for a specific reason.

GeorgeIpsum avatar Jun 11 '24 18:06 GeorgeIpsum

@GeorgeIpsum @zsilbi thanks for sharing. I think this might be due to some tsconfig or similar setting of yours though because the default configuration does work, for example in our example app (https://express-auth-example.vercel.app)

Can you share your tsconfig.json or any other similar config?

ndom91 avatar Jun 13 '24 06:06 ndom91

Of course!

My tsconfig.json:

{
  "compilerOptions": {
    "rootDir": ".",
    "baseUrl": ".",
    "paths": {
      "~/*": [
        "./src/*"
      ]
    },
    "outDir": "./dist",
    "target": "es2022",
    "module": "ESNext",
    "lib": ["es2022", "DOM", "DOM.Iterable"],
    "moduleResolution": "Bundler",
    "moduleDetection": "force",
    "noUncheckedIndexedAccess": true,
    "resolveJsonModule": true,
    "allowArbitraryExtensions": true,
    "forceConsistentCasingInFileNames": true,
    "declaration": true,
    "declarationMap": true,
    "esModuleInterop": true,
    "incremental": false,
    "isolatedModules": true,
    "resolveJsonModule": true,
    "skipLibCheck": true,
    "strict": true
  },
  "include": [
    "src",
    "*.d.ts",
    "*.d.ts",
    "*.config.mjs"
  ],
  "exclude": [
    "node_modules",
    "dist",
    "turbo"
  ],
}

Currently running the project with tsx in dev (so it might just be an issue with how esbuild is resolving imports?), haven't actually tried building using tsc with this configuration.

I'm assuming either my "target" or "module" fields here are the problematic entries (haven't tried changing these yet); I have tried changed "moduleResolution" to "Node" to no avail. I'm honestly still very much a newbie when it comes to understanding how to configure tsconfigs; apologies if there's an obvious mistake here that would rectify the issue.

GeorgeIpsum avatar Jun 13 '24 12:06 GeorgeIpsum