Using ts-node with ESM module: ipfs-http-client

81 views Asked by At

I am trying to run some tests on files I created which use ipfs-http-client. I write code with typescript and I am using ts-node to run files without actually doing the build (when i do tests). I am running this code in a commonJs folder. As ipfs packages is ESM only, it gives me an error each time i try to run this code

No "exports" main defined in ..... (points to the ipfs folder in node_modules)

To reproduce the issue I created a bare project which shows exactly what is happening.

I run npm init and npm i ipfs-http-client. I have already installed ts-node.

the packages.json file looks like this

{
  "name": "import_esm_in_commonjs",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "dependencies": {
    "ipfs-http-client": "^59.0.0"
  }
}

and, for tsConfig file, I am just using the basic ts-node one:

{
  "ts-node": {
    "cwd": "/Users/WAW/Documents/Projects/_issues_stack_over_flow/import_ESM_in_commonJS",
    "projectSearchDir": "/Users/WAW/Documents/Projects/_issues_stack_over_flow/import_ESM_in_commonJS"
  },
  "compilerOptions": {
    "lib": [
      "es2021"
    ],
    "module": "commonjs",
    "target": "es2021",
    "strict": true,
    "esModuleInterop": true,
    "skipLibCheck": true,
    "forceConsistentCasingInFileNames": true,
    "types": [
      "node"
    ],
    "sourceMap": true,
    "inlineSourceMap": false,
    "inlineSources": true,
    "declaration": false,
    "noEmit": false,
    "outDir": "./.ts-node"
  }
}

I just created an index.ts file in the root of the project which looks like this:

import "ipfs-http-client"
console.log("file works");

when I run ts-node index.ts I receive the previously mentioned error:

No "exports" main defined in ..... (pointing to the ipfs folder in the node_modules)

Hope someone can help!

1

There are 1 answers

0
Giacomo Gagliano On

Actually I found how to do it.

In order to be able to import esm only modules in a typescripy project with "type": "commonJs"in the package.json like this:

import { create } from "ipfs-http-client";
console.log(create);

I did the following:

  • explicitly set tsconfig file for ts-node:
{
  "ts-node": {
    "cwd": "/Users/WAW/Documents/Projects/_issues_stack_over_flow/import_ESM_in_commonJS",
    "projectSearchDir": "/Users/WAW/Documents/Projects/_issues_stack_over_flow/import_ESM_in_commonJS"
  },
  "compilerOptions": {
    "lib": [
      "es2021"
    ],
    "module": "commonjs",
    "target": "es2021",
    "strict": true,
    "esModuleInterop": true,
    "skipLibCheck": true,
    "forceConsistentCasingInFileNames": true,
    "types": [
      "node"
    ],
    "sourceMap": true,
    "inlineSourceMap": false,
    "inlineSources": true,
    "declaration": false,
    "noEmit": false,
    "outDir": "./.ts-node"
  }
}
  • set "module": "ES2022" and "modeResolution": "Node" in the tsconfig.json in the tsconfig.json
{
...

  "compilerOptions": {
    "module": "ES2022",
    "moduleResolution": "Node",
...
}
  • when calling ts-node use the --esm flag:
ts-node --esm name_of_the_file

and it works =)

ps: I also updated the repo