If you'd like a more guided walkthrough, see Contributing to a create-typescript-app Repository. It'll walk you through the common activities you'll need to contribute.
After forking the repo from GitHub and installing pnpm:
git clone https://github.com/ < your-name-here > /create-typescript-app
cd create-typescript-app
pnpm install
This repository includes a list of suggested VS Code extensions. It's a good idea to use VS Code and accept its suggestion to install them, as they'll help with development.
Run tsup locally to build source files from src/
into output files in lib/
:
pnpm build
Add --watch
to run the builder in a watch mode that continuously cleans and recreates lib/
as you save files:
pnpm build --watch
Prettier is used to format code. It should be applied automatically when you save files in VS Code or make a Git commit.
To manually reformat all files, you can run:
pnpm format --write
This package includes several forms of linting to enforce consistent code quality and styling. Each should be shown in VS Code, and can be run manually on the command-line:
pnpm lint
(ESLint with typescript-eslint): Lints JavaScript and TypeScript source filespnpm lint:knip
(knip): Detects unused files, dependencies, and code exportspnpm lint:md
(Markdownlint): Checks Markdown source filespnpm lint:packages
(pnpm dedupe --check): Checks for unnecessarily duplicated packages in thepnpm-lock.yml
filepnpm lint:spelling
(cspell): Spell checks across all source files
Read the individual documentation for each linter to understand how it can be configured and used best.
For example, ESLint can be run with --fix
to auto-fix some lint rule complaints:
pnpm run lint --fix
Note that you'll likely need to run pnpm build
before pnpm lint
so that lint rules which check the file system can pick up on any built files.
Vitest is used for tests. You can run it locally on the command-line:
pnpm run test
Add the --coverage
flag to compute test coverage and place reports in the coverage/
directory:
pnpm run test --coverage
Note that console-fail-test is enabled for all test runs.
Calls to console.log
, console.warn
, and other console methods will cause a test to fail.
This repository includes a VS Code launch configuration for debugging unit tests. To launch it, open a test file, then run Debug Current Test File from the VS Code Debug panel (or press F5).
You should be able to see suggestions from TypeScript in your editor for all open files.
However, it can be useful to run the TypeScript command-line (tsc
) to type check all files in src/
:
pnpm tsc
Add --watch
to keep the type checker running in a watch mode that updates the display as you save files:
pnpm tsc --watch
This repository includes a VS Code launch configuration for debugging. Depending upon the type of usage, it can include debugging for unit tests and for executable (or "bin") apps.
To debug a unit test, open a test file, then run Debug Current Test File from the VS Code Debug panel (or press F5).
To debug a bin
app, add a breakpoint to your code, then run Debug Program from the VS Code Debug panel (or press F5).
As described in the README.md
file and docs/
, this template repository comes with three scripts that can set up an existing or new repository.
Each follows roughly the same general flow:
bin/index.ts
usesbin/mode.ts
to determine which of the three setup scripts to runreadOptions
parses in options from local files, Git commands, npm APIs, and/or files on diskrunOrRestore
wraps the setup script's main logic in a friendly prompt wrapper- The setup script wraps each portion of its main logic with
withSpinner
- Each step of setup logic is generally imported from within
src/steps
- Each step of setup logic is generally imported from within
- A call to
outro
summarizes the results for the user
Warning Each setup script overrides many files in the directory they're run in. Make sure to save any changes you want to preserve before running them.
📝 See
docs/Creation.md
for user documentation on the creation script.
This template's "creation" script is located in src/create/
.
You can run it locally with node bin/index.js --mode create
.
Note that files need to be built with pnpm run build
beforehand.
You can run the end-to-end test for creation locally on the command-line.
Note that the files need to be built with pnpm run build
beforehand.
pnpm run test:create
That end-to-end test executes script/create-test-e2e.ts
, which:
- Runs the creation script to create a new
test-repository
child directory and repository, capturing code coverage - Asserts that commands such as
build
andlint
each pass
The pnpm run test:create
script is run in CI to ensure that templating changes are in sync with the template's actual files.
See .github/workflows/test-create.yml
.
📝 See
docs/Initialization.md
for user documentation on the initialization script.
This template's "initialization" script is located in src/initialize/
.
You can run it locally with pnpm run initialize
.
It uses tsx
so you don't need to build files before running.
pnpm run initialize
You can run the end-to-end test for initializing locally on the command-line.
Note that files need to be built with pnpm run build
beforehand.
pnpm run test:initialize
That end-to-end test executes script/initialize-test-e2e.ts
, which:
- Runs the initialization script using
--skip-github-api
and other skip flags - Checks that the local repository's files were changed correctly (e.g. removed initialization-only files)
- Runs
pnpm run lint:knip
to make sure no excess dependencies or files were left over - Resets everything
- Runs initialization a second time, capturing test coverage
The pnpm run test:initialize
script is run in CI to ensure that templating changes are in sync with the template's actual files.
See .github/workflows/test-initialize.yml
.
📝 See
docs/Migration.md
for user documentation on the migration script.
This template's "migration" script is located in src/migrate/
.
Note that files need to be built with pnpm run build
beforehand.
To test out the script locally, run it from a different repository's directory:
cd ../other-repo
node ../create-typescript-app/bin/migrate.js
The migration script will work on any directory. You can try it out in a blank directory with scripts like:
cd ..
mkdir temp
cd temp
node ../create-typescript-app/bin/migrate.js
💡 Seeing
Oh no! Running the migrate script unexpectedly modified:
errors? Unexpected File Modifications covers that below.
You can run the end-to-end test for migrating locally on the command-line:
pnpm run test:migrate
That end-to-end test executes script/migrate-test-e2e.ts
, which:
- Runs the migration script using
--skip-github-api
and other skip flags, capturing code coverage - Checks that only a small list of allowed files were changed
- Checks that the local repository's files were changed correctly (e.g. removed initialization-only files)
The pnpm run test:migrate
script is run in CI to ensure that templating changes are in sync with the template's actual files.
See .github/workflows/test-migrate.yml
.
Tip: if the migration test is failing in CI and you don't see any errors, try downloading the full logs.
The migration test uses the Vitest file snapshot in script/__snapshots__/migrate-test-e2e.ts.snap
to store expected differences to this repository after running the migration script.
The end-to-end migration test will fail any changes that don't keep the same differences in that snapshot.
You can update the snapshot file by:
- Committing any changes to your local repository
- Running
pnpm i
andpnpm build
if any updates have been made to thepackage.json
orsrc/
files, respectively - Running
pnpm run test:migrate -u
to update the snapshot
At this point there will be some files changed:
script/__snapshots__/migrate-test-e2e.ts.snap
will have updates if any files mismatched templates- The actual updated files on disk will be there too
If the snapshot file changes are what you expected, then you can commit them. The rest of the file changes can be reverted.
🚀 Feature: Add a way to apply known file changes after migration #1184 tracks turning the test snapshot into a feature.
The migration test also asserts that no files were unexpectedly changed. If you see a failure like:
Oh no! Running the migrate script unexpectedly modified:
- ...
...then that means the file generated from templates differs from what's checked into the repository. This is most often caused by changes to templates not being applied to checked-in files too.
Templates for files are generally stored in [src/steps/writing/creation
] under a path roughly corresponding to the file they describe.
For example, the template for tsup.config.ts
is stored in src/steps/writing/creation/createTsupConfig.ts
.
If the createTsupConfig
function were to be modified without an equivalent change to tsup.config.ts
-or vice-versa- then the migration test would report:
Oh no! Running the migrate script unexpectedly modified:
- tsup.config.ts