Rollup 打包 Vue3 组件
安装 Rollup
npm install --global rollup
安装 @vue-cli
npm install -g @vue/cli
初始化一个 vue3 项目
vue create my-components-lib
在 src/components/ 创建一个测试组件
// MyComponent/index.ts
import { App } from 'vue'
import MyComponent from './MyComponent.vue'
MyComponent.install = (app: App) => { // 组件本身添加一个 install 方法, 方便独立导出
app.component(MyComponent.name, MyComponent)
}
export default MyComponent
<!-- MyComponent/MyComponent.vue -->
<template>
<div class="my-component-test">My Component Test</div>
</template>
<script lang="ts">
import { defineComponent } from 'vue'
export default defineComponent({
name: 'my-component',
setup () {
return {}
}
})
</script>
<style scoped>
.my-component-test {
color: red;
}
</style>
创建入口文件
// src/index.ts
import { App } from 'vue'
import MyComponent from './components/MyComponent'
const components = [MyComponent]
// 定义 install 函数类型
declare type PluginInstallFunction = (app: App, ...options: any[]) => any
const install: PluginInstallFunction = (app: App) => { // 循环导入组件
components.forEach(component => {
app.component(component.name, component)
})
}
// 导出
export default {
MyComponent,
install
}
配置 Rollup
在根目录创建 build 文件夹
安装所需 rollup 插件,可参考
这里 typescript 插件使用的是 rollup-plugin-typescript2
是为了避免和 vue 冲突
# 注意为开发依赖,记得加上 --save-dev
npm i @rollup/plugin-node-resolve rollup-plugin-typescript2 rollup-plugin-vue rollup-plugin-css-only --save-dev
// rollup.config.js
import { name } from '../package.json'
import typescript from 'rollup-plugin-typescript2'
import vuePlugin from 'rollup-plugin-vue'
import css from 'rollup-plugin-css-only'
// 如果依赖模块中存在 es 模块,需要使用 @rollup/plugin-node-resolve 插件进行转换
import nodeResolve from '@rollup/plugin-node-resolve'
const file = (type) => `dist/${name}.${type}.js`
export { // 这里将 file 方法 和 name 导出
file,
name
}
const overrides = {
compilerOptions: { declaration: true }, // 是否创建 typescript 声明文件
exclude: [ // 排除项
'node_modules',
'src/App.vue',
'src/main.ts'
]
}
export default {
input: '../src/index.ts',
output: {
name,
file: file('esm'),
format: 'es' // 编译模式
},
plugins: [nodeResolve(), typescript({ tsconfigOverride: overrides }), vuePlugin(), css({ output: 'bundle.css' })],
external: ['vue'] // 依赖模块
}
使用 npx 执行一下 rollup 看看 -c
后加配置文件路径
npx rollup -c .\build\rollup.config.js
根据编译类型的不同,创建另外两个文件 rollup.config.esm.js
& rollup.config.umd.js
// rollup.config.umd.js
import baseConfig, { file } from './rollup.config'
export default {
...baseConfig,
output: {
name: 'MyComponents', // 组件库全局对象
file: file('umd'),
format: 'umd', // umd 模式
globals: {
vue: 'Vue' // vue 全局对象名称,若有 lodash 则应为 _
},
exports: 'named'
}
}
// rollup.config.esm.js
import baseConfig, { name, file } from './rollup.config'
export default {
...baseConfig,
output: {
name,
file: file('esm'),
format: 'es'
}
}
配置 package.json
安装 rimraf
npm i rimraf --save-dev
{
"name": "my-components-lib",
"version": "0.1.0",
"private": true,
"scripts": {
"serve": "vue-cli-service serve",
"build": "npm run lint && npm run build:clean && npm run build:esm && npm run build:umd", // 重写 build
"lint": "vue-cli-service lint",
"build:esm": "npx rollup -c build/rollup.config.esm.js", // 打包 esm
"build:umd": "npx rollup -c build/rollup.config.umd.js", // 打包 umd
"build:clean": "rimraf ./dist", // 打包前删除 dist
},
// module 优先级大于 main
"main": "dist/my-components-lib.umd.js", // 入口文件
"module": "dist/my-components-lib.esm.js", // 入口文件
"types": "dist/index.d.ts", // ts 类型文件, 需要注意的是,如果有 tests 文件夹, 没有排除掉了,打包后会放到 dist/src/ 文件夹下
"file": [ // 被项目包含的文件名数组
"dist"
],
"dependencies": {
"core-js": "^3.6.5"
},
"peerDependencies": { // 将 vue 移动到 peerDependencies 防止多次安装
"vue": "^3.0.0"
},
"keywords": [ // npm 关键字
"Component",
"UI",
"Vue3"
],
"license": "MIT", // 开源协议
"publishConfig": { // 推送配置
"registry": "https://registry.npmjs.org/",
"access": "public"
},
"devDependencies": {
...
}
}
打包
npm run build
本地测试
打包后,在项目根目录使用
npm link
# link vue 开发项目和测试项目的 vue 版本不同,使用 link 保证正常使用
npm link 测试项目路径\node_modules\vue\
再到测试项目中
npm link my-components-lib
然后
import { createApp } from 'vue'
import App from './App.vue'
import MyComponentsLib from 'my-components-lib' // 导入模块
import 'my-components-lib/dist/bundle.css' // 导入 css
const app = createApp(App)
app.use(MyComponentsLib) // 使用 use
app.mount('#app')
就可以在项目中使用了
<my-component></my-component>