Usage
October 13, 2021 · View on GitHub
There are a number of ways you can use tsm in your project:
- As a
nodeCLI replacement - As a CommonJS
--requirehook - As an ESM
--loader - As a shell shebang interpreter
CLI
Examples
# run a file
$ tsm server.tsx
# run a file w/ Node flags
# NOTE: flags are forwarded to `node` directly
$ tsm main.ts --trace-warnings
# run a file w/ ENV variables
# NOTE: any ENV is forwarded to `node` directly
$ NO_COLOR=1 PORT=8080 tsm main.ts
# use npx/pnpx with tsm
$ pnpx tsm server.tsx
$ npx tsm server.tsx
Require Hook
The --require hook has existed for a very long time and many tools throughout the ecosystem support/integrate with this feature. However, not every tool – so please consult with your tools' documentation to see if they support a -r/--require flag.
Background: Essentially, the
--require/-rhook subjects anyrequire()d file to additional and/or custom transformation(s). Even though this works on a per-extension basis, it can be quite costly (performance-wise) and there is discouraged; however, for tools liketsm, it's still valuable.
A configuration file is still auto-loaded (if exists) when using --require tsm or -r tsm.
Examples
# node with require hook(s)
$ node --require tsm server.tsx
$ node -r dotenv/register -r tsm server.tsx
# external tool with require hook support
$ uvu -r tsm packages tests
$ uvu --require tsm
Loader Hook
The --loader hook is ESM's version of the --require hook. A loader is only applied to file(s) loaded through import or import() – anything loaded through require is ignored by the loader.
Important: ESM loaders are experimental and will be redesigned. tsm will conform to new design(s) as the feature stabilizes.
You may use --loader tsm or --experimental-loader tsm anywhere that supports ESM loaders. At time of writing, this seems to be limited to node itself.
A configuration file is still auto-loaded (if exists) when using --loader tsm.
Examples
# run node with tsm loader
$ node --loader tsm server.tsx
$ node --experimental-loader tsm main.ts
Shell / Shebang
If you have tsm installed globally on your system, you may write shell scripts with tsm as the interpreter. Here's an example:
// 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:
$ 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.
--#!/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:
$ chmod +x example.ts
At this point, you can run the file directly in your terminal:
$ ./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
ExperimentalWarningtext is from the--trace-warningsargument. This flag is forwarded tonode, which prints this output natively.