medusa icon indicating copy to clipboard operation
medusa copied to clipboard

[@medusajs/js-sdk] ERR_UNSUPPORTED_DIR_IMPORT when using the `js-sdk`

Open RATIU5 opened this issue 1 year ago • 1 comments

Bug report

Describe the bug

When installing and and using the @medusajs/js-sdk and write the code to setup a client, it throws an ERR_UNSUPPORTED_DIR_IMPORT error similar to the following:

node:internal/modules/esm/resolve:251                                                                                        
    throw new ERR_UNSUPPORTED_DIR_IMPORT(path, fileURLToPath(base), String(resolved));                                       
          ^                                                                                                                  
                                                                                                                             
Error [ERR_UNSUPPORTED_DIR_IMPORT]: Directory import '/Users/username/storefront/node
_modules/.pnpm/@[email protected][email protected][email protected][email protected]_@[email protected]_/node_module
s/@medusajs/js-sdk/dist/esm/admin' is not supported resolving ES modules imported from /Users/username/storefront/node_modules/
.pnpm/@[email protected][email protected][email protected][email protected].
9_@[email protected]_/node_modules/@medusajs/js-sdk/dist/esm/index.js                                                        
    at finalizeResolution (node:internal/modules/esm/resolve:251:11)                                                         
    at moduleResolve (node:internal/modules/esm/resolve:914:10)                                                              
    at defaultResolve (node:internal/modules/esm/resolve:1038:11)                                                            
    at ModuleLoader.defaultResolve (node:internal/modules/esm/loader:557:12)                                                 
    at ModuleLoader.resolve (node:internal/modules/esm/loader:525:25)                                                        
    at ModuleLoader.getModuleJob (node:internal/modules/esm/loader:246:38)                                                   
    at ModuleJob._link (node:internal/modules/esm/module_job:126:49) {                                                       
  code: 'ERR_UNSUPPORTED_DIR_IMPORT',                                                                                        
  url: 'file:///Users/username/storefront/node_modules/.pnpm/@[email protected]
[email protected][email protected][email protected]_@[email protected]_/node_modules/@medusajs/js-sdk/dist/esm/admin'     
}                                                                                                                            
                                                                                                                             
Node.js v22.9.0

I got the same error using the following package managers:

  • npm v10.8.3
  • pnpm v9.12.1
  • yarn v1.22.22

System information

Medusa version (including plugins): Only @medusajs/js-sdk rc-4 Node.js version: 22.9.0 Database: Postgres 16 Operating system: macOS 15 Browser (if relevant): Arc (chromium)

Steps to reproduce the behavior

  1. Create a new storefront with a chosen framework (or initialize an empty/blank npm project)
  2. Add "type": "module", to your package.json
  3. Install the @medusajs/js-sdk package with version "rc"
  4. Run the server to see the error

Expected behavior

The error simply should not appear, and the client should import successfully.

Screenshots

If applicable, add screenshots to help explain your problem

Code snippets

I tested this error without a framework on an empty npm project, with this code inside run.js:

import Medusa from "@medusajs/js-sdk";

const client = new Medusa({
  baseUrl: "http://localhost:9000",
});

const test = client.store.cart.retrieve("test");
console.log(test);

Then I ran node run.js to replicate the error.

This is what the package.json looks like for this empty project:

{
  "name": "test",
  "version": "1.0.0",
  "main": "run.js",
  "type": "module",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "description": "",
  "dependencies": {
    "@medusajs/js-sdk": "rc"
  }
}

Additional context

My guess is that this has to do with the bundling/transpiling of the typescript to javascript in the js-sdk package.

RATIU5 avatar Oct 14 '24 22:10 RATIU5

For the time being, I setup a temporary fix using the following script to rewrite all the imports and exports to be explicit in defining the file name:

const fs = require("fs");
const path = require("path");

function fixImports(dir) {
  const files = fs.readdirSync(dir);

  files.forEach((file) => {
    const filePath = path.join(dir, file);
    const stat = fs.statSync(filePath);

    if (stat.isDirectory()) {
      fixImports(filePath);
    } else if (file.endsWith(".js")) {
      let content = fs.readFileSync(filePath, "utf8");

      // Fix imports
      content = content.replace(
        /from\s+['"](\.[^'"]+)['"]/g,
        (match, importPath) => {
          const fullPath = path.resolve(path.dirname(filePath), importPath);
          let relativePath = path
            .relative(path.dirname(filePath), fullPath)
            .replace(/\\/g, "/");

          if (!relativePath.startsWith(".")) {
            relativePath = "./" + relativePath;
          }

          if (fs.existsSync(fullPath + ".js")) {
            return `from '${relativePath}.js'`;
          } else if (fs.existsSync(path.join(fullPath, "index.js"))) {
            return `from '${relativePath}/index.js'`;
          }
          return match;
        },
      );

      // Fix exports
      content = content.replace(
        /export\s+.*from\s+['"](\.[^'"]+)['"]/g,
        (match, exportPath) => {
          const fullPath = path.resolve(path.dirname(filePath), exportPath);
          let relativePath = path
            .relative(path.dirname(filePath), fullPath)
            .replace(/\\/g, "/");

          if (!relativePath.startsWith(".")) {
            relativePath = "./" + relativePath;
          }

          if (fs.existsSync(fullPath + ".js")) {
            return match.replace(exportPath, relativePath + ".js");
          } else if (fs.existsSync(path.join(fullPath, "index.js"))) {
            return match.replace(exportPath, relativePath + "/index.js");
          }
          return match;
        },
      );

      fs.writeFileSync(filePath, content);
    }
  });
}

const esmDir = path.join(
  __dirname,
  "..",
  "node_modules",
  "@medusajs",
  "js-sdk",
  "dist",
  "esm",
);
fixImports(esmDir);
console.log("Fixed ESM imports and exports for @medusajs/js-sdk");

RATIU5 avatar Oct 15 '24 15:10 RATIU5

Any update on this issue? Been having problems in my storefront too.

valiukasd avatar Nov 17 '24 18:11 valiukasd

@RATIU5 Thanks for the temporary fix, hoping for an update soon.

valiukasd avatar Nov 17 '24 19:11 valiukasd

This issue is stale because it has been open 30 days with no activity. Remove stale label or comment or this will be closed in 3 days.

github-actions[bot] avatar Dec 18 '24 02:12 github-actions[bot]

This issue was closed because it has been stalled for 3 days with no activity.

github-actions[bot] avatar Dec 31 '24 01:12 github-actions[bot]

So there is no ES module support for nodejs.

OK, I see.. As long as node does not support these directory imports, this will not work. So far, client only :-)

gp-slick-coder avatar Jan 24 '25 12:01 gp-slick-coder

Switching to bun solved my problems 👍

didair avatar Feb 03 '25 08:02 didair

Switching to bun solved my problems 👍

Can you please update if it's still working? I tried with Bun & it's the same issue

nsakibp avatar May 24 '25 03:05 nsakibp

As of today, the issue is still present. I try to use Medusa sdk with Astro, and I get the same error.

Thanks to @RATIU5 script, we have a workaround. Here is how to use il in Astro :

  1. create the file scripts/fix-imports.cjs and paste @RATIU5 code there
  2. edit your package.json to add a new script :
  "scripts": {
    "dev": "astro dev",
    "build": "astro build",
    "preview": "astro preview",
    "astro": "astro",
+   "fix": "node scripts/fix-imports.cjs"
  },
  1. use npm run fix to execute the fix before your build command.

Fab1en avatar Aug 21 '25 08:08 Fab1en