Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CommonJS register/unregister methods #460

Closed
5 of 6 tasks
privatenumber opened this issue Jan 22, 2024 · 9 comments
Closed
5 of 6 tasks

CommonJS register/unregister methods #460

privatenumber opened this issue Jan 22, 2024 · 9 comments
Labels
enhancement New feature or request pending triage

Comments

@privatenumber
Copy link
Owner

privatenumber commented Jan 22, 2024

Precheck

  • I searched existing issues before opening this one to avoid duplicates
  • I understand tsx aims for TypeScript parity and will not support arbitrary Node.js enhancements
  • This request cannot be made to Node.js directly, and is specific to tsx
  • I understand this form is not for addressing a bug or seeking help

Feature request

  • register / unregister methods for the CommonJS API
  • An API to "require" a TypeScript module without affecting the global register
  • The API should also offer insight into files loaded for the user to include them in the dependency tracker (e.g. watcher)

Motivations

postcss/postcss-load-config#249 (comment)
tailwindlabs/tailwindcss#12506

Alternatives

No response

Additional context

No response

Contributions

  • I plan to open a pull request for this issue
  • I plan to make a financial contribution to this project
@privatenumber privatenumber added enhancement New feature or request pending triage labels Jan 22, 2024
@gajus

This comment was marked as off-topic.

@privatenumber
Copy link
Owner Author

privatenumber commented Apr 30, 2024

I'm currently implementing this via https://github.com/pvtnbr/tsx/pull/3

The usage will look like this:

import { require } from 'tsx/cjs/api';

// Instead of `createRequire(import.meta.url)`, you can pass `import.meta.url` or `__filename` as the second argument
const loaded = require('./file', import.meta.url);

@brc-dd

RE: postcss/postcss-load-config#249 (comment)

Seems it's possible to detect what files were loaded via the CommonJS graph already. What do you think of this approach?

// To detect watch files, we can parse the CommonJS module graph
const resolvedPath = require.resolve('./file', import.meta.url);

// User-land code
const collectDependencies = (
	module,
) => [
	module.filename,
	...module.children.flatMap(collectDependencies)
];
console.log(collectDependencies(require.cache[resolvedPath]));

@brc-dd
Copy link
Sponsor Contributor

brc-dd commented Apr 30, 2024

Is require.cache part of tsx' API too or is it the native one? Most of the vite projects had went ESM only last year 👀 If it's native one, then I wonder if that works with require returned by createRequire 👀 Also, require in CJS might not be much usable for ESM projects as they need to resolve using ESM's resolution algorithm (i.e. prefer exports.import over exports.require, module over main...). jiti provides this with it's esmResolve option.

@privatenumber
Copy link
Owner Author

Is require.cache part of tsx' API too or is it the native one? Most of the vite projects had went ESM only last year 👀 If it's native one, then I wonder if that works with require returned by createRequire

require.cache is native API, and tsx's require.cache follows the implementation via tsxRequire.cache = Module._cache. The tsx/cjs/api file is CommonJS so it should get loaded fine from an ESM file.

If you'd like to try it out:

npm i 'privatenumber/tsx#npm/cjs-require'

👀 Also, require in CJS might not be much usable for ESM projects as they need to resolve using ESM's resolution algorithm (i.e. prefer exports.import over exports.require, module over main...). jiti provides this with it's esmResolve option.

I plan to explore this separately via #239 but I'm not confident this will be safe yet. Also, I'd like to eventually offer an tsx/esm/api with a custom import() that can load TypeScript which might suit Vite's use-case better. But in the PostCSS use-case (postcss/postcss-load-config#249), I see it's CommonJS so I imagine this should suffice?

@brc-dd
Copy link
Sponsor Contributor

brc-dd commented Apr 30, 2024

Yeah for postcss, watching file is not needed. Simply require would work.

@brc-dd
Copy link
Sponsor Contributor

brc-dd commented Apr 30, 2024

Can you share what's getDependencies in your above code 👀

Ah I think it should be collectDependencies (recursive call)

@privatenumber
Copy link
Owner Author

Yep, just fixed! Sorry

@brc-dd
Copy link
Sponsor Contributor

brc-dd commented Apr 30, 2024

Just tested. Seems to work fine. Also, would it be possible to emit .d.ts files for those 👀

@privatenumber
Copy link
Owner Author

Thanks, I appreciate it!

And yes, good catch!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request pending triage
Projects
None yet
Development

No branches or pull requests

3 participants