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

ERR_PACKAGE_PATH_NOT_EXPORTED: No "exports" main defined in helia/package.json #190

Closed
charlesxsh opened this issue Jul 29, 2023 · 18 comments
Labels
need/author-input Needs input from the original author

Comments

@charlesxsh
Copy link

Error

Error [ERR_PACKAGE_PATH_NOT_EXPORTED]: No "exports" main defined in /<path>/node_modules/helia/package.json
    at new NodeError (node:internal/errors:399:5)
    at exportsNotFound (node:internal/modules/esm/resolve:361:10)
    at packageExportsResolve (node:internal/modules/esm/resolve:641:13)
    at resolveExports (node:internal/modules/cjs/loader:538:36)
    at Function.Module._findPath (node:internal/modules/cjs/loader:607:31)
    at Function.Module._resolveFilename (node:internal/modules/cjs/loader:1033:27)
    at Function.Module._resolveFilename.sharedData.moduleResolveFilenameHook.installedValue [as _resolveFilename] (/home/sxia/code/dasset/node_modules/@cspotcode/source-map-support/source-map-support.js:811:30)
    at Function.Module._load (node:internal/modules/cjs/loader:893:27)
    at Module.require (node:internal/modules/cjs/loader:1113:19)
    at require (node:internal/modules/cjs/helpers:103:18) {
  code: 'ERR_PACKAGE_PATH_NOT_EXPORTED'
}

main.ts

import { strings } from '@helia/strings';
import { createHelia } from 'helia';

(async () =>{
    const helia = await createHelia();
})()

dependencies:
"helia": "^1.3.8"

"@helia/strings": "^1.0.0",

When I just simply run the above code with ts-node main.ts

@tomachianura
Copy link

+1
this is very bad, and needs to be addressed as soon as possible.

@hebr3rt
Copy link

hebr3rt commented Aug 5, 2023

I'm having same issue

@achingbrain
Copy link
Member

achingbrain commented Aug 6, 2023

Helia is an ESM-only module. You cannot use require to load it, you must use import.

If you cannot use ESM for your project, you can use the dynamic import function to import it - please see the helia-cjs example for more.

Chances are, ts-node is compiling to CJS in the background. You must configure typescript to output ESM.

@tomachianura
Copy link

I’m using import, on a nestjs project.
And obviously it doesn’t work, still same error described in this thread.

@SgtPooki
Copy link
Member

@tomachianura can you provide your source code or a reproducible example so we can dive deeper?

@SgtPooki
Copy link
Member

For others here, please check out #216 (comment) and let us know if you continue to have issues, but confirm your build tool supports ESM.

@SgtPooki SgtPooki added the need/author-input Needs input from the original author label Aug 10, 2023
@achingbrain
Copy link
Member

achingbrain commented Aug 10, 2023

There's also a helia-ts-node example to show how to get it working, it needs a bit of extra config.

@tomachianura
Copy link

we work with CommonJS, and we can't change this.
Helia shall fully support CommonJS as well, right?

@achingbrain
Copy link
Member

Yes, please see the helia-cjs example for how to use Helia from a CommonJS project.

@tomachianura
Copy link

even when looking at
https://github.com/ipfs-examples/helia-cjs
just doesn't work on an existing nestJS project using CommonJS.

can you kindly provide any solution to that please?
thanks in advance for your support and for being so reactive on this topic.

@achingbrain
Copy link
Member

just doesn't work on an existing nestJS project using CommonJS.

I'm guessing that you have a NextJS project, you've set "module" to "CommonJS".

I'm guessing that you've done something like:

const { createHelia } = await import('helia');

and you've checked your output folder and seen it being transpiled to:

const { createHelia } = await Promise.resolve().then(() => require('helia'));

The solution here appears to be to change "moduleResolution" to "Node16" - this prevents the dynamic import from being transpiled to require.

If this does not solve your problem then you are going to have to provide a link to your source code or a reproducible example for us to assist further, because all this guess work has a high cost in time spent and a low probability of success.

@tomachianura
Copy link

it's not Next, it's Nest :)
changing moduleResolution to Node16 breaks the entire project as well.
our engine is totally closed source, but it's enough to start a new nestjs app (which by default is CommonJS) and install helia to make it crash with the ERR_PACKAGE_PATH_NOT_EXPORTED error.

Clearly, your suggestions described in the helia-nestjs doesn't work, cause changing CommonJS for something else is NOT a solution, considering it'll break a whole project.

Looking forward to have a valid solution, thanks again!
PS: let me know if you need a clean nestjs app with helia installed and crashing, i can create it in the next days once back home.

wish you all a great weekend ahead!

@SgtPooki
Copy link
Member

PS: let me know if you need a clean nestjs app with helia installed and crashing, i can create it in the next days once back home.

Yes please. We can provide much better help with reproducible code. Thanks!

@achingbrain
Copy link
Member

achingbrain commented Aug 13, 2023

TBH I'm not sure if that's going to add much value since there an example available of how to configure NestJS to work with Helia, so we know the default settings for NestJS are to build CJS, and we know the config changes needed to make it build ESM, but you can't apply them because it "breaks the entire project".

The root of the issue here is that ERR_PACKAGE_PATH_NOT_EXPORTED is caused when CJS code uses require to load an ES module.

To prevent his happening you have to import it, or await import if you have to stick on CJS.

Your TypeScript settings are (I think, please confirm) transpiling await import('helia') to await Promise.resolve().then(() => require('helia')) which just isn't going to work.

This is not a problem specific to Helia, you'll have this problem with any module written in ESM that use an exports map.

I suggest fixing your project so it can work with ES modules. This might be as simple as adding '.js' to every imported file from the current project since ESM requires file extensions.

If you won't do this then the only other thing you can do is try to defeat the transpilation of import to require by using eval:

const { createHelia } = await eval('import("helia")')

@tomachianura
Copy link

TBH I'm not sure if that's going to add much value since there an example available of how to configure NestJS to work with Helia, so we know the default settings for NestJS are to build CJS, and we know the config changes needed to make it build ESM, but you can't apply them because it "breaks the entire project".

The root of the issue here is that ERR_PACKAGE_PATH_NOT_EXPORTED is caused when CJS code uses require to load an ES module.

To prevent his happening you have to import it, or await import if you have to stick on CJS.

Your TypeScript settings are (I think, please confirm) transpiling await import('helia') to await Promise.resolve().then(() => require('helia')) which just isn't going to work.

This is not a problem specific to Helia, you'll have this problem with any module written in ESM that use an exports map.

I suggest fixing your project so it can work with ES modules. This might be as simple as adding '.js' to every imported file from the current project since ESM requires file extensions.

If you won't do this then the only other thing you can do is try to defeat the transpilation of import to require by using eval:

const { createHelia } = await eval('import("helia")')

totally correct!
I can't move to ESM cause it's a massive huge project, and also partially closed source.
Instead, your suggestion of using eval to defeat the transpilation it's as dirty as brilliant, it works perfectly for our purposes.

I'll do my best to make the entire thing ESM, but this will require a huge effort and long time to sync all the team and the deploys of the project, so for now your solution works just great!

thanks a lot @achingbrain!

@sosioo
Copy link

sosioo commented Sep 10, 2023

'Helia is an ESM-only module. You cannot use require to load it, you must use import."
That's just sad. Don't you think it is a deal breaker for many developers? It sure is for me. IPFS is a good fit for my project using Electron but that lack of support for require() imports makes everything a lot harder.

@achingbrain
Copy link
Member

There is nothing stopping you from using Helia in Electron - please see the Running Helia in Electron example for how to get started.

@sosioo
Copy link

sosioo commented Sep 10, 2023

OK That's encouraging! Thank you for the link.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
need/author-input Needs input from the original author
Projects
No open projects
Development

No branches or pull requests

6 participants