该示例采用vite+vue3+ts手把手教你发布自己的第一个npm包,快点学习起来吧!
一、新建项目
-
使用npm
npm create vite@latest -
使用yarn
yarn create vite -
使用pnpm
pnpm create vite注意:框架选择vue,语言选择typescript
二、改造目录
- 在根目录下创建packages目录,用来存放组件
- 将src目录改为examples用作示例
- 将index.html文件的src从“/src/main.ts”改为“/examples/main.ts”
三、组件开发
- 在packages目录下开发我们的组件
- packeges目录下存放每个组件单独的开发目录以及一个index.ts用于整合所有的组件对外导出
- 每个组件又包括src目录和index.ts文件,src目录下我们把index.vue当作组件的入口文件
- 我们以el-button为例,目录图大致如下
- 编写el-button/src/index.vue,组件的入口文件
<template>
<button class="el-Button">按钮</button>
</template>
<script lang="ts" setup>
// el-button/src/index.vue
</script>
<style scoped>
.el-Button {
background-color: #1188ff;
color: white;
border: none;
padding: 6px 12px;
}
</style>
- 编写el-button/index.ts,用来实现组件的导出
import elButton from "./src/index.vue";
// 一定要先给name赋值,这样后面的局部install和全局install方法才能读到同一个name
elButton.name = "el-button";
// 为组件添加 install 方法,用于按需引入
// 如果想通过CDN方式引入,需要编写install函数
elButton.install = function (Vue: any) {
// 注册组件
Vue.component("el-button", elButton);
};
export default elButton;
- 编写 packages/index.ts 文件,实现组件的全局注册
import elButton from "./el-button/index";
// 以数组的结构保存组件,便于遍历
const components = [elButton];
// 用于按需导入
export { elButton };
// 定义 install 方法
const install = function (Vue: any) {
if ((install as any).installed) return;
(install as any).installed = true; // 遍历并注册全局组件
components.map((component) => {
Vue.component(component.name, component);
});
};
if (typeof window !== "undefined" && window.Vue) {
install(window.Vue);
}
export default {
// 导出的对象必须具备一个 install 方法
install,
};
这一步会因为ts检验报错:
我们只需要在根目录中建立一个ts声明文件即可。
//env.d.ts
declare module "*.vue" {
import { DefineComponent } from "vue";
const component: DefineComponent<{}, {}, any>;
export default component;
}
declare interface Window {
Vue: any;
}
然后在tsconfig.json中修改include
- "include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.tsx", "src/**/*.vue"],
+ "include": ["packages/**/*.ts", "packages/**/*.d.ts", "packages/**/*.tsx", "packages/**/*.vue", "./*.d.ts"],
四、本地测试
<script setup lang="ts">
// examples/App.vue
import elButton from "../packages/el-button/index";
</script>
<template>
<elButton />
</template>
<style scoped></style>
五、编写package.json文件
- 需要填写的字段有
- name:包名,唯一
- version:版本号
- files:配置需要发布的文件
- main:入口文件
- module:模块入口
- 示例
{
"name": "npm-test",
"private": false,
"version": "0.0.1",
"type": "module",
"main": "dist/npm-test.umd.js",
"module": "dist/npm-test.es.js",
"files": [
"dist/*",
"env.d.ts"
],
"scripts": {
"dev": "vite",
"build": "vue-tsc && vite build",
"preview": "vite preview"
},
"dependencies": {
"path": "^0.12.7",
"vue": "^3.2.47"
},
"devDependencies": {
"@types/node": "^20.2.5",
"@vitejs/plugin-vue": "^4.1.0",
"@vitejs/plugin-vue-jsx": "^3.0.2",
"sass": "^1.62.1",
"typescript": "^5.0.2",
"vite": "^4.3.9",
"vue-tsc": "^1.4.2"
}
}
六、vite打包配置
// vite.config.ts
import { defineConfig } from "vite";
import vue from "@vitejs/plugin-vue";
import vueJsx from "@vitejs/plugin-vue-jsx";
import path from "path";
const resolve = (dir) => path.join(__dirname, dir);
// https://vitejs.dev/config/
export default defineConfig({
plugins: [vue(), vueJsx({})],
resolve: {
alias: {
"@": resolve("examples"),
packages: resolve("packages"),
},
},
build: {
rollupOptions: {
// 请确保外部化那些你的库中不需要的依赖
external: ["vue"],
output: {
// 在 UMD 构建模式下为这些外部化的依赖提供一个全局变量
globals: {
vue: "Vue",
},
},
},
lib: {
entry: "packages/index.ts",
name: "npm-test",
fileName: (format) => `npm-test.${format}.js`,
},
},
});
七、打包
执行yarn build,会生成dist文件夹
八、本地模拟
- 直接引入
- 在examples/main.ts中引入style.css文件
import { createApp } from 'vue'
import './style.css'
import App from './App.vue'
import '../dist/style.css'
createApp(App).mount('#app')
- 在examples/App.vue中引入组件
<template>
<elButton />
</template>
<script setup lang="ts">
import { elButton } from "../dist/npm-test.js";
</script>
<style scoped>
</style>
- 全局引入
- 在examples/main.ts中使用use全局注册组件
import { createApp } from 'vue'
import './style.css'
import App from './App.vue'
import '../dist/style.css'
import elButton from "../dist/npm-test.es.js";
const app = createApp(App);
app.use(elButton)
app.mount('#app');
- 直接在examples/App.vue中使用
<template>
<elButton />
</template>
<script setup lang="ts">
</script>
<style scoped>
</style>
九、发布
- npm config get registry 查看是否是官方源 registry.npmjs.org, 不是的话通过npm config set registry registry.npmjs.org 切换
- npm login 输入账号密码登陆
- npm publish
至此,我们的第一个npm包就发布成功了,快去登陆npm官网查看自己的包吧!