`package.json#source` field is used for npm packages with pnpm
mischnic opened this issue ยท 11 comments
๐ bug report
When using pnpm, the resolver tries to use the "source"
field of a package from npm.
๐ฏ Current Behavior
๐จ Build failed.
@parcel/core: Failed to resolve 'compute-scroll-into-view' from './index.js'
/index.js:1:35
> 1 | import computeScrollIntoView from "compute-scroll-into-view";
> | ^^^^^^^^^^^^^^^^^^^^^^^^^^
2 |
3 | computeScrollIntoView();
@parcel/resolver-default: Could not load './src/index.ts' from module 'compute-scroll-into-view' found in package.json#source
/node_modules/compute-scroll-into-view/package.json:88:13
87 | },
> 88 | "source": "src/index.ts",
> | ^^^^^^^^^^^^^^ './src/index.ts' does not exist, did you mean './dist/index.js'?'
89 | "umd:main": "umd/compute-scroll-into-view.min.js"
90 | }
๐ค Expected Behavior
Ignore package.json#source
for npm packages
๐ฆ Context
๐ป Code Sample
import computeScrollIntoView from "compute-scroll-into-view";
computeScrollIntoView();
{
"dependencies": {
"@babel/core": "^7.12.13",
"compute-scroll-into-view": "^1.0.16"
}
}
Use pnpm install
!
๐ Your Environment
Software | Version(s) |
---|---|
Parcel | 31f431d |
@mischnic Did you find a workaround for this issue? I'm also trying to load compute-scroll-into-view
in a pnpm + parcel2 project.
I don't think there is a workaround, unfortunately.
This is the problematic code
parcel/packages/utils/node-resolver-core/src/NodeResolver.js
Lines 647 to 654 in f28eaf6
Until pnpm, symlinks meant that you're using a monorepo and you're not importing an npm package but another monorepo package. The condition should probably be adjusted to make pnpm work.
Maybe something like this? This is very specific to pnpm though.
if (realpath === file || realpath.includes('node_modules/.pnpm'))
delete pkg.source;
Or maybe something like "if it's a symlink and the realpath is inside of the project root"
Isn't everything in the project root? Unless you meant the node_modules of the project root, that could work.
if (realpath === file || realpath.startsWith(path.join(this.projectRoot, 'node_modules')))
delete pkg.source;
Don't the pnpm symlinks point to a global folder like /Users/abc/.pnpm/....
?
You're right I had to Google around to check. But pnpm works with a content-addressable store /Users/abc/.pnpm-store
, and a virtual store node_modules/.pnpm
. After an install it mentions that packages are hard linked from the content-addressable store to the virtual store.
Packages are hard linked from the content-addressable store to the virtual store.
Content-addressable store is at: /Users/ngfk/.pnpm-store/v3
Virtual store is at: node_modules/.pnpm
Progress: resolved 951, reused 950, downloaded 1, added 954, done
In my case (macOS) the realpath resolved to the location in the virtual store. Not sure if it's the same on a Windows machine. Here's an example of what I get in my project when I simply add a console.log(realpath)
to the function.
console: /Users/ngfk/Repositories/bce-module-manager/package/client/package.json
console: /Users/ngfk/Repositories/bce-module-manager/package/client/package.json
console: /Users/ngfk/Repositories/bce-module-manager/package/client/package.json
console: /Users/ngfk/Repositories/bce-module-manager/package/client/package.json
console: /Users/ngfk/Repositories/bce-module-manager/package/client/package.json
console: /Users/ngfk/Repositories/bce-module-manager/package/client/package.json
console: /Users/ngfk/Repositories/bce-module-manager/package/client/package.json
console: /Users/ngfk/Repositories/bce-module-manager/package/client/package.json
console: /Users/ngfk/Repositories/bce-module-manager/package/client/package.json
console: /Users/ngfk/Repositories/bce-module-manager/package/client/package.json
console: /Users/ngfk/Repositories/bce-module-manager/node_modules/.pnpm/compute-scroll-into-view@1.0.16/node_modules/compute-scroll-into-view/package.json
console: /Users/ngfk/Repositories/bce-module-manager/node_modules/.pnpm/@parcel/runtime-js@2.0.0-nightly.599/node_modules/@parcel/runtime-js/package.json
console: /Users/ngfk/Repositories/bce-module-manager/node_modules/.pnpm/@parcel/runtime-js@2.0.0-nightly.599/node_modules/@parcel/runtime-js/package.json
console: /Users/ngfk/Repositories/bce-module-manager/node_modules/.pnpm/@parcel/runtime-js@2.0.0-nightly.599/node_modules/@parcel/runtime-js/package.json
console: /Users/ngfk/Repositories/bce-module-manager/node_modules/.pnpm/@parcel/runtime-js@2.0.0-nightly.599/node_modules/@parcel/runtime-js/package.json
console: /Users/ngfk/Repositories/bce-module-manager/node_modules/.pnpm/@parcel/runtime-js@2.0.0-nightly.599/node_modules/@parcel/runtime-js/package.json
console: /Users/ngfk/Repositories/bce-module-manager/node_modules/.pnpm/@parcel/runtime-js@2.0.0-nightly.599/node_modules/@parcel/runtime-js/package.json
Yes, it's in /Users/abc/.pnpm-store/
. However that can be changed using
npm config set store-dir /path/to/.pnpm-store
I think a .modules.yml
file can also be stored in the node_modules
to redirect you to a different location as well. I've read about that, but never used it.
I actually use Rush to manage my monorepo, and I have it using pnpm. The final destination for the dependencies is .../project-xyz/common/temp/node_modules/.pnpm/node_modules
. But I think pnpm actually saves the dependencies in sibling folders corresponding to the repository names to which node_modules is linked.
.../project-xyz/common/temp/node_modules/.pnpm/node_modules (symlinks to the other two folders)
.../project-xyz/common/temp/node_modules/.pnpm/npm.fontawesome.com
.../project-xyz/common/temp/node_modules/.pnpm/registry.npmjs.org
Is there something I can do to help get a fix for this issue? I'm still running into packages that parcel incorrectly tries to resolve using package.json#source
.
For this package specifically, adding "compute-scroll-into-view": "compute-scroll-into-view/dist"
under "alias"
in package.json solved the issue.
Maybe something like this? This is very specific to pnpm though.
if (realpath === file || realpath.includes('node_modules/.pnpm')) delete pkg.source;
I made a small Proof-Of-Concept ParcelJS Resolver based on your solution + DefaultResolver, it seems to fix my issues by now:
Usage:
pnpm i parcel-resolver-pnpm
Partial .parcelrc
file:
{
"resolvers": [
"parcel-resolver-pnpm",
"..."
]
}
Here is the project repository: https://github.com/guesant/parcel-resolver-pnpm