全局组件打包
1. 打包的配置项
个目录项创建文件【command > build.js】
const path = require("path");
const { defineConfig, build } = require("vite");
const vue = require("@vitejs/plugin-vue");
const vueJsx = require("@vitejs/plugin-vue-jsx");
// 打包入口文件夹
const entryDir = path.resolve(__dirname, "../packages");
// 出口文件夹
const outDir = path.resolve(__dirname, "../lib");
// vite 基础配置
const baseConfig = defineConfig({
configFile: false,
publicDir: false,
plugins: [vue(), vueJsx()],
});
// rollup配置
const rollupOptions = {
external: ["vue", "vue-router"],
output: {
globals: {
vue: "Vue",
},
},
};
// 全量打包构建方法
const buildAll = async () => {
await build({
...baseConfig,
build: {
rollupOptions,
lib: {
entry: path.resolve(entryDir, "index.ts"),
name: "mooc-element-components",
fileName: "mooc-element-components",
formats: ["es", "umd"],
},
outDir,
},
});
};
// 打包成库
const buildLib = async () => {
await buildAll();
};
buildLib();
2. 添加启动脚本命令
// 【package.json】
"scripts": {
...
"build:components": "node ./command/build.cjs",
"lib": "npm run build:components"
},
3.创建入口文件
根目录下创建入口文件【packages】,并将组件模块和相关文件资源放入,【package > index.ts】引入样式文件
...
import './styles/index.scss'
...
4.vue声明模块
// 【package > vue.d.ts】
declare module '*.vue' {
import { DefineComponent } from 'vue'
// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/ban-types
const component: DefineComponent<{}, {}, any>
export default component
}
5. 打包
终端输入命令进行打包 `npm run lib`
npm run lib
6. 打包后根目录生成【lib】文件即为打包后的组件包
7.打包后端组件库使用
项目的入口文档【main.ts】中引入打包后的组件库,配置后通过命令运行`npm run dev`
// 【main.ts】
...
import mUI from '../lib/index'
import '../lib/style.css'
...
app.use(router).use(ElementPlus).use(mUI)
...
单个组件打包
使用时按需引入
1.打包配置(省略代码同全局配置一致)
安装第三方库 `fxExtra` 自动输出文件
cnpm i -D fs-extra
...
const fsExtra = require('fs-extra')
const fs = require('fs')
...
// 单组件打包构建
const buildSingle = async(name)=>{
await build({
...baseConfig,
build:{
rollupOptions,
lib:{
entry:path.resolve(entryDir,name),
name:'index',
fileName:'index',
formats:['es','umd']
},
outDir:path.resolve(outDir,name)
}
})
}
// 给每个组件单独生成package.json
const createPackageKJson = (name)=>{
const fileStr = `
{
"name":"${name}",
"main":"index.umd.js",
"module":"index.es.js",
"style":"styles.css",
}
`
// 输出
// 安装 cnpm i -D fs-extra
fsExtra.outputFile(
path.resolve(outDir,`${name}/package.json`),
fileStr,
'utf-8'
)
}
// 打包成库
const buildLib = async () => {
await buildAll();
// 获取组件名称组成的数组
const components = fs.readdirSync(entryDir).filter(name => {
const componentDir = path.resolve(entryDir,name)
const isDir = fs.lstatSync(componentDir).isDirectory()
return isDir && fs.readdirSync(componentDir).includes('index.ts')
})
// 循环构建
for(const name of components){
await buildSingle(name)
createPackageKJson(name)
}
};
buildLib();
2. 运行脚本的命令配置
// 【package.json】
"scripts": {
...
"build:components": "node ./command/build.cjs",
"lib": "npm run build:components && cp package.json"
},
3. 打包
终端输入命令进行打包 `npm run lib`
npm run lib
4. 使用单个组件
// 【main.ts】
...
// 单独引入组件
import chooseIcon from '../lib/chooseIcon/index.js'
import form from '../lib/form/index.js'
import '../lib/chooseIcon/style.css'
import '../lib/form/style.css'
...
app.use(chooseIcon).use(form)
发布组件库到npm
1.配置
【lib > package.json】
{
"name":"huanyou-element-components",
"version":"1.0.1",
"main":"index.umd.js",
"module":"index.js",
"types":"index.d.ts",
"author":{
"name":"huanyou"
},
"keywords":[
"element-plus",
"ts",
"封装组件",
"二次封装"
]
}
2. 声明
告诉使用当前组件库的项目这个组件库是一个vue插件
** 每一个单独组件模块都需引入当前声明文件
【lib > index.d.ts】
import { App } from 'vue'
declare const _default: {
install(app: App): void
}
export default _default
3. 发布
1. 【lib】目录下打开终端登录npm
npm login
2. 登录成功后,发布
npm publish
4. 发布成功,安装命令
huanyou-element-components - npm
npm i huanyou-element-components
更新已发布版本
1. 更新代码
更新将原入口文件【main.ts】配置的全局注册的icon添加到打包配置内【package > index.ts】,避免用户使用时需要重新配置全局注册icon
// 【packages > index.ts】
import { App } from 'vue'
import chooseArea from './chooseArea/index'
import chooseIcon from './chooseIcon/index'
import trend from './trend/index'
import notification from './notification/index'
import menu from './menu/index'
import progress from './progress/index'
import chooseTime from './chooseTime/index'
import chooseDate from './chooseDate/index'
import chooseCity from './chooseCity/index'
import list from './list/index'
import form from './form/index'
import modalForm from './modalForm/index'
import table from './table/index'
import calendar from './calendar/index'
import './styles/index.scss'
// 全局注册icon
import * as Icons from '@element-plus/icons-vue'
const components = [
chooseArea,
chooseIcon,
trend,
notification,
menu,
progress,
chooseTime,
chooseDate,
chooseCity,
list,
form,
modalForm,
table,
calendar
]
export default {
// 遍历所有icon,将icon挂载
install(app: App) {
for (let i in Icons) {
app.component(i, (Icons as any)[i])
}
components.map(item => {
app.use(item)
})
}
}
2. 重新打包
npm run lib
3. 重新配置【package.josn】和【index.d.ts】声明
每一个单独组件模块也需要重新添加声明模块
4.修改版本
// 【lib > package.json】
{
"name":"huanyou-element-components",
"version":"1.0.1", // 修改版本
"main":"index.umd.js",
"module":"index.js",
"types":"index.d.ts",
"author":{
"name":"huanyou"
},
"keywords":[
"element-plus",
"ts",
"封装组件",
"二次封装"
]
}
5. 重新发布
npm publish