00 奇迹项目编码环境搭建

开篇

2023 已经过去了,这一年没做啥事情,感觉最难忘就是这个奇迹项目,公司项目名字不叫奇迹,我也不知道该叫啥,业务是一个海外代充,类似小电商平台,里面商品分类、 SKU、购物车、订单、购买等功能,我觉得这玩意有人用那真是一个奇迹,所以就叫它奇迹代充吧。

项目技术栈选择

这个项目在公司后端由是 java 写的,在这里相当于是从零开始搭建一个 api 接口平台,屏蔽一些公司相关的东西,界面稍微改改。本系列我将系列总结一下 nestjs 开发经验以及 nextjsangular 相关体验总结。

为什么要用 Nx

0

Nx 是一个 Monorepos ToolsCLI。底层架构设计来自 Angular-cli,为什么需要在 angular-cli 之上扩展出来一个新工具,那是因为 angular-cli 想要扩展一下功能,繁琐且不友好。然而 Nx 出现就轻松解决这个问题,灵活自如。正是验证那句古话:青出于蓝而胜于蓝。

我曾经按照 Angular-cli 底层设计模式,搭建了一个推广页的 MonoreposCLI 管理器,也介绍怎么使用 Nx 更容易的实现这个 CLI 工具,并将思路和实现整理成文章,不知道为什么一直审核不通过。

0

Nx 它是一个 CLI 工具箱,为它支持技术栈提供最佳实践的工具链支持。

Nx 初衷是因为开发人员很难配置、维护、特别是集成各种工具和框架。建立一个既适用于少数开发人员,同时又能轻松扩展到整个组织的系统是很困难的。这包括设置低级构建工具、配置快速 CI,以及保持代码库健康、最新和可维护。

NX 以模块化方式构建,可以选择所需的功能。

  • Nx 底层包提供了与技术无关的基本功能,例如:工作空间依赖分析、任务运行、缓存、并发、代码生成和代码自动迁移。
  • Plugins 是在 NX 底层包提供的基本功能之上构建的 NPM 软件包。NX 插件包含代码生成器,执行者(抽象下层构建工具)和自动代码迁移,以使你的工具保持最新。Plugins 通常是特定于技术的。例如, @nx/react 增加了对构建 React Appslibs 的支持, 最近版本添加的 @nx/vue 添加了使用 Vue 对构建 Vue Appslibs 的支持。Plugins 消除了不同工具之间集成的障碍,并提供了保持工具更新的实用程序,从而提高了开发人员的工作效率。Nx 团队维护着 React, Next, Remix, Angular, Jest, Cypress, Storybook 等80 多个社区插件。你可以使用 @nx/plugin 包轻松地搭建一个新插件,实现自动化本地工作区。
  • Devkit 是一组用于构建 Nx 插件的实用工具(底层就是使用 angular-devkit 封装)。
  • Nx Cloud 通过添加远程缓存和分布式任务执行,帮助你在 CI 上扩展项目。它还通过与 GitHubGitLabBitBucket集成并提供可搜索的结构化日志来改善开发人员的工作效率
  • Nx ConsoleVS Code, IntelliJVIM 的扩展。它提供了代码自动完成、交互式生成器、工作空间可视化、强大的重构等功能。VS Code 推荐的插件里面有。

回到为什么要用 Nx,因为我要用各种技术栈,想要把它们组织起来很难的一件事,有了 Nx 就让这一切变得迎刃而解,它还能自定义插件,让我的开发就更灵活自由。

为什么选择 Next

项目要求是需要 SEO 推广。

为了满足这个要求,那肯定需要服务端渲染,一开始的想法是 Nodejs(Express + ejs)就可以直接实现,一旦项目大了,页面交互多了,打包构建就相当麻烦。曾经实践过 nest mvc,借助 nx 实现前端打包。

拿到需求后,大家都很懵逼,老板提供了 3 个参考网站,仔细研究了一下这 3 个网站功能,整理了文档,画了一个大概草图。分好工作就要开始干活了。

我发现这些参考,其中 2 个是 Nuxt,一个是 PHP + JQ

我不会 Nuxt 呀,但我会 Next

就这样愉快的使用 Next,并且使用的是 app 路由,而不是 page,这 2 种路由模式是有点区别的,整体来说 apppage 开发体验更友好,缺点就是有些特定的第三方依赖库不好找。

为什么选择 Nest 和 Angular

NestAngular 不用换脑子,这 2 个写法类似,前者灵感来源后者。我一直使用这 2 个技术栈做开发,比如帮运维开发一个域名管理系统和路由器管理项目,都是用这 2 个完成的。

Nx 里面以前版本初始化全栈工程默认选项就是 NestAngular

项目准备

我本人是 Windows 电脑,尽推荐 Windows 相关的工具,如果你是 Mac,可以自行选择。

  1. 开发工具

对于 node.js, typescript 前端等技术最好的开发工具毋庸置疑的就是 vscode

Windows 推荐使用 cmder,和 vscode 很好集成。

项目已经自带推荐插件,建议启用。

  1. 使用 nvm 安装 node.js

项目版本要求:

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 烦恼。

  1. 安装 docker

为了确保在不同的开发、测试和部署环境中都能保持一致。使团队成员能够更轻松地共享和重现开发环境,推荐使用 docker

可以根据自己环境安装客户端

Windows 强烈推荐使用 wsl2

检查 dockerdocker-compose 版本,确保安装成功

项目已提供 docker-compose.yml 文件,直接执行:

docker-compose up -d

自动安装 mysqlredis

  1. 数据库图形化界面

根据自己喜欢需求选择喜欢的软件或工具。

vscode 插件里推荐 2 个数据库管理界面:

  • DATABASE: 连接 mysql
  • NoSql: 连接 redis
  1. 接口文档与测试

接口使用 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-ordercss 属性进行排序。

对于项目我们可以使用 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 破坏变更信息

举例:

  1. 更新 nx 依赖包升级:
git commit -m "chore(dev-deps): bump @nx from 18.0.7 to 18.1.0"
  1. 发布版本:
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 formatnx lint 命令设置相应的 prettiereslint,所以我们不需要过多的配置。

husky

我们有 commitlintlint-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:提示语,你如果对英文不感冒,那么可以自定义中文

其他按注释可以自行选择。

配置了 typesscopes 可以更好使用 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 我们的代码了。

源代码:github.com/jiayisheji/…

接下来我们会介绍初始化 3 个项目以及基本配置和一些开发说明。

原文链接:https://juejin.cn/post/7343243744480182323 作者:jiayi

(0)
上一篇 2024年3月7日 下午4:31
下一篇 2024年3月7日 下午4:42

相关推荐

发表回复

登录后才能评论