我NodeJS+TypeScript项目的初始配置步骤
关于这篇文章
在使用NodeJS环境进行服务器端应用程序开发时,
以下是向新项目(仓库)引入TypeScript、格式化工具(Prettier)、检查工具(ESLint)和单元测试工具(Jest)的步骤备忘录。
※预计将根据需要进行适当的修改和调整。
操作步骤
生成 package.json
npm init -y
引入TypeScript
安装TypeScript本体和NodeJS内置功能的类型定义包。
npm install --save-dev typescript @types/node
设置 tsconfig.json
使用以下命令将生成带有注释的 tsconfig.json 文件,然后可以更改一些设置。
npx tsc --init
以下是一个配置示例,将源代码放置在 src 目录中,生成物放置在 dist 目录中。
{
"compilerOptions": {
"incremental": true,
"tsBuildInfoFile": "./.tsbuildinfo",
"target": "ES2021",
"lib": ["ES2021"],
"experimentalDecorators": true,
"emitDecoratorMetadata": true,
"module": "commonjs",
"moduleResolution": "node",
"rootDir": "./src",
"baseUrl": "./src",
"paths": {
"~/*": ["./*"]
},
"resolveJsonModule": true,
"allowJs": true,
"checkJs": true,
"outDir": "./dist",
"isolatedModules": true,
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true,
"strict": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"exactOptionalPropertyTypes": true,
"noImplicitReturns": true,
"noFallthroughCasesInSwitch": true,
"noUncheckedIndexedAccess": true,
"noImplicitOverride": true,
"noPropertyAccessFromIndexSignature": true,
"allowUnusedLabels": false,
"allowUnreachableCode": false,
"skipLibCheck": true
},
"include": ["./src"],
"exclude": ["node_modules", "./dist"]
}
“lib”: [“ES2021”],
根据NodeJS的版本进行设置,(当前LTS版本的)NodeJS v16支持ES2021
“experimentalDecorators”: true,
“emitDecoratorMetadata”: true,
如果需要使用装饰器,请将其设为true
“rootDir”: “./src”,
如果源代码放置在src目录内的项目布局,请这样设置
“baseUrl”: “./src”,
“paths”: { “~/”: [“./”] },
路径别名设置。使得任何层级的文件都可以将src/视为~/以便进行import
“outDir”: “./dist”,
已编译的JS输出目录。
为了避免与源代码混合存在于同一目录下,将其输出到dist目录下
注意,在使用webpack或esbuild等捆绑工具时,此设置可能没有效果
“strict”: true,
到
“allowUnreachableCode”: false,
将这些严格的语法检查设置一开始全部启用,只有在出现问题时才禁用它们
请参考官方文档以获得各项目的更详细说明。
添加一种工具,方便在TypeScript开发中快速执行。
npm install --save-dev ts-node ts-node-dev tsconfig-paths
通常情况下,在TypeScript项目中通常会添加以下内容:
ts-node:可以直接运行TS文件的工具
ts-node-dev:在进行代码修改时自动重新启动(watch)的工具,常用于服务器程序开发等
tsconfig-paths:用于在运行时解析路径别名的工具
通过传递 -r tsconfig-paths/register ,可以解析路径别名并执行。
ts-node -r tsconfig-paths/register src/main.ts
ts-node-dev -r tsconfig-paths/register src/main.ts
# パスエイリアスを使用したTSをコンパイルしたJS実行時に
TS_NODE_BASEURL=dist node -r tsconfig-paths/register dist/main.js
在 package.json 的 scripts 中添加
可以将主要脚本注册到 package.json 的 scripts 中,以使用简短的命令 npm run dev 来启动。
"scripts": {
...
+ "dev": "ts-node-dev -r tsconfig-paths/register src/main.ts",
...
},
在中文中導入”格式化程式(Prettier)”。
将格式化工具Prettier添加到项目中。
npm install --save-dev prettier
设置 .prettierrc.js
根据项目规定来更改设定值。
/** @type {import("prettier").Config} */
module.exports = {
printWidth: 120,
tabWidth: 4,
useTabs: false,
semi: true,
singleQuote: false,
quoteProps: "consistent",
jsxSingleQuote: false,
trailingComma: "all",
bracketSpacing: true,
bracketSameLine: false,
arrowParens: "always",
};
/** @type {import(“prettier”).Config} */
module.exports = {
// 单行的最大长度
printWidth: 120,
// 缩进宽度
tabWidth: 4,
// 使用空格作为缩进
useTabs: false,
// 在语句末尾加上分号
semi: true,
// 用双引号包裹字符串字面量
singleQuote: false,
// 在对象字面量的属性名中保持引号的一致性
quoteProps: “consistent”,
// 用双引号包裹JSX属性值
jsxSingleQuote: false,
// 在数组(对象)字面量的末尾属性(元素)后面添加逗号
trailingComma: “all”,
// 在花括号内添加空格
bracketSpacing: true,
// 多行HTML元素和JSX标签的”>”放置在单独的新行中
bracketSameLine: false,
// 始终使用括号括住箭头函数的参数
arrowParens: “always”,
};
※ 更详细的配置项说明请参考官方文档。
添加 package.json 文件中的 scripts 部分
在 package.json 中添加一个只执行检查的 lint 脚本和一个用于进行修正的 fix 脚本。
"scripts": {
...
+ "lint": "prettier -l src",
+ "fix": "prettier -w src",
...
}
引入测试工具(Jest)。
将Jest添加到项目中,并添加ts-jest和类型定义以支持TypeScript。
npm install --save-dev jest @types/jest ts-jest
新增 jest.config.js 設定檔
生成 TypeScript 的配置文件
npx ts-jest config:init
为了让生成的 jest.config.js 支持路径别名,进行如下修改。
const { pathsToModuleNameMapper } = require("ts-jest");
const { loadConfig } = require("tsconfig-paths");
const tsconfig = loadConfig();
/** @type {import('ts-jest/dist/types').InitialOptionsTsJest} */
module.exports = {
preset: "ts-jest",
testEnvironment: "node",
// paths
moduleNameMapper: pathsToModuleNameMapper(tsconfig.paths, {
prefix: tsconfig.absoluteBaseUrl,
}),
};
添加 package.json 文件中的 scripts
可以在 package.json 中添加,以便可以使用 npm run test 运行
(如果不添加选项,可能没有太大意义,因为它比 npx jest 更长…)
"scripts": {
...
+ "test": "jest",
...
}
引入代码检查工具ESLint
添加ESLint
为了支持TypeScript,我们需要添加typescript-eslint。
为了添加import顺序的规则,我们需要添加eslint-plugin-import。
为了禁用与prettier冲突的eslint规则,我们需要添加eslint-config-prettier。
此外,还需要添加eslint-plugin-jest来添加针对jest的规则。
npm install --save-dev eslint \
@typescript-eslint/parser @typescript-eslint/eslint-plugin \
eslint-plugin-import eslint-import-resolver-typescript \
eslint-config-prettier eslint-plugin-jest
新增 .eslintrc.js 設定檔
将每个插件的建议规则放在extends中,以便将不适用或缺失的规则禁用/添加到rules中,以适配项目开发。
/** @type {import("eslint").Linter.Config} */
module.exports = {
env: {
node: true,
commonjs: true,
es2021: true,
jest: true,
},
plugins: [
//
"@typescript-eslint",
"import",
"jest",
],
parser: "@typescript-eslint/parser",
parserOptions: {
project: "./tsconfig.json",
},
settings: {
"import/parsers": {
"@typescript-eslint/parser": [".ts", ".tsx"],
},
"import/resolver": {
typescript: true,
},
},
extends: [
"eslint:recommended",
"plugin:@typescript-eslint/recommended",
"plugin:import/recommended",
"plugin:import/typescript",
"plugin:jest/recommended",
"prettier",
],
rules: {},
};
将ESLint规则添加为示例
从.eslintrc.js文件中摘录rules
// 禁止省略单行if语句的大括号
“curly”: “error”,
// 禁止在if语句中使用else语句,只有在必须使用return时除外
“no-else-return”: “error”,
// 强制使用严格比较
“eqeqeq”: “error”,
// 函数的最大行数(不包括顶层函数)
“max-statements”: [“error”, 40, { ignoreTopLevelFunctions: true }],
// 禁止在一个var/const/let语句中声明多个变量
“one-var”: [“error”, “never”],
添加import规则的示例
从.eslintrc.js文件中摘录rules
// 将import语句放在文件开头
“import/first”: “error”,
// import语句的排序规则
“import/order”: [“error”, {
// 按字母顺序排序
“alphabetize”: { order: “asc”, caseInsensitive: false },
// 按照组别排序 NodeJS内置模块→外部模块→内部模块→上级目录→同级目录
“groups”: [“builtin”, “external”, “internal”, “parent”, “sibling”],
// 在组别之间添加空行
“newlines-between”: “always”,
}]
修改 package.json 文件中的 scripts
使npm run lint命令来执行ESLint的检查
使npm run fix命令来执行ESLint规则违反的修正(仅限自动修复的内容)
"scripts": {
...
- "lint": "prettier -l src",
+ "lint": "prettier -l src && eslint src",
- "fix": "prettier -w src",
+ "fix": "prettier -w src && eslint src --fix",
...
}