Skip to content

Commit

Permalink
feat(esm api): register to return a namespaced import() method
Browse files Browse the repository at this point in the history
  • Loading branch information
privatenumber committed May 11, 2024
1 parent fbcbbcc commit 53bb4aa
Show file tree
Hide file tree
Showing 13 changed files with 420 additions and 242 deletions.
34 changes: 33 additions & 1 deletion docs/.vitepress/config.ts
Expand Up @@ -54,11 +54,43 @@ export default defineConfig({
{ text: 'Scripts', link: '/scripts' },
]
},
{
text: 'Node.js API',
base: '/node',
items: [
{
text: 'Global enhancement',
link: '/',
items: [
{
text: 'CommonJS only',
link: '/cjs'
},
{
text: 'Module only',
link: '/esm'
},
],
},
{
text: 'Isolated methods',
items: [
{
text: 'tsImport()',
link: '/ts-import'
},
{
text: 'tsx.require()',
link: '/tsx-require'
},
],
},
],
},
{
text: 'Integration',
items: [
{ text: 'VSCode', link: '/vscode' },
{ text: 'Node.js', link: '/node' },
]
},
{
Expand Down
197 changes: 0 additions & 197 deletions docs/node.md

This file was deleted.

48 changes: 48 additions & 0 deletions docs/node/cjs.md
@@ -0,0 +1,48 @@

# Only CommonJS mode

Node.js runs files in CommonJS mode when the file extension is `.cjs` (or `.cts` if TypeScript), or `.js` when [`package.json#type`](https://nodejs.org/api/packages.html#type) is undefined or set to `commonjs`.

This section is only for adding tsx in CommonJS mode (doesn't affect `.mjs` or `.mts` files, or `.js` files when `package.js#type` is set to `module`).

::: warning Not for 3rd-party packages
This enhances the entire runtime so it may not be suitable for loading TypeScript files from a 3rd-party package as it may lead to unexpected behavior in user code.

For importing TypeScript files in CommonJS mode without affecting the environment, see [`tsx.require()`](http://localhost:5173/node/tsx-require).
:::

## Command-line API

Pass _tsx_ into the `--require` flag:

```sh
node --require tsx/cjs ./file.ts
```

### `NODE_OPTIONS` environment variable

```sh
NODE_OPTIONS='--require tsx/cjs' npx some-binary
```

## Programmatic API

Load `tsx/cjs` at the top of your entry-file:

```js
require('tsx/cjs')
```

### Registration & Unregistration

To manually register and unregister the tsx enhancement:

```js
const tsx = require('tsx/cjs/api')

// Register tsx enhancement
const unregister = tsx.register()

// Unregister when needed
unregister()
```
90 changes: 90 additions & 0 deletions docs/node/esm.md
@@ -0,0 +1,90 @@
# Only Module mode

Node.js runs files in Module mode when the file extension is `.mjs` (or `.mts` if TypeScript), or `.js` when [`package.json#type`](https://nodejs.org/api/packages.html#type) is set to `module`.

This section is only for adding tsx in Module mode (doesn't affect `.cjs` or `.cts` files, or `.js` files when `package.js#type` is undefined or set to `commonjs`).

::: warning Not for 3rd-party packages
This enhances the entire runtime so it may not be suitable for loading TypeScript files from a 3rd-party package as it may lead to unexpected behavior in user code.

For importing TypeScript files in Module mode without affecting the environment, see the *Scoped registration* section below or [`tsImport()`](http://localhost:5173/node/ts-import).
:::

## Command-line API

```sh
# Node.js v20.6.0 and above
node --import tsx/esm ./file.ts

# Node.js v20.5.1 and below
node --loader tsx/esm ./file.ts
```

### `NODE_OPTIONS` environment variable

```sh
# Node.js v20.6.0 and above
NODE_OPTIONS='--import tsx/esm' npx some-binary

# Node.js v20.5.1 and below
NODE_OPTIONS='--loader tsx/esm' npx some-binary
```

## Programmatic API

### Registration & Unregistration
```js
import { register } from 'tsx/esm/api'

// register tsx enhancement
const unregister = register()

// Unregister when needed
unregister()
```

#### Tracking loaded files
Detect files that get loaded with the `onImport` hook:

```ts
register({
onImport: (file: string) => {
console.log(file)
// file:///foo.ts
}
})
```

#### Tracking loaded files
Detect files that get loaded with the `onImport` hook:

```ts
register({
onImport: (file: string) => {
console.log(file)
// file:///foo.ts
}
})
```

### Scoped registration
If you want to register tsx without affecting the environment, you can add a namespace.

```js
import { register } from 'tsx/esm/api'

// register tsx enhancement
const api = register({
namespace: Date.now().toString()
})

// You get a private `import()` function to load TypeScript files
// Since this is namespaced, it will not cache hit from prior imports
const loaded = await api.import('./file.ts', import.meta.url)

Check warning on line 83 in docs/node/esm.md

View workflow job for this annotation

GitHub Actions / Release

'loaded' is assigned a value but never used

// This is using the same namespace as above, so it will yield a cache hit
const loaded2 = await api.import('./file.ts', import.meta.url)

Check warning on line 86 in docs/node/esm.md

View workflow job for this annotation

GitHub Actions / Release

'loaded2' is assigned a value but never used

// Unregister when needed
api.unregister()
```

0 comments on commit 53bb4aa

Please sign in to comment.