Skip to content

Commit

Permalink
chore(docs): include shebang usage instructions/example
Browse files Browse the repository at this point in the history
  • Loading branch information
lukeed committed Oct 10, 2021
1 parent 67600a7 commit 83896bc
Showing 1 changed file with 66 additions and 1 deletion.
67 changes: 66 additions & 1 deletion docs/usage.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
# Usage

There are three ways you can use tsm in your project:
There are a number of ways you can use tsm in your project:

1. As a `node` CLI replacement
2. As a CommonJS [`--require`](https://nodejs.org/api/cli.html#cli_r_require_module) hook
3. As an ESM [`--loader`](https://nodejs.org/api/esm.html#esm_loaders)
4. As a [bash shebang](https://linuxize.com/post/bash-shebang/) interpreter

## CLI

Expand Down Expand Up @@ -64,3 +65,67 @@ A [configuration file](/docs/configuration.md#config-file) is still auto-loaded
$ node --loader tsm server.tsx
$ node --experimental-loader tsm main.ts
```

## Bash / Shebang

If you have `tsm` installed globally on your system, you may write bash scripts with tsm as the interpreter. Here's an example:

```ts
// file: example.ts
#!/usr/bin/env tsm
import { sum } from './math';
import { greet } from './hello';

let [who] = process.argv.slice(2);

greet(who || 'myself');

let answer = sum(11, 31);
console.log('the answer is:', answer);

// file: math.ts
export const sum = (a: number, b: number) => a + b;

// file: hello.ts
export function greet(name: string) {
console.log(`Hello, ${name}~!`);
}
```

> **Important:** These are three separate TypeScript files.
Here, the main `example.ts` file imports/references functionality defined in the two other files. Additionally, the first line within `example.ts` contains a shebang (`#!`) followed by `/usr/bin/env tsm`, which tells the shell to use the `tsm` binary within the user's environment to process this file. Effectively, this means that the shebang is a shortcut for running this in your terminal:

```sh
$ tsm example.ts
```

However, by including the shebang, you are embedding the instructions for _how_ this file should be executed. This also allows you to include additional CLI flags within the shebang, meaning you don't have to redefine or remember them later on. For example, you can forward the `--trace-warnings` argument through tsm, which will always be there whenever the `example.ts` script executes.

```diff
--#!/usr/bin/env tsm
++#!/usr/bin/env tsm --trace-warnings
```

Now, in order to actually execute the `example.ts` script directly, you have to modify its permissions and mark it as executable:

```sh
$ chmod +x example.ts
```

At this point, you can run the file directly in your terminal:

```sh
$ ./example.ts
# ExperimentalWarning: --experimental-loader is an experimental feature. This feature could change at any time
# at emitExperimentalWarning (node:internal/util:227:11)
# at initializeLoader (node:internal/process/esm_loader:54:3)
# at Object.loadESM (node:internal/process/esm_loader:67:11)
# at runMainESM (node:internal/modules/run_main:46:31)
# at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:76:5)
# at node:internal/main/run_main_module:17:47
# Hello, myself~!
# the answer is: 42
```

> **Note:** The large block of `ExperimentalWarning` text is from the `--trace-warnings` argument. This flag is forwarded to `node`, which prints this output natively.

0 comments on commit 83896bc

Please sign in to comment.