Uuid: package.json is not defined by "exports"

Created on 11 May 2020  ·  27Comments  ·  Source: uuidjs/uuid

Describe the bug

'./package.json' is not defined by "exports" when upgrading from v7.0.3 to v8.0.0

To Reproduce

Steps to reproduce the behavior:

  1. upgrading from v7.0.3 to v8.0.0 and running npm build in a Svelte project
  2. See error

Expected behavior

A rollup bundle without an error as shown below.

Runtime

  • OS: macOS
  • Runtime: Node.js
  • Runtime Version: 14.1.0

Additional context

This is the command line output after upgrading from v7.0.3 to v8.0.0 in a Svelte project

> Package subpath './package.json' is not defined by "exports" in /Users/sa/0/edm/node_modules/uuid/package.json
Error [ERR_PACKAGE_PATH_NOT_EXPORTED]: Package subpath './package.json' is not defined by "exports" in /Users/sa/0/edm/node_modules/uuid/package.json
    at applyExports (internal/modules/cjs/loader.js:491:9)
    at resolveExports (internal/modules/cjs/loader.js:507:23)
    at Function.Module._findPath (internal/modules/cjs/loader.js:635:31)
    at Function.Module._resolveFilename (internal/modules/cjs/loader.js:1007:27)
    at Function.requireRelative.resolve (/Users/sa/0/edm/node_modules/require-relative/index.js:30:17)
    at tryResolve (/Users/sa/0/edm/node_modules/rollup-plugin-svelte/index.js:50:19)
    at Object.resolveId (/Users/sa/0/edm/node_modules/rollup-plugin-svelte/index.js:177:21)
    at /Users/sa/0/edm/node_modules/rollup/dist/shared/rollup.js:18217:25

I found some additional information in a SO post that might very well be related to the issue I'm seeing https://stackoverflow.com/questions/61621828/getting-strange-error-using-uuid-npm-module-what-am-i-doing-wrong/61730597#61730597

Most helpful comment

I fixed it by running npm ci.

All 27 comments

@evdama could you provide actual steps that let me reproduce your error (meaning, code that I can execute)? "grading from v7.0.3 to v8.0.0 and running npm build in a Svelte project" does not really help since I have no clue about the details of your project…

I'm using uuid inside my server.js like so

import { v4 as uuidv4 } from 'uuid'

... more code...


const setNonceMiddleware = ( request, response, next ) => {
  try {
    response.locals.nonce = uuidv4()
    next()
  } catch ( error ) {
    console.error ( 'error from setNonceMiddleware: ', error )
  }
}

I don't use uuid anywhere else in my app, just the snippet above. I'll also provide a gist of my rollup config that might help, it's a Sapper (Svelte) project with a client and a server as well as a serviceworker section: https://gist.github.com/7b56754df52b5b26b1db3f2873cee726

OK, this is strange.

Judging from the stack trace of your error this looks much more like an issue with https://github.com/sveltejs/rollup-plugin-svelte though…

Apparently the svelte rollup plugin uses require-relative under the hood:

    at Function.requireRelative.resolve (/Users/sa/0/edm/node_modules/require-relative/index.js:30:17)

which likely has problems with modern Node.js module loading since its latest version has been published 6 years ago:

image

I don't think we could or should solve this in this library here. I think the right place to report this issue would be https://github.com/sveltejs/rollup-plugin-svelte/issues

@ctavan thanks much, I'm trying to catch one of the svelte devs (@Conduitry) on discord, ask him what he thinks is best i.e. me filling an issue about an outdated require-relative that's used in rollup-plugin-svelte

@evdama I dug a little bit into it, I think it's a problem directly in the svelte rollup plugin, see https://github.com/sveltejs/rollup-plugin-svelte/issues/104

It is not only a Svelte Rollup problem.

I upgraded to v8.0.0 in my React Native project and encountered the exact same problem.

@Danny-A can you specify what you mean by "exact same problem"? Do you get exactly the same stack trace? Do you use svelte and rollup-plugin-svelte within react-native (is that even possible)?

@TrySound I think you are more familiar with use cases of requiring package.json files from npm modules in bundler pipelines. Is this something that npm modules should generally support? Is this a documented requirement for e.g. rollup?

@ctavan Sorry for the lack of context. I get a Warning in RN. I don't get a stack trace and I am not using rollup.

warn Package uuid has been ignored because it contains invalid configuration. Reason: Package subpath './package.json' is not defined by "exports" in /Users/danny/Projecten/***/mobile/node_modules/uuid/package.json

There is no any requirement for bundlers because they mostly do not support native node modules. Perhaps package.json should always be in exports list. See here
https://github.com/ai/nanoevents/issues/44#issuecomment-602010343
https://unpkg.com/[email protected]/package.json

For the time being the warning can simply be ignored for uuid, the functionality is not affected!

I think it might make more sense to actually fix this in react-native instead of adding this workaround to every single module on npm. If you agree, feel free to give your 👍 for https://github.com/react-native-community/cli/issues/1168

In general, I think it's a good idea for packages to explicitly add "./package.json": "./package.json" to their "exports" field.

However, unless the ecosystem is consistently willing to do this, tooling will have to determine a different mechanism for accessing package.jsons - something like findPackageJSONFrom(path.dirname(require.resolve('pkg'))).

To rephrase @ljharb's suggestion (assuming Node.js won't change the current behavior, see https://github.com/nodejs/node/issues/33460):

  1. Packages that rely on meta information for other tools from their package.json must export it.
  2. Tools must be able to handle dependencies which don't export package.json gracefully (i.e. without crashing).

    • Tools which make use of meta information from package.json _could_ warn if packages don't export package.json in order to help package maintainers decide if they need to export it or not.

Just release [email protected] which now exports package.json, so the problem reported here should be gone for now.

Hi @ctavan ,

I am seeing the same error using the latest version 8.1.0 but for the v4 exports:

Package subpath './v4' is not defined by "exports" in /Users/path-to-project/nested/in/node-modules-folder/node_modules/uuid/package.json

$ node -v
v14.4.0

This is a different issue, support for deep imports has been deprecated in 7.0.0 and removed in 8.0.0: https://github.com/uuidjs/uuid#deep-requires-no-longer-supported

Strange 🤔 I am using it as follow const { v1: uuid } = require('uuid') (so not deep required).

The node_modules folder containing the node program I am launching is not at the root of the package (nested a few level below) so maybe another dependency with an older version of uuid is required instead. But I would expect the require call to resolve to the closest node_modules/uuid so not sure.

Also manually deleting:

  "exports": {
    "./package.json": "./package.json",
    ".": {
      "require": "./dist/index.js",
      "import": "./wrapper.mjs"
    }
  },

in the deeply nested node_modules/uuid/package.json seems to make it work.

Perhaps some of modules does not list uuid in dependencies and uses the wrong one.

Yes, it looks like one of your dependencies uses uuid and either specifies a wrong dependency version range or does not specify uuid as a dependency at all. Consequently, as @TrySound notes, it tries to load the wrong version of uuid.

You could find the affected package by performing a search for the string uuid/v4 in the entire node_modules subtree, maybe you can identify the package that uses the deep require but doesn't specify the correct dependency in its package.json.

Thanks for the pointers. The problem is actually with npm/lerna where one package didn't get it's (newer) version of uuid installed locally and was using a (probably) deduped one in the parent node_modules folder coming from an older package. Quite a specific use case, nothing wrong with uuid 👍

ECMAScript Module syntax:

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

Hey @musamaUet. Do you have a question?

const { v1: uuidv1 } = require('uuid');

I fixed it by running npm ci.

@alayor thanks , save my ass

Was this page helpful?
0 / 5 - 0 ratings

Related issues

ctavan picture ctavan  ·  5Comments

guybedford picture guybedford  ·  9Comments

8bitjoey picture 8bitjoey  ·  5Comments

ORESoftware picture ORESoftware  ·  5Comments

nemoload picture nemoload  ·  3Comments