序
为什么要自己搭建项目 ?
这个事情起始于前两天给团队写一个脚手架工具,这段时间刚做做完一个系统,是团队第一个正式意义上的全栈项目;团队有自己的前端脚手架,但是没有后端脚手架,所以想着给团队写一个后端脚手架工具,这样团队在开展后续的全栈项目时可以使用脚手架构建项目,避免了重复搭建项目初始架构的大量工作,成员直接编写业务代码即可。
前两天用 JavaScript 完成了脚手架的初版,开发过程中发现没一点代码提示,很不舒服,而且这样的代码不利于后续的迭代和维护。
所以决定用 typescript 重构一遍,但是官方好像没有提供一个合适的脚手架工具,于是就开始自己搭建 typescript 项目;自己搭建最大的好处就是 自主可控,项目中集成了实时编译的开发环境、eslint + prettier 保证代码质量和风格统一、项目构建工具、git 提交信息的规范化,这些都是一个项目最基本和必要的配置。
本来到这里就结束了,但是在后续重构脚手架的过程中发现一个问题,如果每写一个新的 typescript 项目就重复一遍这个搭建流程,比如:今天需要开发一个 npm 包,明天需要开发另外一个脚手架,这好像有点太麻烦了,于是就把整个搭建过程写成了一个脚手架,这样在后续开发的工作中就可以实现一键创建项目,简单、方便、舒爽
从这篇文章中你可以学到什么 ?
- 如何搭建一个基于 typescript 的项目框架
- 在项目中怎么集成 eslint 和 prettier 保证代码质量
- 如何规范化 git 提交信息
- 如何为团队开发自己的脚手架工具(提效)
搭建项目
初始化项目目录
mkdir ts-project && cd ts-project && npm init -y && npm i typescript -D && npx tsc --init
这条命令的意思是在当前目录下创建一个 ts-project 目录,然后进入 ts-project 目录执行 npm init -y 初始话目录产生 package.json 文件,之后运行 npm i typescript -D 在开发环境安装 typescript 包,之后执行 npx tsc --init 生成 tsconfig.json 文件
之后所有的操作都以 ts-project 为根目录
mkdir src && touch src/index.ts
新建 src 目录作为项目的源码目录(开发目录),并在 src 目录下创建 index.ts 文件作为项目的入口文件
设置 tsconfig.json
如果一个目录下存在 tsconfig.json 文件,那就意味着这个目录是 typescirpt 项目的根目录,tsconfig.json 文件中指定了用来编译项目的根文件和编译选项,使用 tsc --init 生成的 tsconfig.json 文件包含了大量的选项,其中大部分都被注释掉了,一般我们只需要配置如下内容即可:
{
"compileOnSave": true,
"compilerOptions": {
"target": "ES2018",
"module": "commonjs",
"moduleResolution": "node",
"experimentalDecorators": true,
"emitDecoratorMetadata": true,
"inlineSourceMap":true,
"noImplicitThis": true,
"noUnusedLocals": true,
"stripInternal": true,
"pretty": true,
"declaration": true,
"outDir": "lib",
"baseUrl": "./",
"paths": {
"*": ["src/*"]
}
},
"exclude": [
"lib",
"node_modules"
]
}
@types/node
npm i @types/node -D
这个是 node.js 的类型定义包
开发环境实时编译
npm i ts-node-dev -D
在 package.json 的 scripts 中增加如下内容
{
"scripts": {
"dev:comment": "启动开发环境",
"dev": "ts-node-dev --respawn --transpile-only src/index.ts"
}
}
执行 npm run dev 即可启动开发环境,并且修改文件时可实时编译
代码质量
代码质量对于一个系统的可维护性、可迭代性至关重要,特别是在多人协作一个大型项目中,如果没有把控代码质量的工具,每人一套编码风格,这样的系统在后期的维护难度可想而知,基本上会成为一个难以迭代升级的祖传系统,除了重写别无他法。
因此控制代码质量的工具应运而生,而 ESLint 当属其中的佼佼者,熬死了各路的竞争者;typescript 之前还在使用 TSLint,但在 2019 年 1 月 官方决定全面采用 ESLint 作为代码检查工具。
ESLint
采用社区的开源配置方案 eslint-config-standard,简单直接,足以 hold 住大部分项目了
npx eslint --init
以上流程走完以后在项目根目录会多出来一个 .eslintrc.js 文件,接下来在 package.json 的 scripts 中增加如下配置
{
"scripts": {
"eslint:comment": "使用 ESLint 检查并自动修复 src 目录下所有扩展名为 .ts 的文件",
"eslint": "eslint --fix src --ext .ts --max-warnings=0"
}
}
Prettier
Perttier 是一个专注于统一代码格式风格的工具,可能有人会疑惑,ESLint 已经能够规范我们的代码,为什么还需要 Prettier ?简单来说是这样的,ESLint 其实有两种类型规则:
- 格式规则:比如 key-spacing、comma-spacing 等
- 质量规则:比如 最常见的 no-var 等
其中 格式规则 主要是控制代码风格,简单理解就是代码看起来好看、易读,而 质量规则 主要是发现代码中存在的潜在 bug 或者可能会制造 bug 的地方,简单来说更多是从语法层面去考虑,比如现在禁止使用 var 声明变量,而 prettier 则是专注于 格式规则,所以在格式方面我们选用更加专业的 Prettier。
如果你同时使用 ESLint 和 Prettier,且在编辑器中配置了 Sava Auto Fix 时,会让你的一键格式化异常痛苦,因为在 格式规则 上有冲突,所以个人建议或者说不喜欢在编辑器中配置 ESLint 和 Prettier,三个原因:
- 不喜欢编码过程被编辑器因为格式检查问题打断
- 通过 git hook 统一处理格式问题很香
- 习惯好,一般编写的代码不存在格式问题,意思是从自身编码习惯触发从根本上解决问题
接下来就开始安装和配置 Prettier
npm i prettier -D
安装 Prettier 所需的依赖,然后在项目目录增加 .prettierrc.js,推荐配置如下:
module.exports = {
// 一行最多 80 字符
printWidth: 80,
// 使用 2 个空格缩进
tabWidth: 2,
// 不使用 tab 缩进,而使用空格
useTabs: false,
// 行尾需要有分号
semi: true,
// 使用单引号代替双引号
singleQuote: true,
// 对象的 key 仅在必要时用引号
quoteProps: 'as-needed',
// jsx 不使用单引号,而使用双引号
jsxSingleQuote: false,
// 末尾使用逗号
trailingComma: 'all',
// 大括号内的首尾需要空格 { foo: bar }
bracketSpacing: true,
// jsx 标签的反尖括号需要换行
jsxBracketSameLine: false,
// 箭头函数,只有一个参数的时候,也需要括号
arrowParens: 'always',
// 每个文件格式化的范围是文件的全部内容
rangeStart: 0,
rangeEnd: Infinity,
// 不需要写文件开头的 @prettier
requirePra