workers-sdk icon indicating copy to clipboard operation
workers-sdk copied to clipboard

Fix terminal color support

Open brillout opened this issue 1 month ago • 3 comments

Describe the solution

Problem

Logs aren't colored (which makes them quite ugly, imagine Vite's startup log being all monocolor).

Root cause

Coloring libraries (chalk, picocolors, ...) try to detect whether the environment supports colors. These test are failing in a workerd context (@cloudflare/vite-plugin).

Test examples: https://github.com/alexeyraspopov/picocolors/blob/0e7c4af2de299dd7bc5916f2bddd151fa2f66740/picocolors.js#L2-L4

Any recommendations to fix the issue? How can I update the test of my favorite coloring library to make it work?

AFAICT the best would be that @cloudflare/vite-plugin sets process.stdout.isTTY and/or process.env.TERM like Node.js does.

brillout avatar Dec 10 '25 15:12 brillout

I think this is more than one issue. If you're seeing the Vite logs without color that is different, because those run in Node. If it's about logs from the worker code then that would be this issue.

ascorbic avatar Dec 12 '25 11:12 ascorbic

It's logs coming from worker code. (I only mentioned the Vite startup log as a vivid example of how missing colors can degrade DX — that log does print in color since it runs in Node.js, as you pointed out.)

A workaround would be for Vike (the Vite-based framework we're building) to statically replace process.env.{isTTY,TERM}, but I guess it would be better if the issue is fixed on Cloudflare's side.

brillout avatar Dec 12 '25 11:12 brillout

Setting process.env.FORCE_COLOR works for picocolors. The problem for chalk is that process.stdout is not a TTY in workerd, so it won't report as such.

ascorbic avatar Dec 12 '25 12:12 ascorbic

Hm, I see. Indeed, it seems like FORCE_COLOR is the only option here.

@cloudflare/vite-plugin could (and should AFAICT) set FORCE_COLOR to true in dev and preview.

brillout avatar Dec 14 '25 18:12 brillout

Yes, I think that would be a good idea for dev at least. What do you think, @jamesopstad?

ascorbic avatar Dec 15 '25 09:12 ascorbic

Not sure we could do this for preview because process.env is only defined when nodejs_compat is enabled. I think we could statically replace the value in dev though. Would that be OK?

jamesopstad avatar Dec 15 '25 14:12 jamesopstad

👍 Makes sense

brillout avatar Dec 15 '25 15:12 brillout

This is harder than I hoped because picocolors doesn't read FORCE_COLOR from process.env.FORCE_COLOR but instead stores process.env in an env variable first:

https://github.com/alexeyraspopov/picocolors/blob/0e7c4af2de299dd7bc5916f2bddd151fa2f66740/picocolors.js#L4

This means you can't statically replace it using define.

jamesopstad avatar Dec 15 '25 17:12 jamesopstad

Maybe a new flag nodejs_compat_light that is true by default would be a good compromise.

brillout avatar Dec 15 '25 18:12 brillout

In the meantime, we implemented this workaround on our side.

brillout avatar Dec 16 '25 13:12 brillout

This is harder than I hoped because picocolors doesn't read FORCE_COLOR from process.env.FORCE_COLOR but instead stores process.env in an env variable first:

https://github.com/alexeyraspopov/picocolors/blob/0e7c4af2de299dd7bc5916f2bddd151fa2f66740/picocolors.js#L4

This means you can't statically replace it using define.

This is a really bad approach too, because lots of tooling replaces env vars statically too.

ascorbic avatar Dec 16 '25 14:12 ascorbic