Skip to content

Latest commit

 

History

History
276 lines (183 loc) · 10.7 KB

DEVELOPMENT.md

File metadata and controls

276 lines (183 loc) · 10.7 KB

Development

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.

Building

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

Formatting

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

Linting

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 files
  • pnpm lint:knip (knip): Detects unused files, dependencies, and code exports
  • pnpm lint:md (Markdownlint): Checks Markdown source files
  • pnpm lint:packages (pnpm dedupe --check): Checks for unnecessarily duplicated packages in the pnpm-lock.yml file
  • pnpm 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.

Testing

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.

Debugging Tests

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).

Type Checking

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

Debugging

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.

Unit Tests

To debug a unit test, open a test file, then run Debug Current Test File from the VS Code Debug panel (or press F5).

bin Apps

To debug a bin app, add a breakpoint to your code, then run Debug Program from the VS Code Debug panel (or press F5).

Setup Scripts

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:

  1. bin/index.ts uses bin/mode.ts to determine which of the three setup scripts to run
  2. readOptions parses in options from local files, Git commands, npm APIs, and/or files on disk
  3. runOrRestore wraps the setup script's main logic in a friendly prompt wrapper
  4. The setup script wraps each portion of its main logic with withSpinner
    • Each step of setup logic is generally imported from within src/steps
  5. 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.

The Creation Script

📝 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.

Testing the Creation Script

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:

  1. Runs the creation script to create a new test-repository child directory and repository, capturing code coverage
  2. Asserts that commands such as build and lint 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.

The Initialization Script

📝 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

Testing the Initialization Script

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:

  1. Runs the initialization script using --skip-github-api and other skip flags
  2. Checks that the local repository's files were changed correctly (e.g. removed initialization-only files)
  3. Runs pnpm run lint:knip to make sure no excess dependencies or files were left over
  4. Resets everything
  5. 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.

The Migration Script

📝 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

Testing the Migration Script

💡 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:

  1. Runs the migration script using --skip-github-api and other skip flags, capturing code coverage
  2. Checks that only a small list of allowed files were changed
  3. 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.

Migration Snapshot Failures

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:

  1. Committing any changes to your local repository
  2. Running pnpm i and pnpm build if any updates have been made to the package.json or src/ files, respectively
  3. 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.

Unexpected File Modifications

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