privatenumber / tsx

⚡️ TypeScript Execute | The easiest way to run TypeScript in Node.js
https://tsx.is
MIT License
9.43k stars 144 forks source link

document `require('tsx/cjs')` usage #496

Closed mmkal closed 6 months ago

mmkal commented 6 months ago

Hi - I've been gradually moving over from ts-node, and one scenario I noticed wasn't in the readme was an equivalent to `require('ts-node/register'). Useful when you need to use typescript modules from a commonjs script. For example, for a CLI tool like ESLint that doesn't support typescript configs. You can write an eslint.config.js like this:

require('tsx/cjs')

module.exports = [
  require('./src/config1.ts'),
  require('./src/config2.ts'),
]

This is much easier than figuring out have to run eslint via tsx or pass in a --require CLI argument. You can just run ./node_modules/.bin/eslint normally.

privatenumber commented 6 months ago

I think that's kind of a hacky solution to your problem because you're sneaking it in via config—exploiting something that's only be available if the CLI accepts a JS config. This may be unexpected or easy to miss for others trying to understand what's happening and why.

Node actually offers an official API for this that works for any CLI (which is documented), even if it doesn't offer a JS config:

NODE_OPTIONS='--require tsx/cjs' eslint .

Or

NODE_OPTIONS='--import tsx' eslint .
mmkal commented 6 months ago

I think they're about equal in hackiness. When using a js config (note that eslint only supports js flat config now), it's better to have a config file that just works rather than require a special environment variable that some might forget to use, or forget to remove when it's no longer needed.

Basically I think it's a pretty valid use case, and it's up to end users whether it's better for them. And tsx already supports it, so worth documenting even if you're not convinced by the eslint use case.

Up to you though!

Max10240 commented 6 months ago

Lucky to see this, as far as I'm concerned, this method works very well: I only want to import a ".ts" configuration file into a ".js" file, just like a "ts-config-loader", the only thing I need to do is add this line "require('tsx/cjs')" into the ".js" file. cheer like:

// @filename: foo.config.ts
export default {
  foo: {
  }
} satisfies { foo: unknown }
// @filename: bar.js
require('tsx/cjs');

const CONFIG_PATH = '.../foo.config.ts';
const config = require(CONFIG_PATH); // works well