vue3+vite+ts 发布自定义组件到npm

vue3+vite 发布自定义组件到npm

初始化项目

typescript 复制代码
// 创建项目
pnpm create vite vue-test-app --template vue-ts

// 运行项目
cd vite vue-test-app
pnpm install
pnpm run dev

编写组件

1、根目录下创建packages目录作为组件的开发包,目录下的index.ts文件作为整个组件库的出口文件,导出组件。

typescript 复制代码
//index.ts
import type { App } from 'vue'
import MyButton from './Button'
import MyTag from './Tag'

// 所有组件列表
const components = [
    MyButton,
    MyTag
]

// 定义 install 方法
const install = (app: App): void => {
  // 遍历注册所有组件
  /*
    component.__name ts报错
    Argument of type 'string | undefined' is not assignable to parameter of type 'string'.

    Type 'undefined' is not assignable to type 'string'.ts(2345)
    解决方式一:使用// @ts-ignore
    解决方式二:使用类型断言 尖括号语法(component.__name) 或 as语法(component.__name as string)
  */
  components.forEach(component => app.component(component.__name as string, component))
}

export {
    MyButton,
    MyTag
}

const VueTestUI = {
  install
}

export default VueTestUI

2、编写组件,创建packages/Button目录,在该目录下创建Button.vue和index.ts文件。

typescript 复制代码
// Button.vue
<template>
    <button class="MyButton" type="button">
      我是一个按钮组件
    </button>
  </template>
  
<script lang="ts">
  export default {
    name: 'MyButton', //组件名称,必须设置
    data () {
      return {}
    },
    methods: {},
    filters: {},
    created () {}
  }
</script>
  
<style>
  .MyButton {
    color: red;
  }
</style>
typescript 复制代码
// index.ts
import type { App } from 'vue'
import MyButton from "./Button.vue"

// 使用install方法,在app.use挂载
MyButton.install = (app: App) => {
    app.component(MyButton.__name as string, MyButton) //注册组件
}
  
export default MyButton

配置打包

1、修改vite.config.ts配置

typescript 复制代码
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import path from 'path'

// https://vitejs.dev/config/
export default defineConfig({
  plugins: [vue()],
  base:'/',
  build:{
    lib:{
      entry: path.resolve(__dirname, './packages/index.ts'), //指定组件编译入口文件
      name: 'vueMoUI',
      fileName: 'vue-mo-ui'
    },//库编译模式配置
    rollupOptions: {
      external: ['vue', 'swiper', '@vuepic/vue-datepicker', 'qrcode'],
      output: {
        // format: 'es', // 默认es,可选 'amd' 'cjs' 'es' 'iife' 'umd' 'system'
        exports: 'named',
        globals: { //在UMD构建模式下为这些外部化的依赖提供一个全局变量
          vue:'Vue',
          // 'vue-router': 'VueRouter', // 引入vue-router全局变量,否则router.push将无法使用
          swiper: 'Swiper',
          '@vuepic/vue-datepicker': 'VueDatePicker',
          qrcode: 'qrcode'
        }
      }
    },
     /** 设置为 false 可以禁用最小化混淆,或是用来指定使用哪种混淆器。
        默认为 Esbuild,它比 terser 快 20-40 倍,压缩率只差 1%-2%。
        注意,在 lib 模式下使用 'es' 时,build.minify 选项不会缩减空格,因为会移除掉 pure 标注,导致破坏 tree-shaking。
        当设置为 'terser' 时必须先安装 Terser。(yarn add terser -D)
    */
    minify: 'terser', // Vite 2.6.x 以上需要配置 minify: "terser", terserOptions 才能生效
    terserOptions: { // 在打包代码时移除 console、debugger 和 注释
      compress: {
        /* (default: false) -- Pass true to discard calls to console.* functions.
          If you wish to drop a specific function call such as console.info and/or
          retain side effects from function arguments after dropping the function
          call then use pure_funcs instead
        */
        drop_console: true, // 生产环境时移除console
        drop_debugger: true
      },
      format: {
        comments: false // 删除注释comments
      }
    }
  }
})

2、执行打包pnpm run build,会在dist文件夹下生成如下文件

3、修改package.json

json 复制代码
//package.json

{
  "name": "vue-mo-ui",
  "private": false,
  "version": "0.0.0",
  "author": "FenceRain",
  "description": "组件发布npm练习",
  "type": "module",
  "license": "MIT",
  "files": [
    "dist"
  ],
  "main": "./dist/vue-mo-ui.umd.cjs",
  "module": "./dist/vue-mo-ui.js",
  "exports": {
    "./dist/style.css": "./dist/style.css",
    "./css": "./dist/style.css",
    ".": {
      "import": "./dist/vue-mo-ui.js",
      "require": "./dist/vue-mo-ui.umd.cjs"
    }
  },
  "scripts": {
    "dev": "vite",
    "build": "vue-tsc && vite build",
    "preview": "vite preview"
  },
  "dependencies": {
    "terser": "^5.19.2",
    "vue": "^3.3.4",
    "vue-mo-ui": "^0.0.0"
  },
  "devDependencies": {
    "@types/node": "^20.5.7",
    "@vitejs/plugin-vue": "^4.2.3",
    "typescript": "^5.0.2",
    "vite": "^4.4.5",
    "vue-tsc": "^1.8.5"
  }
}

组件上传到npm

1、需要先在npm官网注册自己的npm账户,链接:https://www.npmjs.com/

2、查询是否已存在包名,可以在npm官网查,也可以使用 npm view 包名

3、上传包必须使用npm官方源,如果配置的是其他镜像需要修改回来

4、添加自己的账户

  • npm lgoin 回车按照提示操作
  • 登录完成之后可以通过npm who am i查看是够登录成功,出现自己的账号即成功

5、上传包,没有报错就是上传成功了,可以登录npm查看到自己的包

typescript 复制代码
npn publish

测试组件库

1、安装组件

typescript 复制代码
pnpm install vue-mo-ui

2、导入使用

ts 复制代码
<script setup lang="ts">
import {MyButton, MyTag} from 'vue-mo-ui'
</script>

<template>
  <MyButton></MyButton>
  <MyTag></MyTag>
</template>

<style scoped>

</style>

3、如果样式没有加载就在main.ts中导入组件的样式文件

ts 复制代码
import "../node_modules/vue-mo-ui/dist/style.css"
相关推荐
计算机-秋大田10 分钟前
基于Spring Boot的兴顺物流管理系统设计与实现(LW+源码+讲解)
java·vue.js·spring boot·后端·spring·课程设计
m0_528723811 小时前
HTML中,title和h1标签的区别是什么?
前端·html
Dark_programmer1 小时前
html - - - - - modal弹窗出现时,页面怎么能限制滚动
前端·html
GDAL1 小时前
HTML Canvas clip 深入全面讲解
前端·javascript·canvas
禾苗种树1 小时前
在 Vue 3 中使用 ECharts 制作多 Y 轴折线图时,若希望 **Y 轴颜色自动匹配折线颜色**且无需手动干预,可以通过以下步骤实现:
前端·vue.js·echarts
贵州数擎科技有限公司1 小时前
使用 Three.js 实现流光特效
前端·webgl
JustHappy1 小时前
「我们一起做组件库🌻」做个面包屑🥖,Vue的依赖注入实战💉(VersakitUI开发实录)
前端·javascript·github
拉不动的猪2 小时前
刷刷题16
前端·javascript·面试
小盼江2 小时前
水果生鲜农产品推荐系统 协同过滤余弦函数推荐水果生鲜农产品 Springboot Vue Element-UI前后端分离 代码+开发文档+视频教程
vue.js·spring boot·ui
祈澈菇凉3 小时前
如何结合使用thread-loader和cache-loader以获得最佳效果?
前端