uni-app + monorepo + vue3 + typescript 架构分享

2,490 阅读4分钟

Monorepo 简介:

  • 将多个项目代码放在同一个代码仓库中,方便管理和共享代码。

Snipaste_2024-07-23_14-53-34.png

Monorepo 架构能解决哪些痛点?

  • 代码管理复杂:在传统的多仓库项目中,每个仓库都有自己的版本控制和依赖管理,会导致代码管理复杂,难以维护。
  • 工程配置不统一:各项目构建、打包、代码校验都各自维护,不一致时会导致代码差异或构建差异。
  • 部署困难:多仓库项目需要分别进行部署,容易出现版本不一致的问题。
  • 模块重复:在多仓库项目中,不同的仓库可能会有相同的模块,会浪费时间和资源。
  • 开发效率低下:在多仓库项目中,开发人员需要频繁地切换仓库,会降低开发效率。
  • 维护成本高:多仓库项目中,每个仓库都需要单独维护,会导致维护成本高。

Monorepo 项目搭建方式:

  • juejin.cn/post/734236…
  • pnpm dlx create-turbo@latest
  • npx degit dcloudio/uni-preset-vue#vite-ts hou-li-ping
  • 配置 scripts 命令:
  "scripts": {
    "dev:houliping-h5": "cd apps/hou-li-ping && pnpm dev:h5:pages",
    "build:houliping-h5": "cd apps/hou-li-ping && pnpm build:h5:pages",
    "dev:houliping-alipay": "cd apps/hou-li-ping && pnpm dev:mp-alipay:pages",
    "build:houliping-alipay": "cd apps/hou-li-ping && pnpm build:mp-alipay:pages",
    "dev:youai-weixin": "cd apps/you-ai && pnpm dev:mp-weixin:pages",
    "build:youai-weixin": "cd apps/you-ai && pnpm build:mp-weixin:pages",
    "type:check": "vue-tsc --noEmit --skipLibCheck",
    "lint:eslint": "eslint --fix '{packages,apps}/**/*.{js,ts,vue}'",
    "lint:prettier": "prettier --write '{packages,apps}/**/*.{js,ts,json,tsx,css,less,scss,vue,html,md}'",
    "lint:stylelint": "stylelint --cache --fix \"**/*.{vue,less,postcss,css,scss}\" --cache --cache-location node_modules/.cache/stylelint/",
    "lint:lint-staged": "lint-staged",
    "commit": "git add -A && czg "
  },

目录结构:

uni-app + monorepo
├─ .husky                    # husky 配置文件
├─ .vscode                   # VSCode 推荐配置
├─ app                       # app 项目
│  ├─ hou-li-ping            # 侯丽萍项目
│  ├─ you-ai                 # 友爱项目
│  └─ ***                    # ** 项目
├─ packages                  # 项目子包
│  ├─ configuration          # 全局配置
│  │  ├─ tailwind-config     # tailwind 全局配置
│  │  └─ typescript-config   # typescript 全局配置
│  ├─ core                   # 项目核心
│  │  ├─ src                
│  │  │  ├─ apis             # API 接口管理
│  │  │  ├─ assets           # 静态资源文件
│  │  │  ├─ components       # 全局组件
│  │  │  ├─ constants        # 枚举、字典、常量定义
│  │  │  ├─ hooks            # 常用 Hooks 封装
│  │  │  ├─ pages            # 项目所有页面
│  │  │  ├─ static           # 项目静态图片资源
│  │  │  ├─ stores           # pinia store
│  │  │  ├─ styles           # 全局样式文件
│  │  │  ├─ utils            # 常用工具库
│  │  │  ├─ app.ts           # 项目主文件
│  │  │  ├─ main.ts          # 项目入口文件
│  │  │  └─ pages.ts         # 全局页面配置
│  │  ├─ package.json        # 依赖包管理
│  │  ├─ tailwind.config.ts  # tailwind 配置
│  │  └─ tsconfig.json       # tsconfig 配置
│  └─ script                 # 项目 script 命令
├─ .editorconfig             # 统一不同编辑器的编码风格
├─ .eslintignore             # 忽略 Eslint 校验
├─ .eslintrc.js              # Eslint 校验配置文件
├─ .gitignore                # 忽略 git 提交
├─ .prettierignore           # 忽略 Prettier 格式化
├─ .prettierrc.js            # Prettier 格式化配置
├─ .stylelintignore          # 忽略 stylelint 格式化
├─ .stylelintrc.js           # stylelint 样式格式化配置
├─ commitlint.config.cjs     # git 提交规范配置
├─ lint-staged.config.cjs    # lint-staged 配置文件
├─ package.json              # 依赖包管理
├─ pnpm-lock.yaml            # 依赖包包版本锁
├─ pnpm-workspace.yaml       # pnpm workspace 配置
├─ README.md                 # README 介绍
├─ tsconfig.json             # typescript 全局配置
└─ turbo.json                # vite 全局配置文件

编码、兼容问题注意:

  • 支付宝小程序组件内不支持 onShow、onLoad,使用 defineExpose 暴露到页面执行
  • 支付宝小程序组件内不支持 navigationStyle: "custom" 配置
  • 支付宝小程序 page 不支持 height:100%; width:100%,使用 vw、vh
  • 支付宝小程序使用原生 uni-picker 时间选择时,小米、红米系列手机会出现选择不了情况,尽量不使用 uni 原生组件,多端表现形式不一致
  • H5 平台不支持 uni.scanCode 扫码,模拟器使用 BarcodeDetector 解析条码/二维码,正式微信环境使用 wx.scanQRCode
  • css 不能使用标签选择器添加样式,必须定义 class,每个平台标签编译后不一致
  • vite 必须配置监听,否则修改 core 代码修改不会自动热更新
build: {
  // 防止 ?? 语法报错
  target: "es2019",
  watch: {
    chokidar: {
      followSymlinks: false,
      ignored: ["!**/node_modules/@clinic/**"]
    }
  }
}
  • tailwind 配置:
import type { Config } from "tailwindcss";

const config: Config = {
  content: ['"./index.html"', "./src/**/*.{js,ts,jsx,tsx,vue}", "./node_modules/@clinic/core/src/**/*.{js,ts,jsx,tsx,vue}"],
  theme: {
    extend: {}
  },
  plugins: [require("tailwindcss-safe-area")],
  corePlugins: {
    preflight: false
  }
};

export default config;

其他注意问题(适配 + 规范):

  • 多处使用相同值尽量定义枚举/常量
  • 定时器必须放 onShow 里面执行,防止熄屏重新进入后定时器失效
  • 自定义 NavBar,适应屏幕滚动之后显示
  • 小屏手机样式兼容适配(iphoneSE、iphone5)
  • IOS 底部安全区域适配(iphoneX 及以上)
  • 完成一个页面时尽量切换不同模拟器都查看一遍(snipaste)

组件封装:

  • ref 传值 && props

UI 框架: