browserify / browserify/resolve
Node.js imports field is not supported
- Dominant language
- JavaScript
- Stars
- 796
- Forks
- 188
- PR merge metrics
- No merged PRs in 30d
Description
## Imports fields is not supported
### Overview
**Short description**: **resolve** fails to handle Node.js' [imports field](https://nodejs.org/docs/latest/api/packages.html#imports) style imports.
**Steps to reproduce**:
1. Add a simple entry to imports fields to `package.json`:
```diff
+ "imports": {
+ "#src/*": "./src/*"
+ },
```
2. Create a `src/module-1.js` file
3. Call resolve (async or sync) with `#src/module-1.js` argument
**Expected behaviour**: `resolve()` returns the full path of the module
**Actual behaviour**: `resolve()` throws an error
**Minimal reproducible example**: I created the [resolve-nodejs-import](https://stackblitz.com/edit/resolve-nodejs-import-test?file=src%2Fresolve-test.js&terminal=dev) StackBlitz project to showcase the issue with some guiding. Running `npm start` should execute the script and show the behaviour of `resolve()` in various circumstances.
### Context
I'm using the **resolve** package as a transitive dependency of [**eslint-plugin-import**](https://github.com/import-js/eslint-plugin-import/tree/main) for a small project I created, [wordoftheday](https://github.com/pcdevil/wordoftheday/).
This project is very minimal and doesn't utilise any bundler but instead relies on Node.js' module resolution and imports field. By this, the imports are non-relative paths with TypeScript style import aliases. For example the `src/lib/word-resolver.mjs` file has the following dependencies (at [L3-6](https://github.com/pcdevil/wordoftheday/blob/680de8bac6faeb35665d92f57759f97a3c6172ce/src/lib/word-resolver.mjs#L3-L6)):
```javascript
import { UndefinedConfigError, config } from '#src/lib/config.mjs';
import { getLogger } from '#src/util/logger.mjs';
import { NamedError } from '#src/util/named-error.mjs';
import { request } from '#src/util/request.mjs';
```
This works just fine on run, I don't experience any side-effects by calling `pnpm start`.
I decided to upgrade ESLint to v9 and after tinkering the config file, I received a lot of errors from **import**'s [no-unresolved](https://github.com/import-js/eslint-plugin-import/blob/main/docs/rules/no-unresolved.md) rule when I ran `eslint`.
After some investigation I realised the issue lies deeper at **resolve**, as it doesn't unfold module names starting with a `#`. I believe the issue is at the check where the module's nature is determined:
- sync:
https://github.com/browserify/resolve/blob/fd788d94d037e32d4f4be948e2f7e15f6981f004/lib/sync.js#L101-L111
- async:
https://github.com/browserify/resolve/blob/fd788d94d037e32d4f4be948e2f7e15f6981f004/lib/async.js#L141-L164
### Closing thoughts
The issue is not related to ESLint v9, but I mistakenly didn't include **eslint-plugin-import** to my `.eslintrc.json`'s extends field (at [L7-10](https://github.com/pcdevil/wordoftheday/blob/680de8bac6faeb35665d92f57759f97a3c6172ce/.eslintrc.json#L7-L10)) and only realised the mistake on update.
I can understand if you believe it's out of the scope of this package, although I'd think the imports field feature would be supported. In that case a possible workaround for me is to wrap [**eslint-import-resolver-node**](https://github.com/import-js/eslint-plugin-import/tree/main/resolvers/node) and transform imports starting with `#` to project relative paths.
However, if you believe it's worth fixing it, I'd also volunteer to provide a change-set for review!
Contributor guide
Assessment
This issue has not been assessed yet.