前言
在平常工作中我们经常会使用 npm 安装一些包来使用,那么我们又是通过各种文档或者百度来知道这些包,并且告诉我们怎么安装,但是我从未想过这么一个包是怎么诞生的,所以今天我自己尝试的写了一个npm包。如有不正确的地方还请各位大佬们多多指教☺
一、将我们封装的一个Function发布到npm
环境准备
创建一个基本的vite空项目
js
npm create vite
然后选择 Vanilla 、TypeScript 项目创建完成后删除一些自带代码及文件,并创建utils文件夹然后再创建一个index.ts文件(里面写我们要导出的方法)

编写Function
这里我简单写了一个方法通过给函数传递一个水果的名称返回对应的价格,下面是代码明细
js
/**
* 获取水果价格
* @param name 水果名称
* @returns price价格
*/
export const getPrice = (name: string) => {
let price: number = 0.0;
switch (name) {
case '苹果':
price = 9.99;
break;
case '香蕉':
price = 59.99;
break;
case '梨':
price = 69.99;
break;
case '葡萄':
price = 79.99;
break;
case '菠萝':
price = 9.99;
break;
case '榴莲':
price = 99.99;
break;
default:
throw new Error('未匹配到水果价格,请重新录入');
}
return price;
};
然后再main.ts 文件中导入我们写的这个方法,这里面就是main.js的所有代码
js
import { getPrice } from './utils/index';
export { getPrice };
新建tsconfig.node.json
作用是打包后生成类型文件
js
{
"extends": "./tsconfig.json", // 拓展 tsconfig.json 的配置
"compilerOptions": {
"noEmit": false, // 允许生成文件
"declaration": true, // 需要设置为 true 来支持类型
"emitDeclarationOnly": true, // 只生成类型文件
"declarationDir": "lib" // 类型文件的导出目录
},
"include": ["src"] // 编译目标仅为 src 文件夹下的文件
}
更改packge.json 文件
js
{
"name": "custom-npm-vite-packge", // 包名
"private": false, // 是否私有
"version": "0.0.1", // 版本号
"type": "module",
"types": "lib/main.d.ts", // ts 类型文件地址
"main": "dist/custom-npm-vite-packge.cjs", // common.js 入口地址
"module": "dist/custom-npm-vite-packge.js", // esModule入口地址
"scripts": {
"dev": "vite",
"build": "vite build && tsc -p tsconfig.build.json", // 命令增加 tsc -p tsconfig.build.json
"preview": "vite preview"
},
"devDependencies": {
"typescript": "^5.0.2",
"vite": "^4.4.5"
}
}
更改vite.config.ts文件 增加打包规则
js
import { defineConfig } from 'vite';
export default defineConfig({
build: {
outDir: 'dist', // 自定义构建输出目录
target: 'es2020',
lib: {
entry: 'src/main.ts', // 入口文件路径
formats: ['es', 'cjs']
}
},
});
现在所有的配置就都已经完成了
注册npm账号
注册完后打开所在项目位置的终端,设置一下 registry
js
npm config set registry https://registry.npmjs.org/ 设置完成
npm login 执行
根据提示输入对应的用户名、密码、邮箱、还有邮箱验证码。配置完成后
js
npm publish
这样就完成了一个npm的发布,然后我们就可以使用npm来安装了
js
npm i custom-npm-vite-packge
二、编写一个vue3组件引入我们写的包并也发布到npm
项目创建
js
npm create vite
选择 vue、ts 创建完成删除不必要的文件
上面是目录结构及组件代码,效果截图
就是在输入框输入水果名称按下回车键获取到水果的价格,代码中也引入了我们上面写的函数包

组件的index.js文件配置
js
import { App } from 'vue';
import FruitPrice from './FruitPrice.vue';
const install = (app: App<Element>) => {
app.component('FruitPrice', FruitPrice);
};
export default {
install
};
导出这个install方法是因为后续我们项目中使用app.use(xxx) 注入组件的时候会自动调用我们这个install方法,将我们的组件注册为全局组件
vite.config.ts 配置 跟上面差不多
js
import { defineConfig } from 'vite';
import vue from '@vitejs/plugin-vue';
// https://vitejs.dev/config/
export default defineConfig({
plugins: [vue()],
build: {
outDir: 'dist', // 自定义构建输出目录
target: 'es2020',
lib: {
entry: 'src/packges/index.ts', // 入口文件路径
name: 'furitPrice', // 暴露的全局变量
fileName: 'furit-price' // 是输出的包文件名 默认去packge.json的name
},
rollupOptions: {
// 确保外部化处理那些你不想打包进库的依赖,这句话不加打包的时候会把vue给打包进去,让包的体积变大
external: ['vue'],
output: {
// 在 UMD 构建模式下为这些外部化的依赖提供一个全局变量
globals: {
vue: 'Vue'
}
}
} // rollup打包配置
}
});
不知道为什么我没有配置 external: ['vue']的时候打包完引入vue我这个组件的双向绑定失效了,还在排查原因中,后面我加上就好了,有知道可以在评论区留言
packge.json 配置
跟函数的差不多,只不过这个我没有配置类型文件

然后直接按照上面的方法发布就可以了
使用
js
import { createApp } from 'vue';
import furitPrice from 'vue3-furit-price'; 、// 导入项目
import './style.css';
import App from './App.vue';
const app = createApp(App);
app.use(furitPrice); // 注册
app.mount('#app');
页面使用
js
<template>
<FruitPrice />
</template>
<script lang="ts" setup></script>
<style scoped></style>
再发布代码的时候可以新建一个 .npmignore文件过滤掉我们不想上传的代码

这就完成了一个完整的组件包开发发布的过程,你学会了吗!因为我们现在的组件包不支持按需引入,后续再去写一个组件按需引入的demo。