Skip to content
On this page

这篇文章想要做什么

介绍如何使用vue3和vite构建组件库,它能在vue3和非vue3框架中使用,并且无需多套代码和额外的心智成本。

为什么要做这件事

在我们的项目中,我们使用了vue3和vue2两种框架,我们希望能够在两种框架中使用一套组件库,而不是维护两套组件库。

如何做到

在构建过程中我们需要两套vite配置,以下以vite.config.js和vite.vue.config.js为例,来构建包含vue3包的组件库提供给非vue3的框架使用,构建不包含vue包的组件库提供给vue3框架使用。

vite.config.js

js
build: {
    minify: false,
    outDir: resolve(__dirname, 'lib/global/dist'),
    lib: {
        formats: ['es', 'cjs'],
        entry: resolve(__dirname, 'lib/index.ts'),
        name: 'index',
        fileName: 'index'
    }
}

vite.vue.config.js

js
build: {
    minify: false,
    outDir: resolve(__dirname, 'lib/vue/dist'),
    lib: {
        formats: ['es', 'cjs'],
        entry: resolve(__dirname, 'lib/vue-entry.ts'),
        name: 'index',
        fileName: 'index'
    },
    rollupOptions:{
        // make sure to externalize deps that shouldn't be bundled
        // into your library
        external: ['vue'],
        output: {
            // Provide global variables to use in the UMD build
            // for externalized deps
            globals: {
                vue: 'Vue',
            }
        }
    }
}

构建的产物

这时候我们在dist文件夹下就有vueglobal两个产物,区别在于是否包含vue3的库文件,导出的产物也有所不同。

配置package.json

为了支持多入口文件,我们需要添加exports;为了避免typescript在使用package/vue时报错,我们需要加上typesVersions的定义,你也可以参考这边回答

json
{
	"name": "your package name here",
	"version": "1.0.0",
	"files": [
		"global",
		"vue"
	],
	"main": "./global/dist/index.js",
	"exports": {
		".": "./global/dist/index.mjs",
		"./style": "./global/dist/style.css",
		"./vue": "./vue/dist/index.mjs",
		"./vue/style": "./vue/dist/style.css"
	},

	"scripts": {
		"pre-release": "npm version prerelease && npm publish --tag beta",
		"patch": "npm version patch && npm publish",
		"minor": "npm version minor && npm publish",
		"major": "npm version major && npm publish"
	},
	"private": false,
	"author": "author name here",
	"license": "ISC"
}

在项目中使用

js
import VueCom from 'package/vue'
import renderOutput from 'package'

优化的方向

添加单元测试

使用vitest@vue/test-utils进行单元测试

类型支持

由于缺少类型文件,所以在typescript中使用不是很友好,我们可以使用vite-plugin-dts生成vue组件的类型文件

js
// vite.config.js
plugins: [
    dts({
        // 构建使用的tsconfig,不包含测试的ts文件
        tsConfigFilePath: resolve(__dirname, './tsconfig.lib.json'),
        // 类型文件生成的文件目录
        outputDir: resolve(__dirname, `${dist}/types`),
    })
]
json
// package.json
{
    ...
    "typesVersions": {
    "*": {
    	"vue": [
    		"./vue/types/lib/vue-entry.d.ts"
    	]
    }
    },
    "types": "./global/types/lib/index.d.ts",
    ...
}

总结

根据以上的配置,我们可以搭建一套基本的库文件开发体系,发布后的库可以在js/ts、vue3/非vue3框架中使用。其中类型文件和区分环境的产物无需额外的适配工作,我们只需要关注功能的开发即可。

Date: 2023/07/19

Authors: 徐安海

Tags: 教程、npm、vue3、vite、library