denoland / deno

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

Support npm:pm2 #16753

Open bartlomieju opened 1 year ago

bartlomieju commented 1 year ago
    > @iugo how is it same error? What command are you trying to run?

run command deno run -A npm:pm2 --help.

same error, error info is x.y.z is not a function.

Originally posted by @iugo in https://github.com/denoland/deno/issues/16679#issuecomment-1322852714

khrj commented 1 year ago

Min. example

import chalk from "npm:chalk@3"
console.log(chalk.bold.green("Hello"))

Errors:

error: Uncaught TypeError: chalk.bold.green is not a function
console.log(chalk.bold.green("Hello"))
                       ^
khrj commented 1 year ago

The same issue is also present when using createRequire

image

khrj commented 1 year ago

I've dissected through the code for chalk v3 and have managed to get pure JS (no deps) code that works in node, but fails in Deno. I'm not completely sure yet but it seems like Node is handling object prototypes differently from Deno, I'll try to get a cleaner example and then post it here

khrj commented 1 year ago

Note that the code works in node and not in Deno even when not using npm specifiers / createRequire, so this isn't an issue with the npm compatibility layer (or std/node)

khrj commented 1 year ago

Duplicate of https://github.com/denoland/deno/issues/13321

bartlomieju commented 1 year ago

If this is because of chalk@3 then it's because of missing "proto" that Deno doesn't support and will not in the future. So the best bet is to ask pm2 maintainers to update their dependencies.

khrj commented 1 year ago

Yes, it is because of that -- is there no chance of implementing __proto__ to internally call Object.setPrototypeOf? If not for Deno modules, at least for npm specifiers to not break existing modules.

I've run grep through the node_modules of the top 10 packages on npm and nearly all of them have .__proto__ somewhere.

iuioiua commented 1 year ago

FYI, @khrj is aiming to fix this in https://github.com/Unitech/pm2/pull/5489

khrj commented 1 year ago

Note that even after proto is fixed, pm2 will still be broken by #16784

lino-levan commented 4 months ago

pm2 now works with unsafe proto!

image
bartlomieju commented 4 months ago

This still doesn't work for me. It appears that we're not correctly handling "ipc" option in child_process module in new ChildProcess():

Spawning PM2 daemon with pm2_home=/Users/ib/.pm2
spawning
caught error Error: Not implemented: toDenoStdio pipe=string (ipc)
    at notImplemented (ext:deno_node/_utils.ts:27:9)
    at toDenoStdio (ext:deno_node/internal/child_process.ts:379:5)
    at new ChildProcess (ext:deno_node/internal/child_process.ts:197:16)
    at Object.spawn (node:child_process:192:10)
    at module.exports.Client.launchDaemon (file:///Users/ib/Library/Caches/deno/npm/registry.npmjs.org/pm2/5.3.1/lib/Client.js:256:40)
    at file:///Users/ib/Library/Caches/deno/npm/registry.npmjs.org/pm2/5.3.1/lib/Client.js:104:10
    at file:///Users/ib/Library/Caches/deno/npm/registry.npmjs.org/pm2/5.3.1/lib/Client.js:321:14
    at Array.processTicksAndRejections (ext:deno_node/_next_tick.ts:37:11)
    at eventLoopTick (ext:core/01_core.js:166:29)
error: Uncaught TypeError: Cannot read properties of undefined (reading 'unref')
    at ChildProcess.unref (ext:deno_node/internal/child_process.ts:323:19)
    at module.exports.Client.launchDaemon (file:///Users/ib/Library/Caches/deno/npm/registry.npmjs.org/pm2/5.3.1/lib/Client.js:274:9)
    at file:///Users/ib/Library/Caches/deno/npm/registry.npmjs.org/pm2/5.3.1/lib/Client.js:104:10
    at file:///Users/ib/Library/Caches/deno/npm/registry.npmjs.org/pm2/5.3.1/lib/Client.js:321:14
    at Array.processTicksAndRejections (ext:deno_node/_next_tick.ts:37:11)
    at eventLoopTick (ext:core/01_core.js:166:29)

CC @littledivy is it something you could look at? Since we already support IPC in subprocesses it feels like there's something misconfigured that makes it crash.

littledivy commented 4 months ago

@bartlomieju I'm not getting the IPC error. It fails on .unref

$ deno run -A --unstable-unsafe-proto npm:pm2 --help
[PM2] Spawning PM2 daemon with pm2_home=/home/divy/.pm2
error: Uncaught TypeError: Cannot read properties of undefined (reading 'unref')
    at ChildProcess.unref (ext:deno_node/internal/child_process.ts:221:19)
    at module.exports.Client.launchDaemon (file:///home/divy/.cache/deno/npm/registry.npmjs.org/pm2/5.3.1/lib/Client.js:274:9)
    at file:///home/divy/.cache/deno/npm/registry.npmjs.org/pm2/5.3.1/lib/Client.js:104:10
    at file:///home/divy/.cache/deno/npm/registry.npmjs.org/pm2/5.3.1/lib/Client.js:321:14
    at Array.processTicksAndRejections (ext:deno_node/_next_tick.ts:25:11)
    at eventLoopTick (ext:core/01_core.js:166:29)
bartlomieju commented 4 months ago

@littledivy - correct. I added additional logs to surface that error (the catch handler for when the process is spawned).

littledivy commented 4 months ago

Ah, I see the problem now. Our implementation only supports non-stdio IPC.

We need to implement support for stdio as raw fds and "ipc" in Deno.Command.

const process = new Deno.Command(command, {
  stdout: "ipc",
  // or stdout: 3
}).spawn();
bartlomieju commented 4 months ago

Huh, i thought we already had it. Is it any different than the current IPC support we have?

littledivy commented 2 months ago

This should be straightforward to implement:

littledivy commented 3 weeks ago

stdio IPC support landed. A few more things to solve before this works:

By default, pm2 spawns its daemon using node (hard-coded). The daemon fails to start in non-BYONM context because Node doesn't understand Deno npm resolution.

In BYONM context the daemon spawns but IPC between Deno and Node doesn't work because of implementation differences currently.

We have 2 options: