其他分享
首页 > 其他分享> > 使用monorepo发布vue3组件库

使用monorepo发布vue3组件库

作者:互联网

安装pnpm

npm install pnpm -g

初始化package.json

pnpm init

新建配置文件 .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
{
  "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
packages:
    - 'packages/**'
    - 'examples'

::: tip 注意
为了我们各个项目之间能够互相引用我们要新建一个pnpm-workspace.yaml文件将我们的包关联起来
:::

搭建utils包

介绍

utils是公共库包

创建utils目录

进入utils文件夹

cd utils

初始化package.json

pnpm init
{
  "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目录

创建components包

进入components文件夹

cd components

初始化package.json

pnpm init
{
  "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组件 (正式进入核心区)

<!-- 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
import Button from './button.vue'

export default Button

导出所有组件,供局部导入使用(局部导出)

// components/src/index.ts
import Button from "./button";

export { Button as QuickButton };

导出增加版本及相关信息(全局导出)

// 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 -->
<!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目录

创建根组件

<!-- src/app.vue -->
<template>
    <div>
        测试
    </div>
</template>

创建入口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

全局导入

//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')

局部导入

//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
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()
        ]
    }
)

打包

 ...
  "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)。
:::

那么如何向打包后的库里加入声明文件呢? 其实很简单,只需要引入vite-plugin-dts

pnpm i vite-plugin-dts -D -w
//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 注意

  1. 去npm官网注册、登录及相关信息修改

  2. 使用pnpm登录、发布

  3. 发布使用镜像必须是npm(如果是淘宝镜像恢复回npm)

  4. 发布前修改package.json版本并执行build命令。
    :::

  5. 注册

https://www.npmjs.com/

  1. 登录
pnpm login 

Username: 迷的账号
Password:  你的密码
Email: (this IS public) 你的邮箱   

Enter one-time password: 邮箱验证码
  1. 发布
pnpm publish 即可

常见错误

比如:去掉 后面的 -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
  }

标签:vue,pnpm,ts,components,vue3,组件,import,monorepo,vite
来源: https://www.cnblogs.com/zlp520/p/16615744.html