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 "exports" main defined in <PATH>/libp2p/package.json #1583

Closed
akp111 opened this issue Feb 10, 2023 · 12 comments
Closed

Error: No "exports" main defined in <PATH>/libp2p/package.json #1583

akp111 opened this issue Feb 10, 2023 · 12 comments

Comments

@akp111
Copy link

akp111 commented Feb 10, 2023

libp2p version: 0.42.2
Node version: 16.0.0
npm version : 7.10.0

I am trying to use this in typescript to test out. The tsconfig.json I am using:

{
  "compilerOptions": {
    "module": "commonjs",
    "declaration": true,
    "removeComments": true,
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "allowSyntheticDefaultImports": true,
    "target": "es2017",
    "sourceMap": true,
    "outDir": "./dist",
    "baseUrl": "./src",
    "incremental": true,
    "skipLibCheck": true,
    "strictNullChecks": false,
    "noImplicitAny": false,
    "strictBindCallApply": false,
    "forceConsistentCasingInFileNames": false,
    "noFallthroughCasesInSwitch": false
  },
  "ts-node": {
    "transpileOnly": true,
    "files": true,
    "experimentalResolver": true
  }
}

But it gives me the following error while doing :
import { createLibp2p } from 'libp2p'

Error: No "exports" main defined in /Users/ashispradhan/Desktop/Projects/EPNS/push-storage-node/node_modules/libp2p/package.json

@akp111 akp111 added the need/triage Needs initial labeling and prioritization label Feb 10, 2023
@achingbrain
Copy link
Member

Your tsconfig.json is set to output CJS and not ESM. Please ensure you have the correct settings for "target" and "module" - see: https://github.com/ipfs/js-ipfs/blob/master/docs/upgrading/v0.62-v0.63.md#typescript-and-esm

@p-shahi p-shahi added need/author-input Needs input from the original author and removed need/triage Needs initial labeling and prioritization labels Feb 14, 2023
@github-actions
Copy link
Contributor

Oops, seems like we needed more information for this issue, please comment with more details or this issue will be closed in 7 days.

@Igx22
Copy link

Igx22 commented Feb 23, 2023

I've created a sample project with a long readme.
It shows all the errors that pop up when I try to use the typescript compiler X libp2p.
https://github.com/Igx22/p2p-test

@github-actions
Copy link
Contributor

github-actions bot commented Mar 2, 2023

Oops, seems like we needed more information for this issue, please comment with more details or this issue will be closed in 7 days.

@github-actions
Copy link
Contributor

This issue was closed because it is missing author input.

@achingbrain achingbrain removed kind/stale need/author-input Needs input from the original author labels Mar 10, 2023
@achingbrain achingbrain reopened this Mar 10, 2023
@Igx22
Copy link

Igx22 commented Mar 10, 2023

I've added more details here.

One more test case https://github.com/Igx22/p2p-test#option-2-start-compiled-js-from-distsrcindexjs-on-typescript-49

@achingbrain
Copy link
Member

I think the fundamental problem here is as you have found, ts-node does not support ESM.

Until it does, the only solution you have, if you must use ts-node, is to have your project export CJS but load libp2p (and any other ESM-only module) either from a .mjs file or from a common js file with a dynamic import.

In your test project, I make the following changes:

// tsconfig.json
{
"compilerOptions": {
    "module": "commonjs",
    // ... other stuff
}

And add a cjs file (I called it index.cjs, you can call it index.js if you remove "type": "module" from your package.json):

// src/index.cjs
async function main () {
  await import('./p2p-discovery.mjs')
}

main().catch(err => {
  console.error(err)
  process.exit(1)
})

Then run it, everything is happy:

% npx ts-node src/index.cjs 
node 1 is listening on:
/ip4/127.0.0.1/tcp/54449/p2p/12D3KooWHaikSqN6i3PVALEVLzCe2uVB7uyRU5n9AAQ29TCF9uWT
/ip4/192.168.1.10/tcp/54449/p2p/12D3KooWHaikSqN6i3PVALEVLzCe2uVB7uyRU5n9AAQ29TCF9uWT
node 2 is listening on:
/ip4/127.0.0.1/tcp/54450/p2p/12D3KooWC85PF1CF68o6HCNEny57bE8kv3rLppPtd4ZRSvuZc9VS
/ip4/192.168.1.10/tcp/54450/p2p/12D3KooWC85PF1CF68o6HCNEny57bE8kv3rLppPtd4ZRSvuZc9VS
Hello p2p world!

@achingbrain
Copy link
Member

achingbrain commented Mar 10, 2023

Actually, having said that, if I rename ./src/index.cjs to ./src/test.ts it breaks:

% npx ts-node ./src/test.ts
Error [ERR_REQUIRE_ESM]: require() of ES Module /Users/alex/test/p2p-test/src/p2p-discovery.mjs not supported.
Instead change the require of /Users/alex/test/p2p-test/src/p2p-discovery.mjs to a dynamic import() which is available in all CommonJS modules.
    at /Users/alex/test/p2p-test/src/index-c.ts:2:40
    at async main (/Users/alex/test/p2p-test/src/index-c.ts:2:5) {
  code: 'ERR_REQUIRE_ESM'
}

The above message means ts-node has transpiled await import('./p2p-discovery.mjs') to await require('./p2p-discovery.mjs') or something similar - which is completely wrong.

The error message even tells me to use import() which is what is in the un-transpiled code.

I think you need to wait until ts-node has its ducks in a row about ESM.

@Igx22
Copy link

Igx22 commented Mar 13, 2023

https://github.com/Igx22/p2p-test/pull/1/files

This fix actually helped.
But now I'm not sure if it's safe to use this in a medium sized established project.
I'll probably try to stick with an older libp2p, a js version.

@achingbrain
Copy link
Member

But now I'm not sure if it's safe to use this in a medium sized established project.

What are your concerns around this?

I'll probably try to stick with an older libp2p, a js version.

This is not recommended, newer features and bug fixes will not be ported to older versions.

@Igx22
Copy link

Igx22 commented Mar 14, 2023

What are your concerns around this?

70% of our code base is made up of commonjs / require etc.

This is not recommended, newer features and bug fixes will not be ported to older versions.

Fully agree

@achingbrain
Copy link
Member

For CJS codebases it's safe to use dynamic imports, it's less safe to stick on old versions.

Looks like you solved your problem with the ts-node upgrade & extra config though, so I'm going to close this.

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

No branches or pull requests

4 participants