全栈管理系统项目(1):初始化与规范

初始化

创建项目

npm install pnpm -g

// 切换工作目录 “vn”是我的项目文件夹
cd desktop/workspace/vn/
pnpm init
Wrote to /Users/x/Desktop/workspace/vn/package.json

{
  "name": "vn",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC"
}
mkdir packages

根目录新建pnpm-workspace.yaml文件:

packages:
  - 'packages/*'

这样会将packages下面归纳给到pnpm工作空间进行管理

然后开始构建前后端:

前端使用vite:

cd packages
sudo pnpm create vite@latest

.../Library/pnpm/store/v3/tmp/dlx-7672   |   +1 +
.../Library/pnpm/store/v3/tmp/dlx-7672   | Progress: resolved 1, reused 1, downloaded 0, added 1, done
✔ Project name: … web
✔ Select a framework: › Vue
✔ Select a variant: › TypeScript

Scaffolding project in /Users/x/Desktop/workspace/vn/packages/web...

Done. Now run:

  cd web
  pnpm install
  pnpm run dev

后端使用nest-cli

sudo nest new server
⚡  We will scaffold your app in a few seconds..

? Which package manager would you ❤️  to use? pnpm
CREATE server/.eslintrc.js (663 bytes)
CREATE server/.prettierrc (51 bytes)
CREATE server/README.md (3347 bytes)
CREATE server/nest-cli.json (171 bytes)
CREATE server/package.json (1947 bytes)
CREATE server/tsconfig.build.json (97 bytes)
CREATE server/tsconfig.json (546 bytes)
CREATE server/src/app.controller.ts (274 bytes)
CREATE server/src/app.module.ts (249 bytes)
CREATE server/src/app.service.ts (142 bytes)
CREATE server/src/main.ts (208 bytes)
CREATE server/src/app.controller.spec.ts (617 bytes)
CREATE server/test/jest-e2e.json (183 bytes)
CREATE server/test/app.e2e-spec.ts (630 bytes)

✔ Installation in progress... ☕

🚀  Successfully created project server
👉  Get started with the following commands:

$ cd server
$ pnpm run start


                          Thanks for installing Nest 🙏
                 Please consider donating to our open collective
                        to help us maintain this package.


               🍷  Donate: https://opencollective.com/nest

在根目录中执行pnpm install 安装依赖

cd workspace/vn/
pnpm install
Already up to date
Done in 248ms
sudo pnpm install
Scope: all 3 workspace projects
packages/web                             |  WARN  Moving @vitejs/plugin-vue that was installed by a different package manager to "node_modules/.ignored"
packages/web                             |  WARN  Moving typescript that was installed by a different package manager to "node_modules/.ignored"
packages/web                             |  WARN  Moving vue-tsc that was installed by a different package manager to "node_modules/.ignored"
packages/web                             |  WARN  Moving vite that was installed by a different package manager to "node_modules/.ignored"
packages/web                             |  WARN  Moving vue that was installed by a different package manager to "node_modules/.ignored"
Packages: +696
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Progress: resolved 730, reused 621, downloaded 75, added 696, done
node_modules/.pnpm/@nestjs+core@10.3.2_@nestjs+common@10.3.2_@nestjs+platform-express@10.3.2_reflect-metadata@0.1.14_rxjs@node_modules/.pnpm/@nestjs+core@10.3.2_@nestjs+common@10.3.2_@nestjs+platform-express@10.3.2_reflect-metadata@0.1.14_rxjs@7.8.1/node_modules/@nestjs/core: Running postinstall script, done in 6.3s
node_modules/.pnpm/esbuild@0.19.12/node_modules/esbuild: Running postinstall script, done in 340ms
Done in 19.7s

然后分别启动两个项目, 没有问题:

全栈管理系统项目(1):初始化与规范

全栈管理系统项目(1):初始化与规范

对比两个子模块的package.json文件:

web:

{
  "name": "web",
  "private": true,
  "version": "0.0.0",
  "type": "module",
  "scripts": {
    "dev": "vite",
    "build": "vue-tsc && vite build",
    "preview": "vite preview"
  },
  "dependencies": {
    "vue": "^3.4.15"
  },
  "devDependencies": {
    "@vitejs/plugin-vue": "^5.0.3",
    "typescript": "^5.2.2",
    "vite": "^5.1.0",
    "vue-tsc": "^1.8.27"
  }
}

server:

{
"name": "server",
"version": "0.0.1",
"description": "",
"author": "",
"private": true,
"license": "UNLICENSED",
"scripts": {
"build": "nest build",
"format": "prettier --write \"src/**/*.ts\" \"test/**/*.ts\"",
"start": "nest start",
"start:dev": "nest start --watch",
"start:debug": "nest start --debug --watch",
"start:prod": "node dist/main",
"lint": "eslint \"{src,apps,libs,test}/**/*.ts\" --fix",
"test": "jest",
"test:watch": "jest --watch",
"test:cov": "jest --coverage",
"test:debug": "node --inspect-brk -r tsconfig-paths/register -r ts-node/register node_modules/.bin/jest --runInBand",
"test:e2e": "jest --config ./test/jest-e2e.json"
},
"dependencies": {
"@nestjs/common": "^10.0.0",
"@nestjs/core": "^10.0.0",
"@nestjs/platform-express": "^10.0.0",
"reflect-metadata": "^0.1.13",
"rxjs": "^7.8.1"
},
"devDependencies": {
"@nestjs/cli": "^10.0.0",
"@nestjs/schematics": "^10.0.0",
"@nestjs/testing": "^10.0.0",
"@types/express": "^4.17.17",
"@types/jest": "^29.5.2",
"@types/node": "^20.3.1",
"@types/supertest": "^2.0.12",
"@typescript-eslint/eslint-plugin": "^6.0.0",
"@typescript-eslint/parser": "^6.0.0",
"eslint": "^8.42.0",
"eslint-config-prettier": "^9.0.0",
"eslint-plugin-prettier": "^5.0.0",
"jest": "^29.5.0",
"prettier": "^3.0.0",
"source-map-support": "^0.5.21",
"supertest": "^6.3.3",
"ts-jest": "^29.1.0",
"ts-loader": "^9.4.3",
"ts-node": "^10.9.1",
"tsconfig-paths": "^4.2.0",
"typescript": "^5.1.3"
},
"jest": {
"moduleFileExtensions": [
"js",
"json",
"ts"
],
"rootDir": "src",
"testRegex": ".*\\.spec\\.ts$",
"transform": {
"^.+\\.(t|j)s$": "ts-jest"
},
"collectCoverageFrom": [
"**/*.(t|j)s"
],
"coverageDirectory": "../coverage",
"testEnvironment": "node"
}
}

我们可以把公共的比如typescript eslint prettier这些放到最外层的package.json中,这样子模块可以共用:

这样:

{
"name": "vn",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "bsuooo",
"license": "ISC",
"devDependencies": {
"prettier": "^3.0.0",
"@typescript-eslint/eslint-plugin": "^6.0.0",
"@typescript-eslint/parser": "^6.0.0",
"eslint": "^8.42.0",
"eslint-config-prettier": "^9.0.0",
"eslint-plugin-prettier": "^5.0.0",
"typescript": "^5.1.3"
}
}

我们把项目中的3node_modules都删掉, 然后重新在根目录pnpm install, 执行完后再看node_modules

全栈管理系统项目(1):初始化与规范

共用的依赖已经在最外层了,重启websever也都没有问题。

在根目录创建tsconfig.json文件:

{
"compilerOptions": {
"baseUrl": ".", 
"paths": {
"@web": ["packages/web/src"],
"@server": ["packages/server/src"]
},
},
}

这是我们现在的目录结构:

全栈管理系统项目(1):初始化与规范

项目规范

我们把nest生成的eslintrc.jsprettier放到根目录,与web端共用。

同时把格式化脚本放到根目录package.jsonscript中:

"scripts": {
"lint": "eslint --cache --ext .js,.ts,.tsx",
"format": "prettier --write --cache ."
},

这样只需要在最外层执行一次命令就可以覆盖整个项目。

但是针对vue项目,eslint是有特殊插件的,这个插件只有web目录使用,所以我们只需要在web中安装。

根目录运行命令:

pnpm install eslint-plugin-vue -D --filter web

然后在/packages/web目录下创建.eslintrc.js:

module.exports = {
extends: ['plugin:vue/vue3-essential'],
plugins: ['vue'],
};

这时还需要把webpackage.json中的module改为commonjs

这样eslint就没问题了(不生效可以reload一下vscode)

.ignore文件

创建.gitignore文件,这个文件可以过滤一些我们不想要托管到git的目录或文件,比如node_modules或者打包后的dist等。

dist
node_modules
coverage
pnpm-workspace.yaml
.idea
*.log
.eslintcache

创建.eslintignore,这个文件和过滤不需要eslint检查的目录或文件。

node_modules
dist
coverage

创建.prettierignore 这个是prettier

dist
*.md
*.html
pnpm-lock.yaml

然后我们想每次代码提交到git前,自动执行一次eslint的检查,并使用prettier格式化代码风格。这个就需要使用到huskylint-staged

安装husky依赖并初始化:

// 安装
pnpm i -wD husky
// 初始化
pnpm dlx husky-init

pnpm dlx husky-init 会在根目录 创建 .husky文件夹。

其中的pre-commit就是每次git commit前的钩子。

#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"
npm test

这个就表示每次git commit 前会执行一次npm test

我们修改一下这个文件:

#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"
npm run lint && npm run format

现在每次git commit时就会运行 检查并格式化代码。

但是这个这样是全量检查,每次执行范围都是全项目,我们想要的肯定是只检查我们修改的内容, 而且我们修改后的代码还在暂存区中放着,并没有直接一起合到commit中。

这个问题使用lint-staged解决:

安装lint-staged:

sudo pnpm i -wD lint-staged
Password:
Packages: +34 -1
++++++++++++++++++++++++++++++++++-
Progress: resolved 764, reused 725, downloaded 5, added 34, done
devDependencies:
- husky 9.0.10
+ husky 8.0.3 (9.0.10 is available)
+ lint-staged 15.2.2
Done in 6.8s

修改pre-commit文件与package.json文件:

pre-commit:

全栈管理系统项目(1):初始化与规范

package.json

全栈管理系统项目(1):初始化与规范

这时我们测试一下,我们随便找个文件删掉一个;

全栈管理系统项目(1):初始化与规范

然后提交一下代码:

全栈管理系统项目(1):初始化与规范

已经格式化了, 说明我们配置的没问题。

小提示,commit在vscode中可以点这里撤回:

全栈管理系统项目(1):初始化与规范

很多项目不仅仅对代码风格有要求,对commit message也有要求,比如:

全栈管理系统项目(1):初始化与规范

这个我们可以使用commitizen 进行检查:

安装依赖:

pnpm install --wD @commitlint/cli @commitlint/config-conventional

项目根目录中新建commitlint.config.js文件:

module.exports = {
extends: ['@commitlint/config-conventional'],
rules: {
'type-enum': [
2,
'always',
[
'feat', // 新特性
'fix', // 修复
'docs', // 文档
'style', // 风格
'refactor', // 重构
'perf', // 优化
'test', // 测试
'build', // 构建流程、外部依赖变更
'ci', // 修改 CI 配置、脚本
'revert', // 回滚
'chore', // 对构建过程或辅助工具和库的更改
],
],
'type-case': [0],
'type-empty': [0],
'scope-empty': [0],
'scope-case': [0],
'subject-full-stop': [0, 'never'],
'subject-case': [0, 'never'],
'header-max-length': [0, 'always', 72],
},
};

config-conventional 是我们选用的commit规范。

最后执行npx husky add .husky/commit-msg "npx commitlint --edit $1"

创建我们检测coomit-msg的钩子。

测试一下, 随便输一个哈哈哈,报错:

全栈管理系统项目(1):初始化与规范

来个正经的:

全栈管理系统项目(1):初始化与规范

没有问题:

全栈管理系统项目(1):初始化与规范

这样我们的规范设置就差不多了。

git地址:github.com/bsuooo/vn

原文链接:https://juejin.cn/post/7332787416912740371 作者:bsuooo

(0)
上一篇 2024年2月11日 上午10:06
下一篇 2024年2月11日 上午10:17

相关推荐

发表回复

登录后才能评论