目录
创建项目
创建vue+ts+vite项目 (建议尽量使用npm命令进行,减少后面npm发布时出现错误)
javascript
npm create vite@latest my-vue-app -- --template vue-ts
进入项目安装一下依赖
javascript
cd my-vue-app
npm install
#运行项目
npm run dev
安装所需依赖
- @types/node 使用resolve解析项目路径;
javascript
npm install -D @types/node
- @vitejs/plugin-vue-jsx 自动生成ts声明文件;
javascript
npm install -D @vitejs/plugin-vue-jsx
- vite-plugin-dts 自动生成ts声明文件;
javascript
npm install -D vite-plugin-dts

如有其他需求依赖自行安装
调整划分目录
- 删除src下的assets文件;
- 删除src下components下文件;
- 清空App.vue中的文件内容,后续做测试使用;
- 删除src/style.css文件,避免影响全局样式;
- 新建src/packages 目录 用于存放待发布的方法或者组件;
开发组件
- 在src/packages目录下新建button目录,button目录创建index.vue文件;
index.vue文件内容如下:
javascript
<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>
- 在src/packages目录下新建index.js文件,用于导出packages目录下的组件;index.js内容如下:
javascript
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;
- 在app.vue文件中导入组件,进行测试;
javascript
<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文件
- 删除tsconfig.app.json文件和tsconfig.node.json文件;
- 重新配置tsconfig.json文件,内容如下:
javascript
{
"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文件打包
- 启用lib模式,配置lib 用于配置 打包成库的配置项 就是上传npm 配置项 其中entry 为打包的入口文件路径 name: 打包的名称 (x现在随便起的不确定作用) fileName: 打包后的文件名称;
- 配置vite-plugin-dts插件;
- 配置dts 用于生成.d.ts 声明文件;
- 配置rollup;
- 配置resolve,快捷引入路径;
javascript
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文件
- 关闭是否为私人组件;
javascript
"private": false,
- 修改版本;
javascript
// 版本,每次提交之前都需要修改,否则提交失败
"version": "1.0.0",
- 修改配置模块入口指向构建输出的js文件;
javascript
"main": "./dist/my-ui.umd.cjs",
"module": "./dist/my-ui.js"
- 修改ts声明文件指向构建输出的js声明文件;
javascript
"types": "./dist/index.d.ts",
- 修改需要发布的文件清单;
javascript
"files": [
"dist"
],
全部配置如下:
javascript
{
"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"
}
}
发布组件
- 项目进行打包编译;
javascript
npm run build
- 先切换镜像源为官方镜像源;
javascript
npm config set registry=https://registry.npmjs.org
-
登录npm;
npm官网,如未注册npm账号请先注册账号,然后再登录。 -
回到项目中 执行 npm whoami 查看是否登录 如果没有登录 执行 npm login;执行完npm login后终端会显示登录地址,点击地址在浏览器打开进行登录;
-
执行 npm发布命令;
javascript
npm publish
发布npm包成功!!
在新项目中使用组件
- 在新项目中安装发布的组件:
javascript
npm install my-vue-app
- 在 Vue 项目中引入并使用组件:
javascript
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");
- 局部引用组件:
javascript
<template>
<pur-button>我是测试按钮</pur-button>
</template>
<script setup lang="ts">
import { PurButton } from "my-vue-app";
</script>