Vue3.x + Vite 封装组件并打成包

电脑环境

js 复制代码
node v18.17.0
已安装pnpm

编写包组件

初始化 Vue3.x项目,并按照提示安装依赖并运行

js 复制代码
pnpm create vue@latest

改造及编写组件

  • 目录结构
html 复制代码
src/components 组件目录
src/components/MyButton/index.vue
src/components/MyInput/index.vue
src/components/index.js 导出组件 

src/views      组件使用的示例页面
  • 导出组件 src/components/index.js, 同时也是打包入口文件
js 复制代码
import MyButton from "./MyButton/index.vue";
import MyInput from "./MyInput/index.vue";

MyButton.install = (app) => { // 可以按需注册组件
  app.component("MyButton", MyButton);
};

MyInput.install = (app) => { 
  app.component("MyInput", MyInput);
};

export { MyButton, MyInput };
export default {
  install(app: any) {  // 全局注册组件
    app.component("MyButton", MyButton);
    app.component("MyInput", MyInput);
  },
};
  • 包发布配置 package.json 【注意files + exports配置】
json 复制代码
  "name": "vue-antd-components", // 包名称
  "version": "1.0.9", // 包版本
  "private": false, // 必须设置为false
  "type": "module",
  "scripts": {
    "dev": "vite",
    "build": "vite build",
    "preview": "vite preview"
  },
  "dependencies": {
    "ant-design-vue": "^4.2.6",
    "less": "^4.3.0",
    "vue": "^3.5.13",
    "vue-router": "^4.2.5"
  },
  "devDependencies": {
    "@types/node": "^24.0.3",
    "@vitejs/plugin-vue": "^5.2.3",
    "unplugin-auto-import": "^19.3.0", 
    "unplugin-vue-components": "^28.7.0",
    "unplugin-vue-router": "^0.10.9",
    "vite": "^6.2.4",
    "vite-plugin-components": "^0.13.3",
    "vite-plugin-vue-devtools": "^7.7.2"
  },
  "publishConfig": {
    "registry": "http://xxx/"  // npm publish 到远程仓库地址
  },
  "files": [
    "dist"   // 包被安装后暴露的文件
  ],
  "exports": { // 唯有暴露,对方才可引入
    ".": {
      "import": "./dist/vue-antd-components.es.js",  // es6方式 引入包
      "require": "./dist/vue-antd-components.umd.js"  // require方式 引入包
    },
    "./dist/*": "./dist/*"  // 暴露其它文件,如css样式文件等
  }
  • 运行 + 打包产物 配置 vite.config.js【注意打包入口文件】
js 复制代码
import { fileURLToPath, URL } from "node:url";

import { defineConfig } from "vite";
import vue from "@vitejs/plugin-vue";
import vueDevTools from "vite-plugin-vue-devtools";
import Components from "unplugin-vue-components/vite";
import { AntDesignVueResolver } from "unplugin-vue-components/resolvers";
import AutoImport from "unplugin-auto-import/vite";
import { resolve } from "path";
import VueRouter from "unplugin-vue-router/vite";
import { VueRouterAutoImports } from "unplugin-vue-router";

// https://vite.dev/config/
export default defineConfig({
  plugins: [
    VueRouter({ // 路由自动生成配置
      extensions: [".vue"],
      routesFolder: "src/views",
      dts: "src/typed-router.d.ts",
    }),
    vue(),
    vueDevTools(),
    Components({
      resolvers: [
        AntDesignVueResolver({ // antdv组件按需自动引入
          importStyle: false, // css in js
        }),
      ],
    }),
    AutoImport({
      // 自动导入 Vue 相关 API
      imports: [
        "vue",
        "vue-router",
        VueRouterAutoImports,
        {
          "vue-router/auto": ["useLink"],
        },
      ],
      // 生成自动导入的类型声明文件
      dts: "src/auto-imports.d.ts",
      // 可选:解决 ESLint 报错
      eslintrc: {
        enabled: true,
        // filepath: "./.eslintrc-auto-import.json",
        globalsPropValue: true,
      },
    }),
  ],
  resolve: {
    alias: {
      "@": fileURLToPath(new URL("./src", import.meta.url)),
    },
  },
  build: {  // 构建相关配置
    lib: {
      entry: resolve(__dirname, "src/components/index.ts"), // 打包入口文件
      name: "VueAntdComponents",
      fileName: (format) => `vue-antd-components.${format}.js`, // format: es || umd
    },
    rollupOptions: {
      external: ["vue", "ant-design-vue"],
      output: {
        globals: {
          vue: "Vue",
          "ant-design-vue": "AntDesignVue",
        },
      },
    },
  },
});
  • 为了更快测试组件,根据配置src/views生成自动路由
js 复制代码
// src/router/index.js
import { createRouter, createWebHistory } from 'vue-router'
import { routes as autoRoutes } from 'vue-router/auto-routes'

const router = createRouter({
  history: createWebHistory(),
  routes: [...autoRoutes],
})

export default router


// src/main.js
import { createApp } from 'vue'
import App from './App.vue'
import router from './router/index'

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

打包

  • 更改及检查package.json
js 复制代码
版本号等
  • npm打包,发布,留意publish [shasum + integrity]
js 复制代码
npm adduser  // 账号 密码 邮箱
npm login --registry=http://xxx/  // 仓库地址,同package.json中publishConfig
npm who am i // 检查当前登录用户
npm run build // 打包成dist
npm publish // 发包dist到仓库地址,
  • 远程检查包有无发布成功
  • 包产物截图

使用包

  • 安装包 + 对应的版本【注意比对包sha值】
js 复制代码
npm config set registry=http://xxx/  // 仓库地址

// pnpm remove vue-antd-components 包版本号若没变则需要先清除包
pnpm add [email protected]

- 包版本号若没变,则需清除该包对应的lock相关信息 + 缓存
- 下载完成后,检查lock中integrity同publish后的值是否一致,不一致则说明包没有更新成功
  • 注册组件 + 引入样式
js 复制代码
// main.ts 引入样式
import 'vue-antd-components/dist/vue-antd-components.css'

// 按需引入, 可以页面直接使用,借助自动按需引入插件;也可以main.ts中按需引入并use注册
import { MyButton } from 'vue-antd-components'
import { MyInput } from 'vue-antd-components'

// 全部引入 
import VueAntdComponents from 'vue-antd-components'

createApp(App).use(VueAntdComponents).mount('#app')
  • 包安装成功后的目录
  • ts项目使用js编写的组件包,如何消除编辑器飘红提示
js 复制代码
// 新建 src/types.d.ts
declare module 'vue-antd-components';
相关推荐
晴殇i9 分钟前
3 分钟掌握图片懒加载核心技术:面试攻略
前端·面试·trae
Running_C18 分钟前
一文读懂vite和webpack,秒拿offer
前端
咸鱼青菜好好味18 分钟前
node的项目实战相关
前端
hqsgdmn20 分钟前
自动导入插件unplugin-auto-import/unplugin-vue-components
前端
不知火_caleb26 分钟前
前端应用更新提示的优雅实现:如何让用户及时刷新页面?
前端
前端小巷子27 分钟前
跨标签页通信(四):SharedWorker
前端·面试·浏览器
风铃喵游29 分钟前
平地起高楼: 环境搭建
前端·架构
昌平第一王昭君35 分钟前
基于antd pro封装的一个可拖动的modalform
前端
JiaLin_Denny1 小时前
css 制作一个可以旋转的水泵效果
前端·css·动画·animation·transition
集成显卡1 小时前
图片压缩工具 | Electron应用配合 commander 提供命令行调用功能
前端·javascript·electron·人机交互·命令行·cmd