Description
Version
v22.11.0
Platform
Darwin mbp-m3 23.4.0 Darwin Kernel Version 23.4.0: Fri Mar 15 00:12:25 PDT 2024; root:xnu-10063.101.17~1/RELEASE_ARM64_T6030 arm64
Subsystem
internal/modules/esm/resolve.js
What steps will reproduce the bug?
- Add a relative path which refers to a parent directory to the
imports
part in apackage.json
. E.g.:
"imports": {
"#shared/*": "../shared/*"
}
- Import it, e.g.:
import "#shared/common.js"; // or import { foo } fom "#shared/common.js"
- Get error
ERR_INVALID_PACKAGE_TARGET
Error [ERR_INVALID_PACKAGE_TARGET]: Invalid "imports" target "../shared/*" defined for '#shared/*' in the package config [root]/package.json imported from [root]/src/main.ts
at invalidPackageTarget (node:internal/modules/esm/resolve:334:10)
at resolvePackageTargetString (node:internal/modules/esm/resolve:387:11)
at resolvePackageTarget (node:internal/modules/esm/resolve:466:12)
at packageImportsResolve (node:internal/modules/esm/resolve:722:33)
at moduleResolve (node:internal/modules/esm/resolve:897:16)
at defaultResolve (node:internal/modules/esm/resolve:1037:11)
at ModuleLoader.defaultResolve (node:internal/modules/esm/loader:650:12)
at #cachedDefaultResolve (node:internal/modules/esm/loader:599:25)
at ModuleLoader.resolve (node:internal/modules/esm/loader:582:38)
at ModuleLoader.getModuleJobForImport (node:internal/modules/esm/loader:241:38) {
code: 'ERR_INVALID_PACKAGE_TARGET'
}
How often does it reproduce? Is there a required condition?
Deterministic reproduction, 100% of the times.
What is the expected behavior? Why is that the expected behavior?
Should not throw an error and the import should succeed.
Context
Have a monorepo with a BE/FE/shared split. In BE/FE want to import files from shared dir. For that need to go to the parent of the FE/BE. Importing via import { foo } from "../shared/bar.js"
works, but I want it to look cleaner and uniform without depending in which file the import is. All the other tools support such path mapping/aliasing and I though Node.js does also, but seems like it's arbitrarily restricted to only paths which are in the base dir.
What do you see instead?
ERR_INVALID_PACKAGE_TARGET
Error [ERR_INVALID_PACKAGE_TARGET]: Invalid "imports" target "../shared/*" defined for '#shared/*' in the package config [root]/package.json imported from [root]/src/main.ts
at invalidPackageTarget (node:internal/modules/esm/resolve:334:10)
at resolvePackageTargetString (node:internal/modules/esm/resolve:387:11)
at resolvePackageTarget (node:internal/modules/esm/resolve:466:12)
at packageImportsResolve (node:internal/modules/esm/resolve:722:33)
at moduleResolve (node:internal/modules/esm/resolve:897:16)
at defaultResolve (node:internal/modules/esm/resolve:1037:11)
at ModuleLoader.defaultResolve (node:internal/modules/esm/loader:650:12)
at #cachedDefaultResolve (node:internal/modules/esm/loader:599:25)
at ModuleLoader.resolve (node:internal/modules/esm/loader:582:38)
at ModuleLoader.getModuleJobForImport (node:internal/modules/esm/loader:241:38) {
code: 'ERR_INVALID_PACKAGE_TARGET'
}
Additional information
The algorithm used for the imports
feature wasn't really reviewed (?) and I think the implementer just mirrored the no-referring-to-parent-dir restriction which was used for exports
(for which it makes sense as how would you export something which isn't in your package?) without considering if it would be useful or not for imports
.
Also, importing with a reference to a parent via code is anyway possible, be it referring to a parent inside or outside of the base dir (trivially shown by trying to import a file outside of the base dir, e.g. import "../../../foo.js";
), so currently this restriction only achieves making imports
in the package.json inconsistent with how import via code works.
Could provide a small PR which fixes this as I already explored and tested an MVP solution.