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

Error: No valid exports main found for 'node_modules\nanoid' #206

Closed
dstrekelj opened this issue Apr 9, 2020 · 15 comments
Closed

Error: No valid exports main found for 'node_modules\nanoid' #206

dstrekelj opened this issue Apr 9, 2020 · 15 comments

Comments

@dstrekelj
Copy link

dstrekelj commented Apr 9, 2020

Hello!

I was trying out nanoid in a TypeScript project and came across an issue when running the code through ts-node-dev.

The setup

EDIT: Forgot to include I have Node 13.3.0 installed.

The issue occurs with nanoid version 3.0.2 when running ts-node-dev.

Compilation with tsc passes without error.

I was able to reproduce the issue with the following setup:

package.json

{
  "private": true,
  "name": "01-todo-list",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "build": "tsc",
    "start": "ts-node-dev -r tsconfig-paths/register --respawn --no-notify --transpileOnly ./src/index.ts"
  },
  "keywords": [],
  "author": "dstrekelj <[email protected]>",
  "license": "IDGAF",
  "devDependencies": {
    "@types/node": "^13.11.1",
    "ts-node-dev": "^1.0.0-pre.44",
    "tsconfig-paths": "^3.9.0",
    "typescript": "^3.8.3"
  },
  "dependencies": {
    "nanoid": "^3.0.2"
  }
}

tsconfig.json

{
  "compilerOptions": {
    "target": "es2015",
    "module": "commonjs",
    "declaration": true,
    "declarationMap": true,
    "sourceMap": true,
    "outDir": "./build",
    "strict": true,
    "moduleResolution": "node",
    "baseUrl": "./src",
    "paths": {
      "@app/*": ["*"]
    }
  },
  "exclude": ["node_modules", "build", "__tests__"]
}

src/index.ts

import { nanoid } from "nanoid";

console.log(nanoid());

Afterwards:

  1. npm install
  2. npm run start

The issue

Here is the complete transcript:

Using ts-node version 8.8.2, typescript version 3.8.3
Error: No valid exports main found for 'F:\projects\ts\challenges\reproducible\node_modules\nanoid'
    at resolveExportsTarget (internal/modules/cjs/loader.js:618:9)
    at applyExports (internal/modules/cjs/loader.js:499:14)
    at resolveExports (internal/modules/cjs/loader.js:548:12)
    at Function.Module._findPath (internal/modules/cjs/loader.js:650:22)
    at Function.Module._resolveFilename (internal/modules/cjs/loader.js:948:27)
    at Function.Module._resolveFilename (F:\projects\ts\challenges\reproducible\node_modules\tsconfig-paths\lib\register.js:75:40)
    at Function.Module._load (internal/modules/cjs/loader.js:854:27)
    at Module.require (internal/modules/cjs/loader.js:1023:19)
    at require (internal/modules/cjs/helpers.js:72:18)
    at Object.<anonymous> (F:\projects\ts\challenges\reproducible\src\index.ts:1:1)
[ERROR] 18:39:55 Error: No valid exports main found for 'F:\projects\ts\challenges\reproducible\node_modules\nanoid'

Other information

After downgrading to nanoid 2.1.11 everything worked fine, though I had to install @types/nanoid to get completion.

Older 3.x versions throw the same error.

I'm thinking ts-node-dev is at fault or something in my configuration, but seeing as how version 3.x is still fresh I figured it's worth to create an issue just to be safe.

Might be related to #205?

@ai
Copy link
Owner

ai commented Apr 9, 2020

The ideal example of the issue 👍

Honestly, I am overworked right now. I will be able to look only a few days after. Can you look into the ts-node-dev source code?

#205 happens because CRA does not support .cjs file ext, which we use for CommonJS (and CRA uses CJS during jest run). It could potentially be related (but TS should always use ESM files). Another way to find the problem is starting to remove options one by one. I am especially curious about "module": "commonjs".

@ai
Copy link
Owner

ai commented Apr 9, 2020

Until we will discover the problem, I added ts-node-dev notice to known issues of 3.0 migration guide
https://github.com/ai/nanoid/releases/tag/3.0.0

@dstrekelj
Copy link
Author

@ai No worries, I'll look into it tomorrow afternoon at the latest :) Thanks for the quick reply!

@dstrekelj
Copy link
Author

Alright, it's been a while since I last did some good old fashioned detective work. Couldn't resist but to give it a go now.

The first thing I tried was changing the "module": "commonjs" configuration as suggested. No success. The error messages changed to reflect the syntactical requirements set forth by the selected module resolution strategy. Other than that, there was nothing out of the ordinary to report.

Next up, I looked through the ts-node-dev source code. I added the --debug flag to the npm run start script to get some additional information and started off by looking through ts-node-dev/lib/wrap.js. At line 61 is where the trail goes cold as it jumps to another process.

The ts-node-dev library in itself is nothing more than a middleman. As described in the library's docs it's a "tweaked version of node-dev that uses ts-node under the hood". I ran tsc -v and ts-node -vv to compare TypeScript versions and both seem to use use 3.8.3, so it looks like it isn't that. Though it is odd that I run my code successfully through tsc, but not through ts-node.

Back on track with our error message, I searched through other issues on GitHub looking to pinpoint the line of code where the error message is constructed. This led me to find this issue:

home-assistant/home-assistant-js-websocket#113

... where the comment about using the new exports field and the comment about removing the exports field fixing a bug similar to this one grabbed my attention.

So I looked into how nanoid exports modules and noticed that package.json contains the "exports": { ... } property. I deleted the property (as per the aforementioned comment) and - no error! The script ran without any issue.

I'm not familiar with the exports property and seeing how that issue talked about supporting Node versions, I went to look for how exactly the thing works and how well it is supported. This led me to a StackOverflow post about TypeScript not supporting exports, which in turn led me to this issue:

microsoft/TypeScript#33079

I haven't had a change to go through it in detail yet and try fixes, but at least it's something.

@ai
Copy link
Owner

ai commented Apr 9, 2020

Wow. So big research 😍

I will review it tomorrow, because I am going to sleep soon. Just want to say that you are great.

@dstrekelj
Copy link
Author

Thanks! :D

Here's a small update regarding ts-node and ts-node-dev.

I tried running ts-node directly using ts-node-dev --project tsconfig.json src/index.ts (and without the --project flag in case the config is the problem). The error persists.

npm list shows the following version information:

Both are set to the latest versions available through npm at the time of writing.

So far it looks to be a ts-node issue. Are we running into this by chance?

TypeStrong/ts-node#935

@ai
Copy link
Owner

ai commented Apr 10, 2020

I added ts-node test to dual-publish and everything works.

We use this dual-publish to create a dual ESM/CJS package for Nano ID.

But I found that you should use CommonJS in your package. So you must have:

const { lib } = require('lib')

Will moving to CommonJS solved you problem with ts-node-dev?

@dstrekelj
Copy link
Author

I set up a project reflecting the fixture you provided. I still had the error.

Then I realised that my test results aren't valid unless I ran the tests in the same Node environment you use.

Assuming the latest version of Node is used to run the tests, I updated from 13.3.0 to 13.12.0.

I tried...

import { nanoid } from "nanoid";

... and...

const { nanoid } = require("nanoid");

After updating to Node 13.12.0 both worked without a problem!

I will try and play around with some additional samples to see if anything else breaks. As it stands now this seemed to be caused by my older version of Node acting up.

Thank you very much for your patience and expertise in figuring this out!

@ai
Copy link
Owner

ai commented Apr 10, 2020

Wow, Great!

@cansin
Copy link
Contributor

cansin commented May 2, 2020

I think although package.json specifies index.cjs for require export we are somehow still getting index.js instead. Manually copying over index.cjs and require'ing it fixes the problem for me on [email protected]. Though, that is obviously less than ideal. Tried require("nanoid/index.cjs") but `index.cjs is not exposed. I wonder if there is something wrong with the package configuration of this library?

@ai
Copy link
Owner

ai commented May 2, 2020

@cansin creates a separate issue with all details of your project. What builder do you use?

@TrySound
Copy link

TrySound commented May 2, 2020

@cansin See the latest node 13 version is v13.14.0. Your version is very old.
https://nodejs.org/docs/latest-v13.x/api/

@cansin
Copy link
Contributor

cansin commented May 2, 2020

Wow, you guys are quick 😊 Ok, let me create a re-prod repo. Btw, if you are not supporting certain node versions, you should introduce an engines.node entry to package.json (referring to @TrySound 's comment).

@cansin
Copy link
Contributor

cansin commented May 2, 2020

Ok, @ai @TrySound here is the repro: https://github.com/cansin/nanoid-module-not-found-repro

And a sample run on my local:

cansin@localhost nanoid-repro % node --version
v13.2.0
cansin@localhost nanoid-repro % yarn --version
1.22.4
cansin@localhost nanoid-repro % yarn install
yarn install v1.22.4
[1/5] 🔍  Validating package.json...
[2/5] 🔍  Resolving packages...
[3/5] 🚚  Fetching packages...
[4/5] 🔗  Linking dependencies...
[5/5] 🔨  Building fresh packages...

✨  Done in 0.09s.
cansin@localhost nanoid-repro % node index.js 
internal/modules/cjs/loader.js:614
  throw e;
  ^

Error: No valid exports main found for '/Users/cansin/code/nanoid-reprod/node_modules/nanoid'
    at resolveExportsTarget (internal/modules/cjs/loader.js:611:9)
    at applyExports (internal/modules/cjs/loader.js:492:14)
    at resolveExports (internal/modules/cjs/loader.js:541:12)
    at Function.Module._findPath (internal/modules/cjs/loader.js:643:22)
    at Function.Module._resolveFilename (internal/modules/cjs/loader.js:941:27)
    at Function.Module._load (internal/modules/cjs/loader.js:847:27)
    at Module.require (internal/modules/cjs/loader.js:1016:19)
    at require (internal/modules/cjs/helpers.js:69:18)
    at Object.<anonymous> (/Users/cansin/code/nanoid-reprod/index.js:1:20)
    at Module._compile (internal/modules/cjs/loader.js:1121:30) {
  code: 'MODULE_NOT_FOUND'
}

Edited: Sorry, made a small mistake prior. Just force-pushed and updated the console output here for the correct repro a minute ago.

@cansin
Copy link
Contributor

cansin commented May 2, 2020

Oh, sorry I should've created a separate issue. Will do that right away.

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

No branches or pull requests

4 participants