Vue 3 + Ts + Vite 组件开发并发布npm包
目录
- 项目初始化
- 开发组件
- 配置打包
- 注册 npm 账号
- 发布组件到 npm
- 在新项目中使用组件
1. 项目初始化
1.1 创建项目
使用 Vite 快速创建一个 Vue 3 + TypeScript 项目:
(这里我新建了一个项目叫名称my-vue-component)
npm create vite@latest my-vue-component --template vue-ts
进入项目目录:
cd my-vue-component
安装依赖:
npm install
1.2 调整项目结构
将项目调整为组件库的结构:
- 清除不需要的文件, 并在
src
目录下创建packages
文件夹,用于存放组件代码。 - 在
src/packages
下创建vv3-test
文件, 在该文件下创建vv3-test.vue
,作为示例组件, (我个人比较喜欢将每个组件分成一个文件夹)。
调整后的目录结构:
my-vue-component/
├── src/
│ ├── packages/
│ │ ├── vv3-test/
│ │ │ └── vv3-test.vue
│ │ └── index.ts
│ └── main.ts
├── package.json
├── vite.config.ts
└── ...
2. 开发组件
2.1 编写组件代码
在 src/packages/vv3-test/vv3-test.vue
中编写一个简单的组件:
<script setup lang="ts">
import { ref } from "vue";
export interface Vv3TestProps {
user: string;
name?: string;
age?: number;
}
const props = withDefaults(defineProps<Vv3TestProps>(), {
user: "vip",
name: "xxh",
age: 18,
});
const count = ref(1);
const addCount = () => {
count.value++;
};
defineExpose({
addCount,
});
</script>
<template>
<div>
<h1 class="btn-base">vv3-test</h1>
<h2 class="style-color">user: {{ props.user }}</h2>
<h2>name: {{ props.name }}</h2>
<h2>age: {{ props.age }}</h2>
<h2>count: {{ count }}</h2>
</div>
</template>
<style scoped>
.btn-base {
background-color: #42b983;
}
</style>
验证组件是否可用, 在APP.vue中进行局部引入
<script setup lang="ts">
import { ref } from "vue";
import vv3Test from "./packages/vv3-test/vv3-test.vue";
const vv3TestRef = ref();
const testFn = () => {
vv3TestRef.value?.addCount();
};
</script>
<template>
<div>
我要测试一下我的npm包
<vv3Test :user="'哈哈哈'" ref="vv3TestRef" />
<button @click="testFn">测试方法可用吗</button>
</div>
</template>
<style scoped></style>
组件正常显示, 传参和组件中方法可以正常使用
2.2 导出组件
在 packages
文件中添加一个 index.ts
文件,用于导出所有组件:
import type { App } from "vue";
import Vv3Test from "./vv3-test/vv3-test.vue";
/**
* 这里默认导出一个vue支持的install方法
* 可以在main.ts中使用以下方式全局导入组件
*
* import ViteVue3TsTestFjc from "vite-vue3-ts-test-fjc"
* .....
* app.use(ViteVue3TsTestFjc);
*/
export default {
install(app: App) {
app.component("Vv3Test", Vv3Test);
// 如果还有更多的组件需要注册,可以在这里继续添加
// app.component("Vv3Test1", Vv3Test1);
// app.component("Vv3Test2", Vv3Test2);
},
};
/**
* 这里将组件导出,是为了在单独使用组件时,可以按需引入
* 为了将来支持类似这样按需使用 import {Vv3Test} from "vite-vue3-ts-test-fjc";
* 有多少个组件就添加多少个组件
*/
export { Vv3Test };
/**
* 这里是重点,需要将这些组件在ts中声明为全局组件;
*/
declare module "vue" {
export interface GlobalComponents {
Vv3Test: typeof Vv3Test;
}
}
3. 配置打包
3.1 修改 vite.config.ts
为了能够正确导出 ts
的所有类型(xxx.d.ts
)文件,需要安装 vite-plugin-dts
插件:
npm install -D vite-plugin-dts
修改vite.config.ts
以打包组件库:
注意: 需要确保你的组件库名在npm官网并不存在,切尽量不要有太过于相似的npm包名称, 否则不容易发布成功
import { defineConfig } from "vite";
import vue from "@vitejs/plugin-vue";
import dts from "vite-plugin-dts";
// https://vitejs.dev/config/
export default defineConfig({
plugins: [
vue(),
//这里必须引入vite-plugin-dts插件,否则不会生成d.ts文件
dts({
// 这里定义了需要生成d.ts文件的目录,如果有多个目录,可以使用数组
include: ["src/packages/**/*.{vue,ts}"],
}),
],
// 打包配置
build: {
// 打包后的文件输出目录
outDir: "dist",
// cssCodeSplit: true,
lib: {
//指定组件编译入口文件
entry: "./src/packages/index.ts",
// 组件库名称
name: "xxhv3tempcom",
// 文件名称
fileName: "xxh-v3-tempCom",
},
rollupOptions: {
// 确保外部化处理那些你不想打包进库的依赖
external: ["vue"],
output: {
// exports: "named",
// 在 UMD 构建模式下为这些外部化的依赖提供一个全局变量
globals: {
vue: "Vue",
},
// 确保生成的 CSS 文件输出
// assetFileNames: "assets/[name].[hash].[ext]", // 生成的 CSS 文件放在 assets 文件夹中
},
},
},
});
3.2 修改 package.json
调整 package.json
以支持组件库发布:
{
"name": "xxh-v3-tempcom",
// 是否为私人组件,这里需要修改为 fase
"private": false,
// 版本,每次提交之前都需要修改,否则提交失败
"version": "1.0.1",
// 类型必须为 module
"type": "module",
// 该组件默认指向路径
"main": "dist/xxh-v3-tempcom.js",
// 当以类似 import 方式引入时的默认目标, 如: import xxx from "xxh-v3-tempcom"
"module": "dist/xxh-v3-tempcom.umd.cjs",
// 类型定义文件,这个必须要写,要不然也无法自动提示
"types": "dist/index.d.ts",
// 当运行 npm publish 时,需要提交到 npm 的文件
"files": [
"package.json",
"README.md",
"dist"
],
"author": "xxh-h",
"license": "MIT",
"description": "用于测试打包提示的项目",
// 用于在 npm 中搜索的关键字
"keywords": [
"vite",
"vue3",
"typescript",
"demo"
],
"scripts": {
"dev": "vite",
"build": "vue-tsc -b && vite build",
"preview": "vite preview"
},
"dependencies": {
"vue": "^3.5.13"
},
"devDependencies": {
"@vitejs/plugin-vue": "^5.2.1",
"@vue/tsconfig": "^0.7.0",
"typescript": "~5.7.2",
"vite": "^6.1.0",
"vite-plugin-dts": "^4.5.0",
"vue-tsc": "^2.2.0"
}
}
3.3 项目打包
输入打包命令
npm run build
4. 注册 npm 账号
如果还没有 npm 账号,需要先注册:
- 访问 npm 官网。
- 点击 "Sign Up" 注册账号。
- 完成邮箱验证。
5. 发布组件到 npm
5.1 登录 npm
注意: 先切换镜像源为官方镜像源
npm config set registry=https://registry.npmjs.org
在终端中登录 npm:
npm login
输入用户名、密码和邮箱。
5.2 发布组件
在项目根目录下运行以下命令发布组件:
npm publish
发布成功后,可以在 npm 官网搜索到你的组件。
6. 在新项目中使用组件
6.1 安装组件
在新项目中安装发布的组件:
npm install my-vue-component
6.2 使用组件
在 Vue 项目中引入并使用组件:
import { createApp } from "vue";
import "./style.css";
import App from "./App.vue";
// 引入自己的包文件
import Vv3Test from "xxh-v3-tempcom";
// 引入包文件下的样式文件
import "xxh-v3-tempcom/dist/xxh-v3-tempcom.css";
createApp(App).use(Vv3Test).mount("#app");
在 App.vue
中使用组件:
<script setup lang="ts">
import { ref } from "vue";
const Vv3TestRef = ref();
const addCount = () => {
Vv3TestRef.value?.addCount();
};
</script>
<template>
<div>
<button @click="addCount">数字+</button>
<Vv3Test ref="Vv3TestRef" :user="123213" />
</div>
</template>
<style scoped></style>
可能遇到的问题
- 发布npm包时,命令行执行npm login或npm publish连接超时问题
第一步:执行npm config set proxy false
第二步:执行npm login -d 或 npm publish -d
npm config set proxy false
npm login -d 或 npm publish -d
注意:第二步的命令执行前都需要执行一次第一步命令
- 在引入包时, 提示无法找到该模块或声明文件, 可以尝试自己写一个声明文件
在src
下创建文件夹types
在该文件夹下面创建index.d.ts
并写入以下内容
declare module "xxh-v3-tempcom" {
import { App, Plugin } from "vue";
const xxhV3Tempcom: Plugin;
export default xxhV3Tempcom;
}
希望这个文档能帮助你顺利完成 Vue 组件的开发与发布!