实现vue组件库并发布npm上使用流程

发布于:2025-06-11 ⋅ 阅读:(20) ⋅ 点赞:(0)

创建项目

创建vue+ts+vite项目 (建议尽量使用npm命令进行,减少后面npm发布时出现错误)

npm create vite@latest my-vue-app -- --template vue-ts

进入项目安装一下依赖

	cd my-vue-app
	npm install
	
	#运行项目
	npm run dev

安装所需依赖

  1. @types/node 使用resolve解析项目路径;
npm install -D @types/node
  1. @vitejs/plugin-vue-jsx 自动生成ts声明文件;
npm install -D @vitejs/plugin-vue-jsx
  1. vite-plugin-dts 自动生成ts声明文件;
npm install -D vite-plugin-dts

在这里插入图片描述
如有其他需求依赖自行安装

调整划分目录

  1. 删除src下的assets文件;
  2. 删除src下components下文件;
  3. 清空App.vue中的文件内容,后续做测试使用;
  4. 删除src/style.css文件,避免影响全局样式;
  5. 新建src/packages 目录 用于存放待发布的方法或者组件;
    在这里插入图片描述

开发组件

  1. 在src/packages目录下新建button目录,button目录创建index.vue文件;
    在这里插入图片描述
    index.vue文件内容如下:
	<template>
  <button :class="getButtonClass">
    <slot></slot>
  </button>
</template>

<script setup lang="ts">
import { computed } from "vue";
const props = defineProps({
  type: {
    type: String,
    default: "primary",
  },
});

const getButtonClass = computed(() => {
  return `pur-button pur-button-${props.type}`;
});
</script>

<style scoped>
.pur-button {
  line-height: 1.5715;
  position: relative;
  display: inline-block;
  font-weight: 400;
  white-space: nowrap;
  text-align: center;
  background-image: none;
  border: 1px solid transparent;
  box-shadow: 0 2px rgba(0, 0, 0, 0.016);
  cursor: pointer;
  transition: all 0.3s cubic-bezier(0.645, 0.045, 0.355, 1);
  user-select: none;
  touch-action: manipulation;
  height: 32px;
  padding: 4.8px 15px;
  font-size: 13px;
  border-radius: 2px;
  color: #000;
  border-color: #d9d9d9;
  background: #fff;
}

.pur-button,
.pur-button:active,
.pur-button:focus,
.pur-button:focus-visible {
  outline: 0;
}

.pur-button-primary {
  color: #fff;
  border-color: #1677ff;
  background: #1677ff;
  text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.12);
  box-shadow: 0 2px rgba(0, 0, 0, 0.043);
}
.pur-button-primary:hover,
.pur-button-primary:focus {
  color: #fff;
  border-color: #40a9ff;
  background: #40a9ff;
}
.pur-button-primary:active {
  color: #fff;
  border-color: #096dd9;
  background: #096dd9;
}
</style>

  1. 在src/packages目录下新建index.js文件,用于导出packages目录下的组件;index.js内容如下:
import PurButton from './button/index.vue';
import type { App } from 'vue';

const components = [
  { name: 'PurButton', Component: PurButton }
];

const install = (app: App) => {
  components.forEach(comp => {
    app.component(comp.name, comp.Component);
  });
};

/**
 * 这里将组件导出,目的是为了在单独使用组件时,可按需引入 
 **/ 
export { PurButton };

// 添加全局组件
declare module 'vue' {
  export interface GlobalComponents {
    PurButton: typeof PurButton;
  }
}

export default install;
  1. 在app.vue文件中导入组件,进行测试;
<template>
  <div id="app">
    <PurButton type="primary">测试按钮</PurButton>
  </div>
</template>

<script setup lang="ts">
import PurButton from './packages/button/index.vue';
</script>

<style scoped>
</style>

配置tsconfig.json文件

  1. 删除tsconfig.app.json文件和tsconfig.node.json文件;
  2. 重新配置tsconfig.json文件,内容如下:
{
  "compilerOptions": {
    "target": "esnext",
    "module": "esnext",
    "moduleResolution": "node",
    "resolveJsonModule": true,
    "importHelpers": true,
    "jsx": "preserve",
    "esModuleInterop": true,
    "sourceMap": true,
    "baseUrl": "./",
    "strict": true,
    "paths": {
      "@/*": ["src/*"],
      "@@/*": ["src/.umi/*"],
      "#/*": ["types/*"]
    },
    "allowSyntheticDefaultImports": true
  },
  "include": [
    "mock/**/*",
    "src/**/*",
    "config/**/*",
    ".umirc.ts",
    "typings.d.ts",
    "types/**/*.ts",
    "types/**/*.d.ts"
  ],
  "exclude": [
    "node_modules",
    "lib",
    "es",
    "dist",
    "typings",
    "**/__test__",
    "test",
    "docs",
    "tests"
  ]
}

配置vite.config.ts文件打包

  1. 启用lib模式,配置lib 用于配置 打包成库的配置项 就是上传npm 配置项 其中entry 为打包的入口文件路径 name: 打包的名称 (x现在随便起的不确定作用) fileName: 打包后的文件名称;
  2. 配置vite-plugin-dts插件;
  3. 配置dts 用于生成.d.ts 声明文件;
  4. 配置rollup;
  5. 配置resolve,快捷引入路径;
import type { ConfigEnv, UserConfig } from 'vite';
import { loadEnv, defineConfig } from 'vite';
import vue from '@vitejs/plugin-vue';
import vueJsx from '@vitejs/plugin-vue-jsx';
import dts from 'vite-plugin-dts';
import { join, resolve } from 'path';

//构建打包文件
const buildAssetsDir = () => {
  return new Date().getTime() + '';
};

export default defineConfig(({ mode }: ConfigEnv): UserConfig => {
  const root = process.cwd();
  const env = loadEnv(mode, root);
  const assetsDir = buildAssetsDir();
  return {
    plugins: [
      vue(),
      vueJsx(),
      dts({
        tsconfigPath: './tsconfig.json',
        insertTypesEntry: true, // 自动生成d.ts文件
        include: [
          './src/packages/**/*.{vue,ts}',
        ]
      }),
    ],

    build: {
      assetsDir: assetsDir,
      chunkSizeWarningLimit: 2048,
      cssCodeSplit: false,
      lib: {
        entry: resolve(__dirname, 'src/packages/index.ts'), // 打包的入口文件
        name: 'MyUI', // 库的名称,在浏览器中访问时的全局变量名称
        fileName: (format) => `my-ui.${format}.js`, // 打包后的文件名
        formats: ['es', 'umd', 'iife'], // 支持的模块格式
      },
      rollupOptions: {
        // 确保外部化处理那些你不想打包进库的依赖
        external: ['vue', 'ant-design-vue'],
        output: {
          // 在 UMD 构建模式下为这些外部化的依赖提供一个全局变量
          globals: {
            vue: 'Vue',
          },
        }
      },

    },
    resolve: {
      alias: {
        '@': join(__dirname, './src'),
        vue: 'vue/dist/vue.esm-bundler.js',
      },
    },
  };
});

调整package.json文件

  1. 关闭是否为私人组件;
"private": false,
  1. 修改版本;
 // 版本,每次提交之前都需要修改,否则提交失败
 "version": "1.0.0",
  1. 修改配置模块入口指向构建输出的js文件;
"main": "./dist/my-ui.umd.cjs",
"module": "./dist/my-ui.js"
  1. 修改ts声明文件指向构建输出的js声明文件;
"types": "./dist/index.d.ts",
  1. 修改需要发布的文件清单;
"files": [
    "dist"
  ],

全部配置如下:

{
  "name": "my-vue-app",
  "private": false,
  "version": "0.0.1",
  "type": "module",
  "main": "./dist/my-ui.umd.cjs",
  "module": "./dist/my-ui.es.js",
  "types": "./dist/index.d.ts",
  "files": [
    "dist"
  ],
  "scripts": {
    "dev": "vite",
    "build": "vue-tsc -b && vite build",
    "preview": "vite preview"
  },
  "dependencies": {
    "vue": "^3.5.13"
  },
  "devDependencies": {
    "@types/node": "^22.15.30",
    "@vitejs/plugin-vue": "^5.2.3",
    "@vitejs/plugin-vue-jsx": "^3.1.0",
    "@vue/tsconfig": "^0.7.0",
    "typescript": "~5.8.3",
    "vite": "^5.0.0",
    "vite-plugin-dts": "^4.5.4",
    "vue-tsc": "^2.2.8"
  }
}

发布组件

  1. 项目进行打包编译;
npm run build
  1. 先切换镜像源为官方镜像源;
npm config set registry=https://registry.npmjs.org
  1. 登录npm;
    npm官网,如未注册npm账号请先注册账号,然后再登录。

  2. 回到项目中 执行 npm whoami 查看是否登录 如果没有登录 执行 npm login;执行完npm login后终端会显示登录地址,点击地址在浏览器打开进行登录;
    在这里插入图片描述
    在这里插入图片描述

  3. 执行 npm发布命令;

npm publish

发布npm包成功!!
在这里插入图片描述

在新项目中使用组件

  1. 在新项目中安装发布的组件:
npm install my-vue-app
  1. 在 Vue 项目中引入并使用组件:
import { createApp } from "vue";
import "./style.css";
import App from "./App.vue"; 

// 引入自己的包文件
import MyUI from "my-vue-app";
// 引入包文件下的样式文件
import "my-vue-app/dist/style.css";
createApp(App).use(MyUI).mount("#app");
  1. 局部引用组件:
<template>
  <pur-button>我是测试按钮</pur-button>
</template>

<script setup lang="ts">
import { PurButton } from "my-vue-app";
</script>