The One
The One

Reputation: 2331

Error [ERR_PACKAGE_PATH_NOT_EXPORTED]: Package subpath './v4' is not defined by "exports"

I got this error when using uuidv4.

Failure: Package subpath './v4' is not defined by "exports" in C:\Users\mycomp\Desktop\Programming\Javascript\Serverless\Serverless Framework\node_modules\uuid\package.json
Error [ERR_PACKAGE_PATH_NOT_EXPORTED]: Package subpath './v4' is not defined by "exports" in C:\Users\mycomp\Desktop\Programming\Javascript\Serverless\Serverless Framework\node_modules\uuid\package.json

I already installed uuid and require it in my code

const uuidv4 = require('uuid/v4');

Here's the package.json

"dependencies": {
  "aws-sdk": "^2.702.0",
  "moment": "^2.27.0",
  "serverless-offline": "^6.4.0",
  "underscore": "^1.10.2",
  "uuid": "^8.1.0"
}

Upvotes: 57

Views: 88377

Answers (4)

milahu
milahu

Reputation: 3589

docs:

https://nodejs.org/api/esm.html

Like in CommonJS, module files within packages can be accessed by appending a path to the package name unless the package's package.json contains an "exports" field, in which case files within packages can only be accessed via the paths defined in "exports".

https://nodejs.org/api/packages.html#main-entry-point-export

When the "exports" field is defined, all subpaths of the package are encapsulated and no longer available to importers. For example, require('pkg/subpath.js') throws an ERR_PACKAGE_PATH_NOT_EXPORTED error.

This encapsulation of exports provides more reliable guarantees about package interfaces for tools and when handling semver upgrades for a package.

It is not a strong encapsulation since a direct require of any absolute subpath of the package such as require('/path/to/node_modules/pkg/subpath.js') will still load subpath.js.

you can get the absolute path of node_modules/pkg with something like

function get_absolute_module_path(name) {
  // this can throw MODULE_NOT_FOUND
  const main_export = require.resolve(name);
  const suffix = `/node_modules/${name}/`;
  const idx = main_export.lastIndexOf(suffix);
  if (idx == -1) {
    throw new Error(`failed to parse module path from main export path ${main_export}`);
  }
  const end = idx + suffix.length - 1;
  return main_export.slice(0, end);
}

console.log(get_absolute_module_path("pkg"));

different package managers will produce different paths, for example

npm:
/tmp/tmp.OPv0pmip4T/node_modules/cowsay

pnpm:
/tmp/tmp.ls6MykLOOC/node_modules/.pnpm/[email protected]/node_modules/cowsay

Upvotes: 0

Tchakabam
Tchakabam

Reputation: 505

We had the same error with v1 uuid module (v8.3.2).

Solved this, adding following entry to exports section of installed uuid package.json(inside your node_modules):

"./v1": "./dist/v1.js"

Full export section of my projects' node_modules/uuid/package.json:

  "exports": {
    ".": {
      "node": {
        "module": "./dist/esm-node/index.js",
        "require": "./dist/index.js",
        "import": "./wrapper.mjs"
      },
      "default": "./dist/esm-browser/index.js"
    },
    "./package.json": "./package.json",
    "./v1": "./dist/v1.js"
  },

The problem remaining i now need to keep this modification across dist installs... :/

This could be fixed with a patch on uuid source itself?

EDIT: Didn't require the module in our own source. It is a dependency of jest (via some jest reporting sub-pkg).

EDIT: Alternatively, rolling back to uuid dep to v7.0.3 may fix this issue too, see comment below.

Upvotes: 7

Miguel Trejo
Miguel Trejo

Reputation: 6677

Another option

const uuid = require('uuid');
uuid.v4(); // "c438f870-f2b7-4b2c-a1c3-83bd88bb1d79"

Upvotes: 11

Ajith P Mohan
Ajith P Mohan

Reputation: 919

ECMAScript Module syntax:

import { v4 as uuidv4 } from 'uuid';
uuidv4(); // ⇨ '9b1deb4d-3b7d-4bad-9bdd-2b0d7b3dcb6d'

CommonJS syntax:

const { v4: uuidv4 } = require('uuid');
uuidv4(); // ⇨ '1b9d6bcd-bbfd-4b2d-9b5d-ab8dfbbd4bed'

Upvotes: 85

Related Questions