安裝pnpm
npm install pnpm -g
初始化package.json
pnpm init
新建配置文件 .npmrc
- 在根目錄下新建.npmrc文件,並寫入如下內容
shamefully-hoist = true
::: tip 注意
如果某些工具僅在根目錄的node_modules時纔有效,可以將其設置爲true來提升那些不在根目錄的node_modules,就是將你安裝的依賴包的依賴包的依賴包的...都放到同一級別(扁平化)。說白了就是不設置爲true有些包就有可能會出問題。
:::
安裝依賴包:vue@next、typescript、sass
pnpm i vue@next typescript sass -D -w
::: tip 注意
我們開發環境中的依賴一般全部安裝在整個項目根目錄下,方便下面我們每個包都可以引用,所以在安裝的時候需要加個 -w ,-w 代表工作區(workspace)
:::
初始化tsconfig.json
- 初始化
npx tsc --init
- 配置tsconfig.json
//tsconfig.json
{
"compilerOptions": {
"baseUrl": ".",
"jsx": "preserve",
"strict": true,
"target": "ES2015",
"module": "ESNext",
"skipLibCheck": true,
"esModuleInterop": true,
"moduleResolution": "Node",
"lib": ["esnext", "dom"]
}
}
monorepo實現
介紹
一個倉庫多個項目
新建pnpm-workspace.yaml
-
根目錄下新建pnpm-workspace.yaml
-
配置yaml
# pnpm-workspace.yaml
packages:
- 'packages/**'
- 'examples'
::: tip 注意
爲了我們各個項目之間能夠互相引用我們要新建一個pnpm-workspace.yaml文件將我們的包關聯起來
:::
搭建utils包
介紹
utils是公共庫包
創建utils目錄
- 手動創建utils目錄
進入utils文件夾
cd utils
初始化package.json
pnpm init
- 配置package.json
{
"name": "@quick-vue3-ui/utils",//utils修改爲@quick-vue3-ui/utils
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC"
}
待完善
搭建components庫包
介紹
components是組件包
創建packages目錄
- 手動創建packages目錄
創建components包
- 手動在packages目錄下創建components文件夾
進入components文件夾
cd components
初始化package.json
pnpm init
- 配置package.json
{
"name": "@quick-vue3-ui/components",//components修改爲@quick-vue3-ui/components
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC"
}
開發一個button組件 (正式進入核心區)
-
在components目錄下新建src目錄
-
在src目錄下新建button目錄
-
button目錄下新建button.vue文件
<!-- button/button.vue 此處使用的是vue3.0方式,爲了是增加組件名稱方便。3.2需要特殊處理纔可以增加組件名稱 -->
<script lang="ts">
import { defineComponent } from 'vue'
export default defineComponent({
name:'QuickButton'
})
</script>
<template>
<button>我是按鈕</button>
</template>
- button目錄下新建index.ts文件,(局部導出)
// button/index.ts
import Button from './button.vue'
export default Button
導出所有組件,供局部導入使用(局部導出)
// components/src/index.ts
import Button from "./button";
export { Button as QuickButton };
導出增加版本及相關信息(全局導出)
- components目錄下新建index.ts
// components/index.ts
import pack from '../../package.json'
import * as components from './src/index'
export * from './src/index'
const install =(app: any) => {
for (const comkey in components) {
app.component((components as any)[comkey].name, (components as any)[comkey])
}
}
export default {
name: pack.name,
version: pack.version,
install,
}
暫時告一段落,如下測試
----------------------------------------
## 搭建examples包
### 介紹
examples基於vite+vue3,目的用於調試組件
### 創建examples包
- 手動創建examples文件夾
### 進入examples文件夾
```sh
cd examples
初始化package.json
pnpm init
安裝vite、@vitejs/plugin-vue
pnpm install vite @vitejs/plugin-vue -D -w
配置vite.config.ts
//vite.config.ts
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
export default defineConfig({
plugins:[vue()]
})
創建入口html文件
- 手動創建index.html
<!-- index.html -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>examples</title>
</head>
<body>
<div id="app"></div>
<script src="src/main.ts" type="module"></script>
</body>
</html>
創建src目錄
創建根組件
-
手動創建app.vue文件
-
配置app.vue
<!-- src/app.vue -->
<template>
<div>
測試
</div>
</template>
創建入口ts
-
手動創建main.ts文件
-
配置main.ts
//src/main.ts
import {createApp} from 'vue'
import App from './app.vue'
const app = createApp(App)
app.mount('#app')
配置啓動命令
// package.json
...
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"dev": "vite"//新增
},
...
運行
pnpm run dev
::: tip 注意
如上沒有問題才能按照下面的進行
包之間本地調試(全局安裝)由於組件庫是基於ts的,所以需要安裝esno來執行ts文件便於測試包之間的引入情況
npm i esno -g
# 哪裏用就切換到那個包下執行,例如:examples要用那麼就 cd examples 然後執行安裝依賴命令即可
pnpm install @quick-vue3-ui/utils
pnpm install @quick-vue3-ui/components
:::
安裝組件庫的依賴
pnpm i @quick-vue3-ui/components
全局導入
- main.ts中導入
//examples/src/main.ts
import {createApp} from 'vue'
import quickVue3UI from '@quick-vue3-ui/components' //++
import App from './app.vue'
const app = createApp(App)
app.use(quickVue3UI) //++
app.mount('#app')
局部導入
- app.vue中導入
//examples/src/app.vue
<script lang="ts" setup>
import {QuickButton} from '@quick-vue3-ui/components'
</script>
<template>
<div>
<quick-button></quick-button>
</div>
</template>
發佈到npm
打包組件庫
::: tip 注意
vite提供了庫模式,下面我們來配置。
:::
打包配置
::: tip 注意
這裏我們選擇打包cjs(CommonJS)和esm(ESModule)兩種形式,cjs模式主要用於服務端引用(ssr),而esm就是我們現在經常使用的方式,它本身自帶treeShaking而不需要額外配置按需引入(前提是你將模塊分別導出)。
:::
-
在components包下新建vite.config.ts文件
-
配置vite.config.ts
//components/vite.config.ts
import { defineConfig } from "vite";
import vue from "@vitejs/plugin-vue"
export default defineConfig(
{
build: {
target: 'modules',
//打包文件目錄
outDir: "es",
//壓縮
minify: false,
//css分離
//cssCodeSplit: true,
rollupOptions: {
//忽略打包vue文件
external: ['vue'],
input: ['src/index.ts'],
output: [
{
format: 'es',
//不用打包成.es.js,這裏我們想把它打包成.js
entryFileNames: '[name].js',
//讓打包目錄和我們目錄對應
preserveModules: true,
//配置打包根目錄
dir: 'es',
preserveModulesRoot: 'src'
},
{
format: 'cjs',
entryFileNames: '[name].js',
//讓打包目錄和我們目錄對應
preserveModules: true,
//配置打包根目錄
dir: 'lib',
preserveModulesRoot: 'src'
}
]
},
lib: {
entry: './index.ts',
formats: ['es', 'cjs']
}
},
plugins: [
vue()
]
}
)
打包
- 配置package.json
...
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"build":"vite build"//++
},
...
- 打包命令
pnpm run build
- 打包後
::: tip 注意
其實到這裏就已經可以直接打包了;components下執行: pnpm run build你就會發現打包了es和lib兩個目錄。
到這裏其實打包的組件庫只能給js項目使用,在ts項目下運行會出現一些錯誤,而且使用的時候還會失去代碼提示功能,這樣的話我們就失去了用ts開發組件庫的意義了。所以我們需要在打包的庫里加入聲明文件(.d.ts)。
:::
- 配置d.ts
那麼如何向打包後的庫里加入聲明文件呢? 其實很簡單,只需要引入vite-plugin-dts
pnpm i vite-plugin-dts -D -w
- 再次配置vite.config.ts
//components/vite.cofig.ts
import { defineConfig } from "vite";
import vue from "@vitejs/plugin-vue"
import dts from 'vite-plugin-dts'
export default defineConfig(
{
build: {...},
plugins: [
vue(),
dts({
//指定使用的tsconfig.json爲我們整個項目根目錄下掉,如果不配置,你也可以在components下新建tsconfig.json
tsConfigFilePath: '../../tsconfig.json'
}),
//因爲這個插件默認打包到es下,我們想讓lib目錄下也生成聲明文件需要再配置一個
dts({
outputDir:'lib',
tsConfigFilePath: '../../tsconfig.json'
})
]
}
)
::: tip 注意
因爲這個插件默認打包到es下,我們想讓lib目錄下也生成聲明文件需要再配置一個dts插件,暫時沒有想到其它更好的處理方法.
然後執行打包命令你就會發現你的es和lib下就有了聲明文件
:::
發佈組件庫
::: tip 注意
其實後面就可以進行發佈了,發佈之前更改一下我們components下的package.json如下:
:::
{
"name": "quick-vue3-ui",
"version": "1.0.1",
"private": false,//這個很關鍵,如果爲true,不能發佈
"description": "quick-vue3--ui組件庫",
"main": "lib/index.js",
"module":"es/index.js",
"typings": "lib/index.d.ts",
"files": [
"es",
"lib"
],
"scripts": {
"build":"vite build"
},
"keywords": [
"quick-vue3-ui",
"quick-vue3--ui組件庫"
],
"author": "zhanglp",
"license": "MIT"
}
- 如果是第一次
::: tip 注意
-
去npm官網註冊、登錄及相關信息修改
-
使用pnpm登錄、發佈
-
發佈使用鏡像必須是npm(如果是淘寶鏡像恢復回npm)
-
發佈前修改package.json版本並執行build命令。
::: -
註冊
- 登錄
pnpm login
Username: 迷的賬號
Password: 你的密碼
Email: (this IS public) 你的郵箱
Enter one-time password: 郵箱驗證碼
- 發佈
- 非第一次
pnpm publish 即可
常見錯誤
-
錯誤:
::: tip 注意
ERROR --workspace-root may only be used inside a workspace
::: -
解決方案:
比如:去掉 後面的 -w
pnpm i vue@next typescript sass -D -w
暫時忽略,找解決方案中。。。
- 錯誤
::: tip 注意
找不到模塊“./app.vue”或其相應的類型聲明。ts
:::
- 解決方案:
//src/env.d.ts
declare module '*.vue' {
import type { DefineComponent } from 'vue'
const component: DefineComponent<{}, {}, any>
export default component
}