denoland / deno

A modern runtime for JavaScript and TypeScript.
https://deno.com
MIT License
93.44k stars 5.18k forks source link

npm peerDependency duplicate module issue with elysia #21394

Open marvinhagemeister opened 7 months ago

marvinhagemeister commented 7 months ago

Reported on discord:

Hi all 👋 ,

you can reproduce it like:

// main.ts
import 'npm:@bogeychan/elysia-polyfills/deno/index.js';

import 'npm:@sinclair/typebox@0.31.17';

import { cors } from 'npm:@elysiajs/cors@0.7.2';
import { html } from 'npm:@elysiajs/html@0.7.3';
import { bearer } from 'npm:@elysiajs/bearer@0.7.0';
import { swagger } from 'npm:@elysiajs/swagger@0.7.4';

import { Elysia } from 'npm:elysia@0.7.29';

new Elysia()
  .use(cors())
  .use(html())
  .use(bearer())
  .use(swagger())
  .get('/', () => ({ hello: 'Deno👋' }))
  .listen(8080);

running the following commands works 50% of the time (checkout the screenshots): no change to code

rm -fr ~/.cache/deno/ deno.lock node_modules/
deno run --node-modules-dir --allow-net  main.ts

doesn't work with or without --node-modules-dir

idk why but sometimes deno decides to download the elysia dependency multiple times (with _1) suffix (checkout the screenshots). therefore some dependencies use/reference elysia_01 as it's peer). that's bad because both elysia's reference the same @sinclair/typebox package and it throws the error Duplicate type kind 'Files' detected because its executed twice, ... https://github.com/elysiajs/elysia/blob/757357f28749674844fc848e4ddd715134f7714f/src/type-system.ts#L144

the dependency tree looks something like this:

main.ts
  elysia
    @sinclair/typebox (peer)
  @elysiajs/cors
    elysia (peer)
  @elysiajs/html
    elysia (peer)
  @elysiajs/bearer
    elysia (peer)
  @elysiajs/swagger
    elysia (peer)

The error that I'm getting looks like this when I run the provided sample code:

error: Uncaught Error: Duplicate type kind 'Files' detected
    at Object.Type (file:///Users/marvinh/dev/test/deno-peer-deps2/node_modules/.deno/@sinclair+typebox@0.31.17/node_modules/@sinclair/typebox/system/system.js:58:19)
    at Object.<anonymous> (file:///Users/marvinh/dev/test/deno-peer-deps2/node_modules/.deno/elysia@0.7.29_1/node_modules/elysia/dist/cjs/type-system.js:64:35)
    at Object.<anonymous> (file:///Users/marvinh/dev/test/deno-peer-deps2/node_modules/.deno/elysia@0.7.29_1/node_modules/elysia/dist/cjs/type-system.js:244:4)
    at Module._compile (node:module:733:34)
    at Object.Module._extensions..js (node:module:747:10)
    at Module.load (node:module:658:32)
    at Function.Module._load (node:module:539:12)
    at Module.require (node:module:677:19)
    at require (node:module:791:16)
    at Object.<anonymous> (file:///Users/marvinh/dev/test/deno-peer-deps2/node_modules/.deno/elysia@0.7.29_1/node_modules/elysia/dist/cjs/index.js:16:23)
dsherret commented 7 months ago

Looking at the deno info output, these are the duplicate packages:

The npm:/elysia@0.7.29_@sinclair+typebox@0.31.17 is duplicated because it's found under npm:/@bogeychan/elysia-polyfills@0.6.1/deno/index.js, which does not define a dependency on openapi-types. However, elysia is also a peer dependency of @elysiajs/swagger, which does have a dependency on openapi-types. This causes a duplication of the dependency.

So, a workaround is to define a dependency on openapi-types at the top level, by adding this import statement:

// run `rm deno.lock` after doing this
import "npm:openapi-types@12.1.3";