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

import/no-unresolved is not recognizing installed modules that export "." #2703

Open
TheJaredWilcurt opened this issue Feb 3, 2023 · 23 comments

Comments

@TheJaredWilcurt
Copy link
Contributor

TheJaredWilcurt commented Feb 3, 2023

All dependencies are on their latest versions.
Errors:

  1:39  error  Unable to resolve path to module '@vue/test-utils'  import/no-unresolved
  4:29  error  Unable to resolve path to module 'vuex'             import/no-unresolved

Code:

import { createLocalVue, mount } from '@vue/test-utils';
import axios from 'axios';
import flushPromises from 'flush-promises';
import Vuex, { Store } from 'vuex';

import { mutations } from '@/store.js';

import App from '@/App.vue';

import { currentUser } from '@@/mockData/CommonMockData.js';
import mockUsersResponse from '@@/mockResponses/Users.js';

vuex is in the dependencies and @vue/test-utils is in the devDependencies in package.json. Both are installed and in the node_modules folder.

What's interesting is that they fail across all test files, but no other node_module imports fail. It's just these two.

eslintrc.js

const path = require('path');

module.exports = {
  root: true,
  parserOptions: {
    parser: '@babel/eslint-parser',
    ecmaVersion: 2022,
    sourceType: 'module',
    requireConfigFile: false
  },
  extends: [
    'tjw-import'
  ],
  settings: {
    'import/resolver': {
      webpack: {
        config: {
          resolve: {
            alias: {
              '@': path.resolve(__dirname, 'src'),
              '@@': path.resolve(__dirname, 'tests')
            }
          }
        }
      }
    }
  }
};

tjw-import can be seen here:

@masi
Copy link

masi commented Feb 7, 2023

Do the package.json files have an "export" key to map exports to file names?

@TheJaredWilcurt
Copy link
Contributor Author

TheJaredWilcurt commented Feb 7, 2023

// /node_modules/@vue/test-utils/package.json
...
  "main": "dist/vue-test-utils.js",
  "module": "dist/vue-test-utils.esm.js",
  "exports": {
    ".": {
      "default": "./dist/vue-test-utils.js",
      "require": "./dist/vue-test-utils.js",
      "import": "./dist/vue-test-utils.esm.js"
    }
  },
...
// /node_modules/vuex/package.json
...
  "main": "dist/vuex.common.js",
  "module": "dist/vuex.esm.js",
  "exports": {
    ".": {
      "module": "./dist/vuex.esm.js",
      "require": "./dist/vuex.common.js",
      "import": "./dist/vuex.mjs"
    },
    "./": "./"
  },
...
// /node_modules/axios/package.json
...
  "main": "index.js",
...
// /node_modules/flush-promises/package.json
...
  "main": "index.js",
...

The flush-promises and axios imports do not have a linting error, and do not have exports or module defined in their package.json.

@PierreJeanjacquot
Copy link

hey, I'm running into the same issue while importing @multiformats/multiaddr

the issue may comes from nested export of "."

@vue/test-utils
image

@multiformats/multiaddr
image

this syntax look good according to nodejs doc https://nodejs.org/docs/latest-v16.x/api/packages.html#package-entry-points but is no resolved by eslint-plugin-import

@TheJaredWilcurt TheJaredWilcurt changed the title import/no-unresolved is not recognizing installed modules import/no-unresolved is not recognizing installed modules that export "." Feb 7, 2023
@TheJaredWilcurt
Copy link
Contributor Author

Updated issue title based on this new information.

@ljharb
Copy link
Member

ljharb commented Feb 7, 2023

Do they have a "main", though?

This plugin uses resolve, which does not yet support "exports".

@TheJaredWilcurt
Copy link
Contributor Author

Updated previous example to answer question

@PierreJeanjacquot
Copy link

Thank you for the head up @ljharb
No "main" neither in @multiformats/multiaddr
I looked at the resolve source it seems neither the legacy "module" nor "exports" is supported
From Node.js 12 having only "exports" is fine, "main" is only used as a fallback when the former is missing. Since the oldest Node.js maintained LTS is 14 "exports" should be the default resolution.

@FloV22
Copy link

FloV22 commented Feb 14, 2023

issue occurs also with avajs

@TorinFrancis
Copy link

TorinFrancis commented Feb 22, 2023

This issue also occurs with react-hook-form, which does have a "main" field. For some reason, the issue does not occur with webpack 4, only 5. The error in the debug log comes from an webpack dependency (that conflicts with a eslint-import-resolver-webpack dependency).

eslint-plugin-import:resolver:webpack Error during module resolution: Error: Package path . is not exported from package /Users/torinfrancis/projects/churro/node_modules/react-hook-form (see exports field in /Users/torinfrancis/projects/churro/node_modules/react-hook-form/package.json)
    at /Users/torinfrancis/projects/churro/node_modules/webpack/node_modules/enhanced-resolve/lib/ExportsFieldPlugin.js:104:7

I can resolve the issue by changing the react-hook-form package.json from

  "exports": {
    "./package.json": "./package.json",
    ".": {
      "types": "./dist/index.d.ts",
      "import": "./dist/index.esm.mjs",
      "require": "./dist/index.cjs.js"
    }
  },

to

  "exports": {
    "./package.json": "./package.json",
    ".": "./dist/index.esm.mjs"
  },

Of course, this isn't a real solution, but seems to indicate that it's specifically the conditional exports syntax that is a problem for the resolver

@MattIPv4
Copy link

MattIPv4 commented Mar 9, 2023

👋 Just noting that I ran into this with graphql-request as well, which only has exports and not main:

...
  "exports": {
    ".": {
      "require": {
        "types": "./build/cjs/index.d.ts",
        "default": "./build/cjs/index.js"
      },
      "import": {
        "types": "./build/esm/index.d.ts",
        "default": "./build/esm/index.js"
      }
    }
  },
...

@ivorpeles
Copy link

Also happening with solid-js

@13OnTheCode

This comment was marked as off-topic.

@ljharb

This comment was marked as off-topic.

@Raynos
Copy link

Raynos commented Aug 23, 2023

Yeah it's the missing "main" field which causes an error on sql-template-tag package which appears to be ESM only and only has an exports set in the package.json

@chawes13

This comment was marked as off-topic.

@ljharb

This comment was marked as off-topic.

@JounQin

This comment was marked as off-topic.

@sla89
Copy link

sla89 commented Oct 24, 2024

I have the same issue with @nats-io/nats-core:
Unable to resolve path to module '@nats-io/nats-core' import/no-unresolved

From their package.json:

  "name": "@nats-io/nats-core",
  "version": "3.0.0-30",
  "files": [
    "lib/",
    "LICENSE",
    "README.md"
  ],
  "types": "./lib/mod.d.js",
  "exports": {
    ".": "./lib/mod.js",
    "./internal": "./lib/internal_mod.js"
  },

Image

@Airkro
Copy link

Airkro commented Jan 6, 2025

This issue has been going on for years, and I think manny issues are related to this:

#3076, #2293, #1810, #2132, #2703, #3076

For my personal project only, I wrote a node-next-resolver.cjs to solve this problem, just for reference.

@TheJaredWilcurt
Copy link
Contributor Author

@ljharb

Would switching to using this library for resolving imports/exports be possible?

A tiny (952b), correct, general-purpose, and configurable "exports" and "imports" resolver without file-system reliance

It could even be used as a fallback from what you are currently doing, so it is only called if the current checks failed before reporting an error.

@ljharb
Copy link
Member

ljharb commented Jan 17, 2025

@TheJaredWilcurt unfortunately no, because it's not actually correct - there's at least 6 different permutations of the exports algorithm depending on the node version, and we need to support all of them or none of them.

@TheJaredWilcurt
Copy link
Contributor Author

Is there any downside to supporting all of them? That seems like the clear choice, since we can't control which approach libraries choose.

@ljharb
Copy link
Member

ljharb commented Jan 17, 2025

They're contradictory. A library would have to allow the node version, and thus the algorithm, to be configurable per invocation, which is what resolve will eventually do.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

No branches or pull requests