00 奇迹项目编码环境搭建
开篇
2023 已经过去了,这一年没做啥事情,感觉最难忘就是这个奇迹项目,公司项目名字不叫奇迹,我也不知道该叫啥,业务是一个海外代充,类似小电商平台,里面商品分类、 SKU、购物车、订单、购买等功能,我觉得这玩意有人用那真是一个奇迹,所以就叫它奇迹代充吧。
项目技术栈选择
这个项目在公司后端由是 java
写的,在这里相当于是从零开始搭建一个 api
接口平台,屏蔽一些公司相关的东西,界面稍微改改。本系列我将系列总结一下 nestjs
开发经验以及 nextjs
和 angular
相关体验总结。
为什么要用 Nx
Nx 是一个 Monorepos Tools 的 CLI
。底层架构设计来自 Angular-cli,为什么需要在 angular-cli
之上扩展出来一个新工具,那是因为 angular-cli
想要扩展一下功能,繁琐且不友好。然而 Nx
出现就轻松解决这个问题,灵活自如。正是验证那句古话:青出于蓝而胜于蓝。
我曾经按照 Angular-cli
底层设计模式,搭建了一个推广页的 Monorepos
的 CLI
管理器,也介绍怎么使用 Nx
更容易的实现这个 CLI
工具,并将思路和实现整理成文章,不知道为什么一直审核不通过。
Nx
它是一个 CLI
工具箱,为它支持技术栈提供最佳实践的工具链支持。
Nx
初衷是因为开发人员很难配置、维护、特别是集成各种工具和框架。建立一个既适用于少数开发人员,同时又能轻松扩展到整个组织的系统是很困难的。这包括设置低级构建工具、配置快速 CI,以及保持代码库健康、最新和可维护。
NX
以模块化方式构建,可以选择所需的功能。
Nx
底层包提供了与技术无关的基本功能,例如:工作空间依赖分析、任务运行、缓存、并发、代码生成和代码自动迁移。Plugins
是在NX
底层包提供的基本功能之上构建的NPM
软件包。NX
插件包含代码生成器,执行者(抽象下层构建工具)和自动代码迁移,以使你的工具保持最新。Plugins
通常是特定于技术的。例如,@nx/react
增加了对构建React Apps
和libs
的支持, 最近版本添加的@nx/vue
添加了使用Vue
对构建Vue Apps
和libs
的支持。Plugins 消除了不同工具之间集成的障碍,并提供了保持工具更新的实用程序,从而提高了开发人员的工作效率。Nx
团队维护着React
,Next
,Remix
,Angular
,Jest
,Cypress
,Storybook
等80 多个社区插件。你可以使用 @nx/plugin 包轻松地搭建一个新插件,实现自动化本地工作区。Devkit
是一组用于构建 Nx 插件的实用工具(底层就是使用 angular-devkit 封装)。Nx Cloud
通过添加远程缓存和分布式任务执行,帮助你在CI
上扩展项目。它还通过与GitHub
、GitLab
和BitBucket
集成并提供可搜索的结构化日志来改善开发人员的工作效率Nx Console
是VS Code
,IntelliJ
和VIM
的扩展。它提供了代码自动完成、交互式生成器、工作空间可视化、强大的重构等功能。VS Code
推荐的插件里面有。
回到为什么要用 Nx
,因为我要用各种技术栈,想要把它们组织起来很难的一件事,有了 Nx
就让这一切变得迎刃而解,它还能自定义插件,让我的开发就更灵活自由。
为什么选择 Next
项目要求是需要 SEO
推广。
为了满足这个要求,那肯定需要服务端渲染,一开始的想法是 Nodejs(Express + ejs)
就可以直接实现,一旦项目大了,页面交互多了,打包构建就相当麻烦。曾经实践过 nest mvc,借助 nx
实现前端打包。
拿到需求后,大家都很懵逼,老板提供了 3 个参考网站,仔细研究了一下这 3 个网站功能,整理了文档,画了一个大概草图。分好工作就要开始干活了。
我发现这些参考,其中 2 个是 Nuxt,一个是 PHP + JQ
。
我不会 Nuxt
呀,但我会 Next
。
就这样愉快的使用 Next
,并且使用的是 app
路由,而不是 page
,这 2 种路由模式是有点区别的,整体来说 app
比 page
开发体验更友好,缺点就是有些特定的第三方依赖库不好找。
为什么选择 Nest 和 Angular
用 Nest 和 Angular 不用换脑子,这 2 个写法类似,前者灵感来源后者。我一直使用这 2 个技术栈做开发,比如帮运维开发一个域名管理系统和路由器管理项目,都是用这 2 个完成的。
Nx
里面以前版本初始化全栈工程默认选项就是Nest
和Angular
。
项目准备
我本人是 Windows 电脑,尽推荐 Windows 相关的工具,如果你是 Mac,可以自行选择。
- 开发工具
对于 node.js, typescript 前端等技术最好的开发工具毋庸置疑的就是 vscode。
Windows 推荐使用 cmder,和 vscode 很好集成。
项目已经自带推荐插件,建议启用。
- 使用
nvm
安装node.js
- 非 Windows 版 github.com/nvm-sh/nvm
- Windows 版 github.com/coreybutler…
项目版本要求:
node -v
# 20+
如果对你自己网络不自信可以使用淘宝镜像:
npm config set registry http://registry.npmmirror.com/
安装 pnpm 包管理
npm install -g pnpm
配置pnpm淘宝镜像:
pnpm config set registry https://registry.npmmirror.com/
说明:nx 和 pnpm 本身是有思想冲突的。nx 提倡是一锅出,用多 lib 方式降低 app 复杂度,可以共享多个 app。这时候多个 app 和 lib 共享一份依赖。如果有不同的 app 项目(比如:react,vue,angular)在一个工作区里,就会出现冲突,我一直用 npm,最近才用 pnpm。减少每次安装包就需要使用
npm install --force xxx
烦恼。
- 安装
docker
为了确保在不同的开发、测试和部署环境中都能保持一致。使团队成员能够更轻松地共享和重现开发环境,推荐使用 docker。
可以根据自己环境安装客户端。
Windows 强烈推荐使用 wsl2
检查 docker
和 docker-compose
版本,确保安装成功
项目已提供 docker-compose.yml
文件,直接执行:
docker-compose up -d
- 数据库图形化界面
根据自己喜欢需求选择喜欢的软件或工具。
vscode 插件里推荐 2 个数据库管理界面:
- DATABASE: 连接
mysql
- NoSql: 连接
redis
- 接口文档与测试
接口使用 swagger 文档,简单测试可以使用命令行 curl 工具或者 vscode 的 REST Client 插件。
创建工作区
pnpm dlx create-nx-workspace@latest --name=miracle1 --pm=pnpm --preset=ts --ci=github --workspaceType=integrate
- name 项目名,工作区目录
- pm 使用 pnpm 包管理
- preset 预设 ts 工作区
- ci 帮我们创建一个 github workflows 文件
- workspaceType 工作区类型,这里是一个大杂烩
等待它默默安装...
代码规范化
prettier
nx
初始化项目以后会自动添加 .prettierrc
和 .editorconfig
可以根据自己需求配置 prettier
。这里不展开细说。
Eslint
pnpm add -D @nx/eslint @nx/eslint-plugin jsonc-eslint-parser @typescript-eslint/parser @typescript-eslint/eslint-plugin eslint eslint-config-prettier eslint-plugin-import
创建 .eslintignore
文件:
node_modules
创建 .eslintignore
文件:
{
"root": true,
"ignorePatterns": [
"**/*"
],
"plugins": [
"@nx"
],
"overrides": [
{
"files": "*.json",
"parser": "jsonc-eslint-parser",
"rules": {}
},
{
"files": [
"*.ts",
"*.tsx",
"*.js",
"*.jsx"
],
"rules": {
"@nx/enforce-module-boundaries": [
"error",
{
"enforceBuildableLibDependency": true,
"allow": [],
"depConstraints": [
{
"sourceTag": "*",
"onlyDependOnLibsWithTags": [
"*"
]
}
]
}
]
}
},
{
"files": [
"*.ts",
"*.tsx"
],
"extends": [
"plugin:@nx/typescript"
],
"rules": {}
},
{
"files": [
"*.js",
"*.jsx"
],
"extends": [
"plugin:@nx/javascript"
],
"rules": {}
},
{
"files": [
"*.spec.ts",
"*.spec.tsx",
"*.spec.js",
"*.spec.jsx"
],
"env": {
"jest": true
},
"rules": {}
}
]
}
在 nx.json
配置:
{
...
"plugins": [
{
"plugin": "@nx/eslint/plugin",
"options": {
"targetName": "lint"
}
}
]
}
@nx/enforce-module-boundaries
规则就是@nx/eslint-plugin
里的功能。
enforce-module-boundaries
主要是限制包引用关系。可以使用 tags
来管理。配置文档,
@nx/eslint
会帮我们执行 eslint
检查:
pnpm exec nx lint project
如果你觉得当前规则不满足需求,可以自己写一些规则,执行命令:
pnpm exec nx generate @nx/eslint:workspace-rule --name=rule-name --no-interactive
它会帮你生成一个 eslint rule
模板,并自动导入根配置里。
stylelint
写前端界面,如果需要写样式肯定少不了 stylelint
。
初始化:
pnpm create stylelint
我们主要使用 scss:
pnpm add -D stylelint-order stylelint-config-standard-scss
打开 .stylelintrc.json
文件,把 stylelint-config-standard
替换为 stylelint-config-standard-scss
,如下配置:
{
"extends": [
"stylelint-config-standard-scss"
],
"plugins": [
"stylelint-order"
],
// 自定义覆盖规则
"rules": {}
}
stylelint-order
对css
属性进行排序。
对于项目我们可以使用 nx-stylelint 可以帮助我们设置不同的项目:
pnpm exec nx stylelint project
这里不详细展开,后面项目配置在详细讲解
commitlint
现在规范化 commit.message
算是一种主流。
pnpm add -D @commitlint/cli @commitlint/config-conventional
创建配置文件 commitlint.config.js
:
module.exports = {
extends: ['@commitlint/config-conventional']
}
通用的书写模板:
type(scope?): subject
body?
footer?
- type:类型
- feat:新增功能
- fix:bug 修复
- docs:文档更新
- style:风格修复(现在可以使用lint-staged代替)
- refactor:重构代码(既没有新增功能,也没有修复bug)
- perf:改进性能、体验优化的代码更改
- test:新增测试或更新现有测试用例
- build:主要目的是修改项目构建系统或项目配置文件提交
- ci:主要目的是修改项目继续集成流程配置文件提交
- revert:回滚某个更早之前的提交
- release:版本发布
- chore:不属于以上类型的其他类型
- scope:范围
- subject:简单描述
- body:更多内容
- footer:
BREAKING CHANGE
破坏变更信息
举例:
- 更新 nx 依赖包升级:
git commit -m "chore(dev-deps): bump @nx from 18.0.7 to 18.1.0"
- 发布版本:
git commit -m "release: bump the next branch to v18.2.0-next.0"
# 或者
git commit -m "chore(release): bump the next branch to v18.2.0-next.0"
lint-staged
让我们在提交之前使用 lint-stage 来运行 lint 和格式化。
pnpm add -D lint-staged
创建配置文件 lint-staged.config.js
:
module.exports = {
"{apps,libs,tools}/**/*.ts": [
"npx nx affected:lint --uncommitted --parallel --fix --files"
],
"*": [
"npx nx format:write --uncommitted --files"
],
"{apps,libs}/**/*.scss": [
"npx stylelint --fix"
]
}
- apps: 项目目录
- libs:共享目录
- tools:工具目录(包含部署脚本,nx自定义插件,自定义 eslint 规则等工具)
Nx
会自动为 nx format
和 nx lint
命令设置相应的 prettier
和 eslint
,所以我们不需要过多的配置。
husky
我们有 commitlint
和 lint-staged
,要想它们更好发挥作用还需要使用 husky
。
husky
主要功能自动检测 git
提交消息、代码,并在提交或推送时运行 git
钩子。
安装:
pnpm add -D husky
初始化:
pnpm exec husky init
生成 2 个 git 钩子脚本:
pre-commit:git commit 时启用 lint-staged
默认会给我们生成一个 pre-commit
文件:
#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"
npx --no-install lint-staged
commit-msg:使用 commitlint 检查 commit.message 信息是否符合规范
创建一个 commit-msg
文件:
#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"
npx --no-install -- commitlint --edit
commitizen
一切都准备就绪,可以提交代码了,虽然 commitlint
那套规范看起来很酷,每次输入那么多需要记忆太多,我们可以使用 commitizen
来开启交互式的提交,当然你也可以使用 vscode 插件(推荐插件已提供)。
pnpm add -D cz-customizable
在 package.json
中添加一个新脚本:
"scripts": {
...,
"commit": "./node_modules/cz-customizable/standalone.js"
}
在工作区根目录,创建一个 .cz-config.js
文件。
里面内容如何编写可以参考 EXAMPLE,根据自己需求定制。
常用定制:
- types:根据自己需求选择更合理的分类
- scopes:对你工作区项目分类,适合对生成版本日志有帮助
- messages:提示语,你如果对英文不感冒,那么可以自定义中文
其他按注释可以自行选择。
配置了 types
和 scopes
可以更好使用 commitlint
的规则限制:
const { types, scopes } = require('./.cz-config.js');
module.exports = {
extends: ['@commitlint/config-conventional'],
rules: {
'header-max-length': [2, 'always', 100],
/**
* scope-enum 提交 scope 的枚举
*/
'scope-enum': [2, 'always', scopes.map((s) => s.name)],
/**
* type-enum 提交的类型枚举
*/
'type-enum': [2, 'always', types.map((t) => t.value)],
},
};
当你准备 git commit
时,允许命令:
pnpm run commit
到这里我们就可以 git push
我们的代码了。
接下来我们会介绍初始化 3 个项目以及基本配置和一些开发说明。
转载自:https://juejin.cn/post/7343243744480182323