Using NPM-prefixed Import Syntax Breaks Lock File
Deno Info
Version: Deno 2.0.3
Steps to reproduce
File Tree:
- .vscode
- settings.json
- app.ts
- deno.json
Deno.json:
{
"imports": {
"@aws-sdk/client-s3": "npm:@aws-sdk/client-s3@^3.679.0"
}
}
- Add the following to
app.ts:import { S3Client } from '@aws-sdk/client-s3'; console.log(S3Client); - Run
deno run -A app.ts: Console Output:[class S3Client extends Client] - Update
app.ts:import { S3Client } from 'npm:@aws-sdk/client-s3'; console.log(S3Client); - Run
deno run -A app.ts: Console Output:error: Could not resolve 'npm:@aws-sdk/[email protected]'. - Update
app.tsto original:import { S3Client } from '@aws-sdk/client-s3'; console.log(S3Client); - Run
deno run -A app.ts: Console Output:error: Could not resolve 'npm:@aws-sdk/[email protected]'.
Expected Behavior
Both import syntaxes should work.
import { S3Client } from '@aws-sdk/client-s3';
import { S3Client } from 'npm:@aws-sdk/client-s3';
Notes
The lock file seems to become “corrupted” once the command in step 4 is run.
I can reproduce this on MacOS. Just for some context, this was a new user struggling with some imports and after a few suggestions in the Discord channel, the entire workspace seemed to become corrupted. There is a workaround -- delete the deno.lock file -- but it certainly wasn't obvious to anyone helping Josh.
Might be related: #26238
Reproducable in Github Codespaces.
Can confirm. Looking in the cache directory it seems to append a _1 to the version specifier which is wrong. It should be like this:
- /Users/marvinh/Library/Caches/deno/npm/registry.npmjs.org/@aws-sdk/client-s3/3.679.0_1/index.js
+ /Users/marvinh/Library/Caches/deno/npm/registry.npmjs.org/@aws-sdk/client-s3/3.679.0/index.js
I think the issue is https://github.com/denoland/deno_npm/blob/3b975895bcc2921a8c7de4b2963730f946343267/src/resolution/snapshot.rs#L231 It's quite silly.
My theory is that packages in deno.json and packages found in files might be duplicated. Thus removing the package from deno.json should solve the issue.
top_level_packages = [
"@aws-sdk/client-s3"
"@aws-sdk/client-s3"
]
I was able to reproduce with 2.0.2 and 2.0.3.
main.ts file
import { S3Client } from "npm:@aws-sdk/client-s3@^3.679.0";
console.log(S3Client);
No deno.json yet. No deno.lock yet.
Then run
deno run -A -r main.ts
Outputs [class S3Client extends Client].
Now let's create an import map. Create file with touch deno.json. Then run
deno add 'npm:@aws-sdk/client-s3@^3.679.0'
This generates deno.lock and deno.json.
deno.json will now have an import map.
{
"imports": {
"@aws-sdk/client-s3": "npm:@aws-sdk/client-s3@^3.682.0"
}
}
Run
deno run -A main.ts
Output:
error: Could not resolve 'npm:@aws-sdk/[email protected]'.
Caused by:
[ERR_MODULE_NOT_FOUND] Cannot find module 'file:///home/uncomfy/development/projects/.cache/deno/npm/registry.npmjs.org/@aws-sdk/client-s3/3.682.0_1/index.js' imported from 'file:///tmp/s3/main.ts'
Then let's try removing the lockfile with rm deno.lock
Run deno run -A main.ts or deno run -A -r main.ts.
Outputs [class S3Client extends Client]. This also regenerates the lockfile... of which I think points to the import from main.ts and not from deno.json. I wanted to try to test this theory so I ran deno install. The lockfile was regenerated.
Now it points to the import map in deno.json. The error came back.
[!NOTE] Notice the
3.682.0_1. By copying the3.682.0directory to3.682.0_1, it removes the error.
For those running into this: for now you can rm deno.lock and re-install.