monorepo仓库的创建与使用

备注:记录学习monorepo过程及使用方法,如有侵权将私密该文章。

一,前置准备

1、需要选定一个包管理器(yarn、yarn2、npm、pnpm)。

        包管理器之间的分析请看:文档monorepo相关概念。(在前一篇文章)

最好使用 pnpm 作为包管理器。全局安装pnpm。

npm install -g pnpm

二,使用 pnpm 创建一个 monorepo 仓库

1、新建目录并初始化该目录为git仓库

mkdir monorepo-dri // 创建根目录
cd monorepo-dri // 进入根目录
pnpm init // 初始化项目

2、初始化仓库后,目录中生成package.json。接下来在生成的package.json文件中修改、删除、新增配置来限制使用pnpm等。

{
  "name": "monorepo-dri", // 目录所在文件 的名称
  "version": "1.0.0",
  "description": "",
  "private": true, // 用来限制该包为私有包,避免 npm 整包发布
  "engines": {
    "node": ">=16",
    "pnpm": ">=7" // 限制 pnpm 版本为 7 以上。
  },
  "main": "index.js", // 该配置可删除
  "scripts": { // 该配置可删除
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC"
}

3、在项目根目录新建 pnpm-workspace.yaml 文件,这个文件定义了工作空间的根目录,然后写入以下内容

packages:
  // common文件夹(包)下的所有文件夹(包)
  - 'common/**'
  // libs文件夹(包)下的所有文件夹(包)
  - 'libs/**'
  // packages文件夹(包)下的所有文件夹(包)
  - 'packages/**'
  // test文件夹(包)下的所有文件夹(包)排除在外
  - '!**/test/**'

  // 注意:-后面有一个空格,然后再写'文件夹/**'
        接下来创建目录common 、libs 、packages 
mkdir common && mkdir libs && mkdir packages
        我们的应用创建在 packages 目录下,而 libs 目录则是存放一些公共的方法(如需要发布的包)等内容、而common 目录则是存放一些公共组件和方法等内容。

4、主包基本目录结构

        至此,我们的主包基本搭建完成。其基本目录结构如下:

├── common
├── libs
├── package.json
├── packages
└── pnpm-workspace.yaml

5、接下来在packages 目录下创建第一个应用、第二个应用、第三个应用

        在 packages 目录中创建第一个应用,以 vite 为例,进入 packages 目录执行 

pnpm create vite app-base --template vue-ts 命令,来创建一个名为 app-base 的项目。

pnpm create vite app-base --template vue-ts

        接下来修改刚刚创建的应用 app-base 的包名,方便以后使用:名称为 @主包名/子包名。 

{
  "name": "@monorepo-dri/app-base"
}

        此时的结构如下:

        同上流程,进行创建第二个应用与第三个应用。修改新创建的两个应用的package.json文件的包名,方便以后使用。

// 创建第二个应用
pnpm create vite app1 --template vue-ts
// 创建第三个应用
pnpm create vite app2 --template vue-ts

   app1应用的package.json文件

{
  "name": "@monorepo-dri/app1"
}

   app2应用的package.json文件

{
  "name": "@monorepo-dri/app2"
}

6、复制 packages 目录中的任意一个应用的package.json文件的这几个配置项到根目录的package.json

{
  ...
  "scripts":{
    "dev":"vite",
    "build":"vue-tsc && vite build",
    "preview":"vite preview"
  },
  "dependencies":{
    "vue":"^3.4.19"
  },
  "devDependencies":{
    "@vitejs/plugin-vue":"^5.0.4",
    "typescript":"^5.2.2",
    "vite":"^5.1.4",
    "vue-tsc":"^1.8.27"
  }
}

7、接下来修改packages 目录下的所有应用的package.json文件

        子应用一定要删除以下这些配置项。如果子应用中不删除这些配置依赖的配置项,那么后续使用 pnpm install 在根目录安装模块包时,这些子应用中也会自动下载 node_modules这样子应用中模块包就又重复安装了。

{        
  "dependencies":{
    "vue":"^3.4.19"
  },
  "devDependencies":{
    "@vitejs/plugin-vue":"^5.0.4",
    "typescript":"^5.2.2",
    "vite":"^5.1.4",
    "vue-tsc":"^1.8.27"
  }
}

8、运行 pnpm install 来安装依赖

8.1、在项目根目录下运行 pnpm install 来 一次性安装所有依赖

        在根目录下运行 pnpm install 命令,它会自动安装所有依赖,他会找到根目录的 package.json、各个文件夹下的子应用中的 package.json,然后根据各个package.json中的依赖项的配置去安装依赖包(模块包)

        在根目录下安装的依赖,在所有的packages中都可以使用(各个子应用可以使用根目录中的依赖包)。

pnpm i

8.2、为 具体的某一个应用 安装指定依赖,以及模块之间的相互依赖
        如果需要为 具体的某一个应用安装依赖,如何处理?    ——>    pnpm 提供了 --filter 参数。
        其中 --filter 过滤包名,具体使用可以参考 pnpm --filter

        给具体的子应用单独安装指定依赖,例如 axios。——具体使用看 标题9

pnpm add axios --filter 应用的名称(就是子应用的package.json中的name对象的值)

        模块之间的相互依赖。 给具体的子应用单独安装指定依赖,例如dayjs。——具体使用看 标题15
pnpm install dayjs --filter 应用的名称(就是子应用的package.json中的name对象的值)

        在设置依赖版本的时候推荐用 workspace:* ,这样就可以保持依赖的版本是工作空间里最新版本,不需要每次手动更新依赖版本。

9、在 libs 目录中,再来创建一个工具函数,例如 axios

        在 libs 目录创建 utils/request 目录,并创建文件 index.js 作为入口文件。在request 目录进行初始化,得到一个 packages.json 文件,将这个packages.json 文件的name修改为@monorepo-dri/request 。

        为名为 @monorepo-dri/request 的子应用安装指定依赖,以 axios为例,并在  index.js  中导出一个 axios 实例。

pnpm add axios --filter @monorepo-dri/request
import axios from 'axios';
const request = axios.create({});

export default request;

        此时的结构如下:

10、为各个子应用分别在vite.config.ts中设置端口号

        app-base文件夹:应用名称为  ——>  @monorepo-dri/app-base

import { defineConfig } from "vite";
import vue from "@vitejs/plugin-vue";

// https://vitejs.dev/config/
export default defineConfig({
  plugins:[vue()],
  server:{
    port:5573
  }
})

        app1文件夹:应用名称为  ——>  @monorepo-dri/app1

import { defineConfig } from "vite";
import vue from "@vitejs/plugin-vue";

// https://vitejs.dev/config/
export default defineConfig({
  plugins:[vue()],
  server:{
    port:5574
  }
})

        app2文件夹:应用名称为  ——>  @monorepo-dri/app2

import { defineConfig } from "vite";
import vue from "@vitejs/plugin-vue";

// https://vitejs.dev/config/
export default defineConfig({
  plugins:[vue()],
  server:{
    port:5575
  }
})

11、根目录的package.json配置修改

主要修改package.json文件的 scripts 配置项

{
  ...
  "scripts":{
    "dev":"vite",
    "dev-base": "pnpm run -C packages/app-base dev",
    "dev-app1": "pnpm run -C packages/app1 dev",
    "ev-app2": "pnpm run -C packages/app2 dev",
    "build": "vue-tsc && vite build",
    "preview": "vite preview"
  },
  ...
}

12、至此,包目录基本完成,进入根目录安装 typescript、eslint 等公用的包,添加一些其他文件的配置

        在根目录安装依赖包的命令:
pnpm add eslint @antfu/eslint-config typescript -Dw

        注意:该命令末尾的 -Dw 不能丢,不然会报警告。

        并在项目根目录下新建 .eslintrc.js文件,写入如下内容
process.env.ESLINT_TSCONFIG = 'tsconfig.json'

module.exports = {
  extends: '@antfu',
}

13、进入 packages/app-base 目录,安装我们刚刚创建的 request 依赖

13.1、一种方式是进入子包进行安装。

        (待补充)

13.2、另一种方式是通过 --filter 来指定包名。
pnpm -F @monorepo-dri/app-base add @monorepo-dri/request@\*

        该命令表示在包名为 @monorepo-dri/app-base 的包中安装 @monorepo-dri/request 依赖

14、接下来即可在 @monorepo-dri/app-base 项目中使用@monorepo-dri/request

<script setup lang="ts">
  import request from '@kklearn/request'
  const hitokoto = ref<string>('')
  async function reflush() {
    const result = await request.get('https://v1.hitokoto.cn')
    hitokoto.value = result.data.hitokoto
  }
  onMounted(() => reflush())
</script>

15、pnpm公共组件库

        在common目录新建components文件夹,components文件夹内部放一些公用组件或方法等。

15.1、初始化components目录

        common/components

pnpm init
15.2、在components目录新建index.js文件,导出一个方法:一个格式化日期的函数,下面的 15.7 标题会用到。

        common/components/index.js

import dayjs from 'dayjs'
 
export function formatDate(value, format = 'YYYY-MM-DD') {
    return dayjs(value).format(format)
}

        注意:此处通过es6模块化引入手法引入dayjs,那么就需要先下载依赖包dayjs,不然无法运行。

pnpm install dayjs -F @monorepo-dri/components 

        -F 等价于 --filter。

        此时的结构如下:

15.3、创建一个名叫snow的文件夹(以后的组件)

        snow目录内新建 index.vue 组件。

        common/components/snow/index.vue

<template>
    <div>我是snow组件,来自common目录的components文件夹,其内部有一个组件库叫snow,入口文件是一个vue文件index.vue</div>
</template>
 
<script setup lang="ts">
</script>
 
<style scoped>
</style>
15.4、修改 package.json 文件
{
  // 主要修改的就是name 
  "name": "@monorepo-dir/components",
  "version": "1.0.0",
  "description": "组件库内部组件snow",
  "private": true,
  "keywords": [],
  "author": "",
  "license": "MIT",
  "main": "index.ts"
}
15.5、安装 workspace 依赖

        下边的命令是在根目录安装 @monorepo-dir/components 这个组件,所有子项目都可以使用@monorepo-dir/components 下面的所有组件及方法等。

pnpm i @monorepo-dir/components -w

        此时的结构如下:

        也可以通过 --filter 指定 子应用 @monorepo-dir/app-base 安装 组件 @monorepo-dir/components 。

pnpm i @monorepo-dri/components --filter @monorepo-dri/app-base

        子应用 @monorepo-dir/app-base安装组件 @monorepo-dir/components 后 子应用目录的 package.json文件 增加依赖,子项目 node_modules 增加依赖,子项目同样运行成功。 

15.6、使用组件snow

        app-base/src/App.vue引入snow组件并使用snow组件。

        启动项目 pnpm run dev-base,运行成功,组件内容已使用成功。

        效果图:

15.7、app-base 子应用中引用 common/components/index.js,并使用该文件导出的格式化时间的方法

效果图:

三、部署

        待补充

  • 19
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
monorepo使用 prettier 和 eslint 可以非常有效地帮助我们统一代码风格并保持代码质量。 首先,Prettier 是一个代码格式化工具,它能够自动识别代码中的格式问题,并通过自动化调整代码格式,使其在项目中保持一致。在 monorepo使用 Prettier 可以确保不同子项目的代码风格保持一致,避免因为多人协作或者多个子项目而导致的格式不一致的问题。可以通过在 monorepo目录中配置 Prettier,并在各个子项目中使用相同的配置文件来实现统一的代码格式。 而 Eslint 是一个静态代码分析工具,可以帮助我们检查代码中的潜在问题、错误和不规范的写法。在 monorepo 中,使用 Eslint 可以帮助我们规定一致的代码质量标准,并对代码进行自动化的检查。可以在 monorepo目录中配置 Eslint,并在各个子项目中使用相同的配置文件,以保持一致的代码规范。 同时,在 monorepo使用 prettier 和 eslint,我们可以通过版本控制工具(如 Git)在团队协作中实现持续集成和自动化的代码格式检查。当代码提交到版本控制工具时,可以配置钩子(hooks)来触发 Prettier 和 Eslint 的检查,并在检查不通过时阻止代码提交,从而确保每个提交的代码都符合团队的要求。 总结来说,在 monorepo使用 prettier 和 eslint 可以帮助我们统一代码格式和质量标准,提高开发效率,减少潜在问题和维护成本。但需要注意,在配置过程中要保持一致的配置文件,并在团队中进行培训和沟通,以确保所有开发者都能正确使用这些工具。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值