This article summaries my practices of how to start a TypeScript project from scratch, including the configurations of code style, code lint, and commit lint.
All the following steps are performed using pnpm and VSCode.
1. TypeScript
First things first, we need to install TypeScript and configure tsconfig.json
.
pnpm tsc --init # create tsconfig.json
Normally the default configuration is good enough. But we can tweak some of them to make our coding more convenient.
First, set our rootDir
and outDir
:
{
"rootDir": "./src",
"outDir": "./dist"
}
Second, set baseUrl
and paths
to enable absolute module lookup:
{
"baseUrl": "./src",
"paths": {
"@/*": ["./*"]
}
}
Why? Imagine that we have a configuration file config.ts
at the root of the project, and lots of modules import it. If a module file someModule.ts
is deeply nested relative to config.ts
, the import path is like ../../../../../config.ts
, which is nasty. Making things worse, if someModule.ts
is moved to a different path, all the relative import paths may not work anymore. With absolute module lookup, the import path can be @/config.ts
, and it’s always valid unless you moved config.ts
. Pretty neat, right?
The TypeScript compiler knows about the configuration and can provide correct type checking. However, after compiling, Node.js does not aware of the mapping. Additionally, we need tsc-alias
to solve this.
2. Prettier
We can use Prettier to ensure our code style. Follow the document to install and configure it.
Here are some additional suggestions.
- For simplicity, don't create
.prettierrc.json
. Instead, we put the configurations inpackage.json
. - We don't need
.prettierignore
. We can limit Prettier to format certain files by usinglint-staged
.
// package.json
{
"lint-staged": {
"src/**/*.(j|t)(s|sx)": "prettier --write --ignore-unknown"
}
}
If you are migrating from an existing project, you can use the following command to format your current codes:
pnpm prettier --write --ignore-unknown src/
3. ESLint
We use ESLint to avoid frequent problems. Follow the document to install and configure it.
Here are some additional suggestions.
- Again, don't create
.eslintrc.json
, put the configuration inpackage.json
. - Follow the instructions of Prettier document to avoid conflicts between ESLint and Prettier.
After the installation, remember to modify the configuration of lint-staged
:
// package.json
{
"lint-staged": {
"src/**/*.(j|t)(s|sx)": [
"eslint --fix",
"prettier --write --ignore-unknown"
]
}
}
Some extra configurations for TypeScript, see the document of typescript-eslint
.
{
"eslintConfig": {
"parserOptions": {
"project": true
}
}
}
If you want to sort imports, the simple-import-sort
plugin is easier to use compared with the integrated rule of ESLint.
If you are migrating from an existing project, you can use the following command to lint your current codes:
pnpm eslint --fix src/
4. Commit Lint
commitlint
is used for making the format of our commit messages consistent. Follow the document to install and configure it.
5. Jest Configuration
We need ts-jest
to make Jest work with TypeScript. See the document of Jest and ts-jest.
6. package.json
Scripts
We can add some scripts in package.json
for convince:
// package.json
{
"scripts": {
"watch": "tsc --watch",
"build": "tsc",
"test": "jest -o --passWithNoTests"
}
}
By the way, the npm script of husky
introduces error when you install dependencies with pnpm i -P
. We can replace it to avoid the error:
// package.json
{
"scripts": {
"prepare": "test -d node_modules/husky && husky install || echo \"husky is not installed\""
}
}