lukeed / tsm

TypeScript Module Loader
MIT License
1.18k stars 19 forks source link

Is there a way to silence warnings? #12

Open jasonkuhrt opened 2 years ago

jasonkuhrt commented 2 years ago

Is there a way to disable the Node warning?

If so, a mention in the docs would be good I think.

CleanShot 2021-10-16 at 12 31 03@2x
lukeed commented 2 years ago

I thought about silencing them, but the ESM loader API is experimental and may change at any point, so I think for my own sake it's better to surface this warning. It reminds users that this is experimental and that they're actually using native ESM and not something faked.

As for native flags, there aren't any but you can track this issue: https://github.com/nodejs/node/issues/30810

geelen commented 2 years ago

I would disagree, I think the advantage of something like tsm is that you can present a higher-level facade than the ESM modules underneath, and if things change at the low level you can potentially smooth that out for the user.

Might I suggest you capture the first couple of lines output by whatever program you run, compare them to what you expect:

(node:46230) ExperimentalWarning: --experimental-loader is an experimental feature. This feature could change at any time
(Use `node --trace-warnings ...` to show where the warning was created)
(node:46230) DeprecationWarning: Obsolete loader hook(s) supplied and will be ignored: getFormat, transformSource

If the program prints these exact lines, silence them, otherwise print them out (potentially with a message saying something like TSM has been tested on Node versions up to X.Y.Z, you're running A.B.C. If things break, consider using NVM to run a known-good version of Node?

shawn-yee commented 2 years ago

I add a console.clear() at the beginning of the file to clear the warning, but each execution causes a screen flash. So i hope --silent can clear the ExperimentalWarning && DeprecationWarning.

hippotastic commented 2 years ago

I built a quick & effective solution that only filters out the unwanted warnings and keeps all others intact, for those interested.

Add this script to your project - I've named it ./filter-warnings.cjs:

/**
 * When using custom loaders like `tsm` to add TypeScript & module support to scripts,
 * Node.js outputs a known set of warnings, which distract from the actual script output.
 * 
 * By adding `--require=./filter-warnings.cjs` to the `node` or `tsm` args,
 * this script filters those known warnings (but not any others) from the output.
 */

// Remove Node's built-in `warning` listener which outputs all warnings to stderr
process.removeAllListeners('warning');

// Add our own version that skips known warnings
process.on('warning', (warning) => {
  let { name, message } = warning;
  if (name === 'ExperimentalWarning' && message.indexOf('--experimental-loader') > -1)
    return;
  if (name === 'DeprecationWarning' && message.indexOf('Obsolete loader hook') > -1)
    return;

  console.warn(warning);
});

Usage works like this then:

tsm --require=./filter-warnings.cjs ./path-to-your-ts-file.ts

I could imagine that @lukeed could add this script to the tsm package and add the --require=... arg to the node call. If you prefer not to do this by default, you could add an optional arg like --filter-known-warnings to the tsm CLI which enables this feature.

karlhorky commented 1 year ago

There's also tsx, an alternative package to execute TypeScript files, which silences the warnings:

$ yarn tsx index.ts run hackerNews
Hacker News Agent: once

vs tsm:

$ yarn tsm index.ts run hackerNews
(node:59451) ExperimentalWarning: Custom ESM Loaders is an experimental feature. This feature could change at any time
(Use `node --trace-warnings ...` to show where the warning was created)
(node:59451) DeprecationWarning: Obsolete loader hook(s) supplied and will be ignored: getFormat, transformSource
Hacker News Agent: once
lukeed commented 1 year ago

This is unlikely to change as ESM loading is still really busted & variable. For instance, the solutions above wouldn't even work in Node 20.x because ESM loaders now run in a separate thread, so catching/silencing main-thread-process-messages isn't possible within tsm itself. In 20.x (and presumably beyond, who tf knows), controlling/manipulating process can only happen within the main-thread.

lukeed commented 1 year ago

What will get better is the removal of this DeprecationWarning message once tsm raises its minimum Node version support:

(node:38053) DeprecationWarning: Obsolete loader hook(s) supplied and will be ignored: getFormat, transformSource