背景:之前的项目告一段落了,最近开始写一些组件库,主要是上面想统一现有系统的UI风格,所以写一些通用组件来节省时间,之前的私有npm也搭起来了,就开干了。
一、简介
monorepo是一种将多个项目存储在同一个存储库中的版本控制策略,对应到本篇要介绍的内容就是将多个npm package存储在一个git仓库中,这样做的优点有:
- 对于组件库来说可以不用每一个package都开一个新的Git库;
- package之间的引用可以不用发布、下载;
本篇使用的是pnpm的workspace来搭建monorepo。
二、创建项目
- 初始化项目:
pnpm init
- 在项目根目录创建
pnpm-workspace.yaml
,内容如下:
packages:
- 'packages/**'
- 'dev'
上面的意思就是dev
目录和**packages
下的子目录**均为一个package,然后创建对应的目录并初始化:
mkdir dev
mkdir packages
cd dev && pnpm init
我们在packages
下创建一个hello
目录并初始化用来作为我们要发布的一个包,dev
目录作为我们的调试项目:
mkdir hello
cd hello && pnpm init
现在的目录结构应当如下:
├── dev
│ └── package.json
├── package.json
├── packages
│ └── hello
│ └── package.json
└── pnpm-workspace.yaml
- 安装依赖
对于pnpm的workspace依赖有两种,一个是workspace共用的依赖,另一个是独立package的依赖;
对于第一种workspace共用的依赖,比如我们可以安装typescript
、vite
到workspace:
pnpm i -w -D typescript vite
对于第二种独立package的依赖,比如我们安装vue
到hello的package:
cd packages/hello
pnpm i -D vue
- 编写一个vue组件
cd packages/hello
vim index.ts
mkdir src
cd src
vim hello-wrold.vue
// index.ts
import HelloWorld from './src/hello-world.vue';
export {
HelloWorld
}
// src/hello-world.vue
<script setup lang="ts">
interface Props {
name: string;
}
const props = defineProps<Props>();
</script>
<template>
<span>hello: {{ props.name }}</span>
</template>
<style scoped></style>
- 初始化dev调试项目
pnpm create vite
pnpm i
- dev安装hello依赖
pnpm i hello
安装后dev/package.json
中会新增一条dependencies
:
{
"name": "dev",
"private": true,
"version": "0.0.0",
"type": "module",
"scripts": {
"dev": "vite",
"build": "vue-tsc && vite build",
"preview": "vite preview"
},
"dependencies": {
"hello": "workspace:^1.0.0", // 这个
"vue": "^3.2.41"
},
"devDependencies": {
"@vitejs/plugin-vue": "^3.2.0",
"typescript": "^4.6.4",
"vite": "^3.2.3",
"vue-tsc": "^1.0.9"
}
}
接下来就可以直接在dev项目中使用hello了
// App.vue
<script setup lang="ts">
import { HelloWorld } from 'hello';
</script>
<template>
<HelloWorld name="❄️"></HelloWorld>
</template>
项目代码已上传到github - main分支,可对照commit记录查看搭建过程。