Error: No valid exports main found for 'node_modules\nanoid'
Closed this issue ยท 15 comments
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 <domagoj.strekelj@gmail.com>",
"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:
npm install
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?
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"
.
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
@ai No worries, I'll look into it tomorrow afternoon at the latest :) Thanks for the quick reply!
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:
I haven't had a change to go through it in detail yet and try fixes, but at least it's something.
Wow. So big research ๐
I will review it tomorrow, because I am going to sleep soon. Just want to say that you are great.
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:
+-- ts-node-dev@1.0.0-pre.44
| +-- ts-node@8.8.2
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?
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
?
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!
Wow, Great!
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 node@13.2.0. 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?
@cansin creates a separate issue with all details of your project. What builder do you use?
@cansin See the latest node 13 version is v13.14.0. Your version is very old.
https://nodejs.org/docs/latest-v13.x/api/
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).
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.
Oh, sorry I should've created a separate issue. Will do that right away.