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

初始化

创建项目

bash 复制代码
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"
}
arduino 复制代码
mkdir packages

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

pnpm-workspace.yaml 复制代码
packages:
  - 'packages/*'

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

然后开始构建前后端:

前端使用vite:

bash 复制代码
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

js 复制代码
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 安装依赖

kotlin 复制代码
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

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

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

web:

json 复制代码
{
  "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:

json 复制代码
{
  "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中,这样子模块可以共用:

这样:

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

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

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

json 复制代码
{
  "compilerOptions": {
    "baseUrl": ".", 
    "paths": {
      "@web": ["packages/web/src"],
      "@server": ["packages/server/src"]
    },
  },
}

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

项目规范

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

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

json 复制代码
"scripts": {
    "lint": "eslint --cache --ext .js,.ts,.tsx",
    "format": "prettier --write --cache ."
  },

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

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

根目录运行命令:

css 复制代码
pnpm install eslint-plugin-vue -D --filter web

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

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

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

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

.ignore文件

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

.gitignore 复制代码
dist
node_modules
coverage
pnpm-workspace.yaml
.idea
*.log
.eslintcache

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

.eslintignore 复制代码
node_modules
dist
coverage

创建.prettierignore 这个是prettier

.prettierignore 复制代码
dist
*.md
*.html
pnpm-lock.yaml

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

安装husky依赖并初始化:

csharp 复制代码
// 安装
pnpm i -wD husky
// 初始化
pnpm dlx husky-init

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

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

sh 复制代码
#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"

npm test

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

我们修改一下这个文件:

sh 复制代码
#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"

npm run lint && npm run format

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

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

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

安装lint-staged:

js 复制代码
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:

package.json

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

然后提交一下代码:

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

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

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

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

安装依赖:

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

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

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的钩子。

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

来个正经的:

没有问题:

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

git地址:github.com/bsuooo/vn

相关推荐
老码沉思录1 小时前
写给初学者的React Native 全栈开发实战班
javascript·react native·react.js
我不当帕鲁谁当帕鲁1 小时前
arcgis for js实现FeatureLayer图层弹窗展示所有field字段
前端·javascript·arcgis
那一抹阳光多灿烂1 小时前
工程化实战内功修炼测试题
前端·javascript
红中马喽4 小时前
JS学习日记(webAPI—DOM)
开发语言·前端·javascript·笔记·vscode·学习
Black蜡笔小新5 小时前
网页直播/点播播放器EasyPlayer.js播放器OffscreenCanvas这个特性是否需要特殊的环境和硬件支持
前端·javascript·html
Dread_lxy6 小时前
vue 依赖注入(Provide、Inject )和混入(mixins)
前端·javascript·vue.js
奔跑草-7 小时前
【前端】深入浅出 - TypeScript 的详细讲解
前端·javascript·react.js·typescript
羡与8 小时前
echarts-gl 3D柱状图配置
前端·javascript·echarts
前端郭德纲8 小时前
浏览器是加载ES6模块的?
javascript·算法
JerryXZR8 小时前
JavaScript核心编程 - 原型链 作用域 与 执行上下文
开发语言·javascript·原型模式