ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

使用monorepo发布vue3组件库

2022-08-23 13:01:50  阅读:202  来源: 互联网

标签:vue pnpm ts components vue3 组件 import monorepo vite


安装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 注意

  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 即可

常见错误

  • 错误:
    ::: 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
  }

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

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有