创建组件

src/components 目录下,新建 vue 组件,以 MyButton.vue 为例;

注意一定要写 name 属性

<template>
    <el-row class="mb-4">
        <el-button>Default</el-button>
        <el-button type="primary">Primary</el-button>
        <el-button type="success">Success</el-button>
        <el-button type="info">Info</el-button>
        <el-button type="warning">Warning</el-button>
        <el-button type="danger">Danger</el-button>
        <el-button>中文</el-button>
    </el-row>
</template>
<script>
export default {
    name: 'MyButtom'
}
</script>

src/components 目录下,新建打包配置文件 index.ts。

import { App } from 'vue'

// 加载 src/components 下全部 vue 文件
const components = import.meta.globEager('./**/*.vue');

export default {
    install(app: App) {
        for(let i in components) {
            let component = components[i].default;
            app.component(component.name, component);
        }
    }
}

组件打包

打包配置

根目录下新建 build/build.js 文件

const path = require('path')
const { defineConfig, build } = require('vite')
const vue = require('@vitejs/plugin-vue')

// 添加打包入口文件夹 packages(需要手动创建)
const entryDir = path.resolve(__dirname, '../src/components')
// 添加出口文件夹 lib(不需要手动创建,会自动生成)
const outDir = path.resolve(__dirname, '../lib')

// vite 配置
const baseConfig = defineConfig({
	configFile: false,
	publicDir: false,
	plugins: [vue()]
})

// rollup 配置(vite 基于 rollup 打包)
const rollupOptions = {
    // 这两个库不需要打包
	external: ['vue', 'vue-router'],
	output: {
		globals: {
			vue: 'Vue'
		}
	}
}

//全量构建
const buildAll = async () => {
  await build(defineConfig({
    ...baseConfig,
    build: {
      rollupOptions,
      lib: {
        entry: path.resolve(entryDir, 'index.ts'),
		    // 组件库名字
        name: 'my-components-base',
        fileName: 'my-components-base',
		    // 输出格式
        formats: ['es', 'umd']
      },
      outDir
    }
  }))
}


const buildLib = async () => {
  await buildAll()
}

buildLib()

package.json

scripts属性下新增如下两行

"build:components": "node --trace-warnings ./build/build.js",
"lib": "npm run build:components"

打包

yarn lib

使用

main.ts 中注册

import { createApp } from 'vue'
import App from './App.vue'
import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'
// 引入组件
import MyComponents from '../lib/my-components-base.es.js'
// 注意一定要引入样式
import '../lib/style.css'
// 这是测试,直接引入
// import MyComponents from './components/index.ts'

createApp(App)
.use(ElementPlus)
.use(MyComponents)// 注册
.mount('#app')

home.vue

<template>
    <div>
        <my-buttom></my-buttom>
    </div>
</template>

发布到 npm

package.json

  • private 值为 false,组件库不能私有;
  • version 默认为 0.0.0,发布到 npm 必须遵守规范,这里改为 1.0.0;
  • main 当组件库被 import 时,默认指向 /lib/my-components.es.js 文件;
{
  "name": "my-test-components",
  "private": false, // 组件库不能私有
  "version": "1.0.0", // 注意一定不能为 0.0.0
  "main": "/lib/my-components.es.js", // 主入口文件,当组件 import 时,默认指向该文件
  // ...
}

npm 登录

请正确填写用户名、密码和邮箱。当发布成功会发布邮箱信息

npm login

发布

npm publish

下载

npm install my-test-components
// 或
yarn add my-test-components

使用

main.ts 中引入

import { createApp } from 'vue'
import App from './App.vue'
import MyComponents from 'my-test-components'

createApp(App)
.use(MyComponents)
.mount('#app')

参考资料