组件库打包
注意
全量打包
按需打包
全量打包
新建 根目录/command/build.js
新建 根目录/packages/ 打包入口文件夹
复制结构
(1) 把 components 下面的所有文件复制到 packages 下面
(2) 把写组件用到的都放到 packages 下面
复制 interfaces,hooks,utils,stores 等等文件夹到 packages 下面
- 架构
bash
├── command
│ ├── build.js
├── src
├── packages
│ ├── stores
│ ├── utils
│ ├── interfaces
│ ├── hooks
│ ├── index.ts
│ ├── chooseArea
│ │ ├── lib (引入的第三方库)
│ │ │ └── xxx.json
│ │ ├── src (源码)
│ │ │ ├── index.vue
│ │ ├── index.ts
│ ├── chooseIcon
│ │ ├── lib (引入的第三方库)
│ │ │ └── xxx.json
│ │ ├── src (源码)
│ │ │ ├── index.vue
│ │ ├── index.ts
- 修改 packages 文件夹下面的引入路径(重点)
都换成引入 packages 目录下面的
创建打包文件
- src/command/build.js
js
import { createRequire } from "module";
import { fileURLToPath } from "node:url";
// 使用require
const require = createRequire(import.meta.url);
const path = require("path");
// 使用文件路径
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
const { defineConfig, build } = require("vite");
const vue = require("@vitejs/plugin-vue");
// const vueJsx = require('@vitejs/plugin-vue-jsx')
// 打包入口文件夹 ,找到packages下的所有文件夹
const entryDir = path.resolve(__dirname, "../packages");
// 出口文件夹,打包到lib文件夹下
const outDir = path.resolve(__dirname, "../lib");
// vite 基础配置
const baseConfig = defineConfig({
configFile: false,
publicDir: false,
plugins: [vue()],
});
// rollup 配置
const rollupOptions = {
// vue 全家桶不需要打包
external: ["vue", "vue-router", "pinia"],
output: {
globals: {
vue: "Vue",
vueRouter: "VueRouter",
pinia: "Pinia",
},
},
};
// 全量打包配置
const buildAll = async () => {
await build({
...baseConfig,
build: {
rollupOptions,
lib: {
entry: path.resolve(entryDir, "index.ts"),
name: "YJ-elementplus-components",
fileName: "YJ-elementplus-components",
formats: ["es", "umd"],
},
outDir,
},
});
};
// 打包成库
const buildLib = async () => {
await buildAll();
};
buildLib();
配置 vue 模块
新建 packages/vue.d.ts
- packages/vue.d.ts
ts
/// <reference types="vite/client" />
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;
}
配置打包命令
- 使用的时候直接执行
npm run lib
即可
js
"scripts": {
"dev": "vite",
"build": "run-p type-check \"build-only {@}\" --",
"preview": "vite preview",
"build-only": "vite build",
"type-check": "vue-tsc --build",
"build:components":"node ./command/build.js",
"lib":"npm run build:components"
},
测试的时候直接引入
- main.js 中 引入
bash
import YJUI from '../lib/YJ-elementplus-components.js'
import '../lib/YJ-elementplus-components.css'
单独打包组件
前面的步骤和全量一样
安装一个输出库
js
npm i fs-extra -D
修改 command/build.js
js
import { createRequire } from "module";
import { fileURLToPath } from "node:url";
// 使用require
const require = createRequire(import.meta.url);
const path = require("path");
// 使用文件路径
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
const { defineConfig, build } = require("vite");
const vue = require("@vitejs/plugin-vue");
// const vueJsx = require('@vitejs/plugin-vue-jsx')
// 打包入口文件夹 ,找到packages下的所有文件夹
const entryDir = path.resolve(__dirname, "../packages");
// 出口文件夹,打包到lib文件夹下
const outDir = path.resolve(__dirname, "../lib");
// vite 基础配置
const baseConfig = defineConfig({
configFile: false,
publicDir: false,
plugins: [vue()],
});
/* 单独打包 要引入的 */
const fsExtra = require("fs-extra");
const fs = require("fs");
// rollup 配置
const rollupOptions = {
// vue 全家桶不需要打包
external: ["vue", "vue-router", "pinia"],
output: {
globals: {
vue: "Vue",
vueRouter: "VueRouter",
pinia: "Pinia",
},
},
};
// 全量打包配置
const buildAll = async () => {
await build({
...baseConfig,
build: {
rollupOptions,
lib: {
entry: path.resolve(entryDir, "index.ts"),
name: "YJ-elementplus-components",
fileName: "YJ-elementplus-components",
formats: ["es", "umd"],
},
outDir,
},
});
};
// 单组件打包
// name 就是最终的组件名称
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 createPackageJson = async (name) => {
const fileStr = `
{
"name": "${name}",
"main": "index.umd.js",
"module": "index.es.js",
"style":"styles.css"
}
`;
// 如果有css就是
/*
const fileStr = `
{
"name": "${name}",
"main": "index.umd.js",
"module": "index.es.js",
"style":"styles.css"
}
`
*/
// 输出
fsExtra.outputFile(
path.resolve(outDir, `${name}/package.json`),
fileStr,
"utf-8"
);
};
// 打包成库
const buildLib = async () => {
await buildAll();
// 获取到组件名称组成的数组
const components = fs.readdirSync(entryDir).filter((name) => {
// 判断是否是组件
const componentsDir = path.resolve(entryDir, name);
// 判断是否是一个目录
const isDir = fs.lstatSync(componentsDir).isDirectory();
// 是一个目录 并且包含index.ts
return isDir && fs.readdirSync(componentsDir).includes("index.ts");
});
// 循环构建
for (const name of components) {
// 单独打包
await buildSingle(name);
// 生成package.json
await createPackageJson(name);
}
};
buildLib();
修改 package.json
js
"scripts": {
"dev": "vite",
"build": "run-p type-check \"build-only {@}\" --",
"preview": "vite preview",
"build-only": "vite build",
"type-check": "vue-tsc --build",
"build:components": "node ./command/build.js",
"lib": "npm run build:components"
},
使用
- 如果是 TS 项目在根目录下
env.d.ts
里面写
ts
declare module "*.vue";
declare module "*.js";
- main.ts
ts
// 单独引入组件
import "../lib/chooseIcon/index.css";
import chooseIcon from "../lib/chooseIcon/index.js";
// 单独引入地区
import chooseArea from "../lib/chooseArea/index.js";
app.use(chooseIcon);
app.use(chooseArea);