This guide is best-effort and will be improved as necessary.
We use npm scripts for building, testing, and linting. Read the scripts to become familiar with our build process. The big ones are:
npm install
npm run build
npm run test-local
npm run lint-fix
npm prepare
is maintained so that anyone can install ts-node
from git, which is useful for testing experimental branches and unreleased features.
Source lives in src
and is compiled to dist
. Some shim files live outside of src
so that they can be imported at
certain paths. For example, to allow users to import ts-node/register
, we have register/index.js
which is a shim to
compiled code in dist
.
dist-raw
is for larger chunks of code which are not compiled nor linted because they have been copy-pasted from node
's source code.
Test cases are declared in src/test/*.spec.ts
, and test fixtures live in ./tests
. They can be run with npm run test-local
.
To run a subset of tests:
# Use ava's --match flag to match the name of a test or suite
# https://github.com/avajs/ava/blob/main/docs/05-command-line.md
# Don't forget the * wildcards
npm run test-local -- --match '*esm loader*'
Tests are run with AVA, but using a custom wrapper API to enable some TS-friendly features and grouped test suites.
The tests npm pack
ts-node into a tarball and npm install
it into ./tests/node_modules
. This makes ./tests
a better testing environment
because it more closely matches the end-user's environment. Complex require()
/ import
/ --require
/ --loader
invocations behave
the way they would in a users's project.
Historically, it has been difficult to test ts-node in-process because it mutates the node environment: installing require hooks, stack trace formatters, etc.
nyc
, ava
, and ts-node
all mutate the node environment, so it is tricky to setup and teardown individual tests in isolation, because ts-node's hooks need to be
reset without disturbing nyc
or ava
hooks. For this reason, many tests are integration style, spawning ts-node's CLI in an external process, asking it to
execute one of the fixture projects in ./tests
.
Over time, I've gradually added setup and teardown logic so that more components can be tested in-process.
We have a debug configuration for VSCode.
- Open a
*.spec.ts
so it is the active/focused file. - (optional) set breakpoints.
- Invoke debugger with F5.
Note that some tests might misbehave in the debugger. REPL tests in particular. I'm not sure why, but I think it is related to how console
does not write to
stdout when in a debug session.
Documentation is written in markdown in website/docs
and rendered into a website by Docusaurus. The README is also generated from these markdown files.
To edit documentation, modify the markdown files in ./website/docs
and the sidebar declaration in ./website/sidebars.js
Docs for the latest stable release live in a docs
branch. The "Edit this page" links on the website link to the docs
branch so that the website can be improved in parallel with new feature work.
Docs changes for unreleased features are merged to main
in the same PR which implements the feature, adds tests, etc.
When we release a new version, we merge main
with docs
, unifying the two.
cd ./website
yarn
yarn start
# Will host live website locally
yarn build-readme # will rebuild the README.md
This site was used to generate the favicon from a high-res PNG export of the SVG. https://realfavicongenerator.net/
We publish using np
: https://npm.im/np
- Merge
docs
intomain
using a pull request, ensuring a consistent squash-merge - Rebuild the README (see instructions above, necessary because npmjs.com renders the readme)
- (optional) Update the api-extractor report; check for unexpected changes. See below
- Publish with
np
- Add changelog to the Github Release; match formatting from previous releases
- Move
docs
branch to head ofmain
- this rebuilds the website
git push --force origin main:docs
- avoids merge messiness due to earlier squash-merge from
docs
tomain
- If tsconfig schema has changed, send a pull request to schemastore. Example
npm run api-extractor
will update an API report generated by api-extractor
which may be useful
when generating release notes to detect (breaking) changes in our API surface.
I configured it for my own convenience; it is not a necessary part of our development process.