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

Package export map & self-referencing not possible #2580

Closed
Knorgias opened this issue Oct 27, 2022 · 5 comments
Closed

Package export map & self-referencing not possible #2580

Knorgias opened this issue Oct 27, 2022 · 5 comments

Comments

@Knorgias
Copy link

Knorgias commented Oct 27, 2022

1. Description

Hey there 👋

I want to be able to self-reference my package without lint errors while using packages eslint & eslint-plugin-import.

I have a repo tree:

.
├── foo-bar.js
├── index.js
├── node_modules
├── package-lock.json
├── package.json
└── resolver.cjs

with file contents…

index.js :

export const foo = 1;

foo-bar.js :

import { foo } from 'demo-export-map';

console.log(foo);

package.json :

{
  "name": "demo-export-map",
  "version": "0.0.1",
  "description": "",
  "main": "index.js",
  "type": "module",
  "exports": {
    ".": "./index.js"
  },
  "scripts": {
    "lint": "eslint ."
  },
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "eslint": "^8.26.0",
    "eslint-plugin-import": "^2.26.0"
  }
}

2. Expected behaviour

npm run lint runs without errors

3. Actual behaviour

npm run lint throws error:
error Unable to resolve path to module 'demo-export-map' import/no-unresolved

You can reproduce it via:

git clone https://github.com/Knorgias/demo-export-map.git
npm i
npm run lint

Note: I also spotted this related issue, and so it seems that the browserify’s resolver doesn't support “exports” mapping & self-referencing, by default.

4. Possible solution/workaround

First, create a eslint-resolver.cjs file and add contents:

'use strict';
const { createRequire, builtinModules } = require('module');
exports.interfaceVersion = 2;
exports.resolve = function (source, file, config) {
  try {
    if (builtinModules.includes(source)) {
      return { found: true, path: null };
    }
    const myRequire = createRequire(file);
    const resolvedPath = myRequire.resolve(source);
    return { found: true, path: resolvedPath };
  } catch (err) {
    return { found: false };
  }
};

Then use it as import resolver in .eslintrc.js by adding:

settings: {
    'import/resolver': {
      [path.resolve('./scripts/eslint-resolver.cjs')]: {},
    },
  },

You may also need to import path, by adding const path = require('path'); to top of file.

You can reproduce it via:

git checkout fix/exports-resolver
npm run lint

View fix on github

Note: this fix only works in node (not in browser).

@ljharb
Copy link
Member

ljharb commented Oct 27, 2022

This plugin uses resolve, which does not yet support exports - and thus, doesn't support self-referencing. When it does, so will we.

Duplicate of #2430.

@ljharb ljharb closed this as not planned Won't fix, can't repro, duplicate, stale Oct 27, 2022
@toFrankie
Copy link

exports field not supported?

@ljharb
Copy link
Member

ljharb commented Nov 11, 2022

@toFrankie no, it's not supported yet.

Since packages should be using exports in a backwards-compatible way, this shouldn't be an obstacle, but if packages deviate from this best practice, it'll be annoying until resolve adds this support.

@daKmoR
Copy link

daKmoR commented Nov 16, 2022

I'm curious why is it using a custom-coded resolver when you could use the "built in" resolver from node?
e.g. why use the resolve package and not require.resolve(source);?

does eslint always run via node?

@ljharb
Copy link
Member

ljharb commented Nov 16, 2022

node's built-in resolver can't consistently be used in the way we need it; and regardless, having this plugin behave unpredictably across different node versions would be undesirable.

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

4 participants