您现在的位置是:首页 >技术杂谈 >vue封装组件发布到npm,支持unplugin-vue-components按需引入网站首页技术杂谈

vue封装组件发布到npm,支持unplugin-vue-components按需引入

江渚清沨 2024-08-27 00:01:02
简介vue封装组件发布到npm,支持unplugin-vue-components按需引入

目的:vue封装组件发布到npm,支持unplugin-vue-components按需引入

本篇文章只介绍plugin-vue-components组件,工具类和taro组件可直接看代码
先上效果:https://www.npmjs.com/package/plugin-vue-components

plugin-vue-componets

安装

npm i -S plugin-vue-components

引入

方式一 按需手动引入

main.ts引入样式

import "plugin-vue-components/dist/style.css"//引入样式

vue组件中使用

<template>
            <IoUpload>IoUpload</IoUpload>
            <IoList></IoList>
</template>
 import { Upload as IoUpload, List as IoList } from 'plugin-vue-components'
 

方式二 基于unplugin-vue-components按需引入

   npm install --save unplugin-vue-components

vite.config.ts文件中添加配置

import Components from 'unplugin-vue-components/vite'
plugins:[
    Components({
      resolvers: [
       (componentName) => {
          if (componentName.startsWith('Io'))
            return { name: componentName, from: 'plugin-vue-components' }
        },
      ],
]

方式三(推荐使用)基于unplugin-vue-components按需自动引入

   npm install -D unplugin-vue-components

vite.config.ts文件中添加配置

import Components from 'unplugin-vue-components/vite'
import IoUIResolver from 'plugin-vue-components/resolver'
plugins:[
    Components({
      resolvers: [
       IoUIResolver(),
      ],
]

废弃,在main.ts全局注册

import IoComponents from 'plugin-vue-components'
import "plugin-vue-components/dist/style.css"//引入样式
    
const app = createApp(App)
app.use(IoComponents)
app.mount('#app')

vue组件封装

项目结构

在这里插入图片描述

创建项目

npm create vite@latest   

封装组件

src/packages/components/ 目录下封装组件 upload/upload.vue

<template>
    <div class="upload">上传图片
        <slot></slot>
    </div>
</template>
<style lang="css">
.upload {
    color: red;
    display: flex;
}
</style>

upload/index.ts 组件注册

import { App } from 'vue'
import Upload from './upload.vue'


Upload.install = (app: App) => {
    app.component(Upload.name, Upload)
}
export {
    Upload
}
export default Upload

组件注册

src/package/componets 目录下新建 index.ts用于组件注册

import Upload from './components/upload'
import List from './components/list'
import type { App } from 'vue'

const components = [
    Upload,
    List,
]
//注册
const install = (app: App) => {
    components.forEach((component) => {
        app.component(component.name, component)
    })
}
export {
    Upload,
    List
}
export default {
    install
}

配置组件名,入口,输出位置

根目录下新建 vite.config.build.ts

import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import { resolve } from 'path'
import dts from 'vite-plugin-dts'
// 打包后的目录
// https://vitejs.dev/config/
export default defineConfig({
  resolve: {                                       // +++
    alias: {
      '@': resolve(__dirname, './src')         // +++
    }                                            // +++
  },
  plugins: [
    vue(),
    dts(),//使用的typescript,需要生成*.d.ts声明文件
  ],
  //配置打包入口 https://cn.vitejs.dev/guide/build.html#library-mode
  build: {
    lib: {
      entry: resolve(__dirname, 'src/packages/index.ts'),//入口
      name: 'plugin-vue-components',//组件名
      fileName: (format) => `plugin-vue-components.${format}.ts`
    },
    rollupOptions: {
      // 确保外部化处理那些你不想打包进库的依赖
      external: ['vue'],
      output: {
        // 在 UMD 构建模式下为这些外部化的依赖提供一个全局变量
        globals: {
          vue: 'Vue',
        },
        // dir: resolve(__dirname, 'dist') //打包输出目录
      },
    },
  },
})

配置兼容unplugin-vue-componets按需自动引入

  • src/resolver.ts 处理组件引入
import type { ComponentResolveResult, ComponentResolver } from 'unplugin-vue-components/types';

function getIoResolved(name: string): ComponentResolveResult {

    const packageName = 'plugin-vue-components';

    const style = `${packageName}/dist/style.css`;

    return {
        name,
        from: packageName,
        sideEffects: style
    };
}

const IoUIResolver = (): ComponentResolver => {
    return {
        type: 'component',
        resolve: (name) => {
            if (name.startsWith('Io')) {
                return getIoResolved(name.slice(2));
            }
        }
    };
}

export {
    IoUIResolver
}
export default IoUIResolver
  • 根目录vite.config.build.resolver.ts
import { defineConfig } from 'vite';
import path, { resolve } from 'path'
import vue from '@vitejs/plugin-vue';
import dts from 'vite-plugin-dts'

export default defineConfig({
  resolve: {                                       // +++
    alias: {
      '@': resolve(__dirname, './src')         // +++
    }                                            // +++
  },
  plugins: [
    vue(),
    dts(),
  ],
  build: {
    minify: true,
    lib: {
      entry: path.resolve(__dirname, './src/resolver.ts'),
      name: 'name',
      fileName: (format) => {
        if (format === 'es') {
          return 'resolver.mjs';
        } else {
          return 'resolver.js';
        }
      },
      formats: ['es', 'cjs']
    },
    rollupOptions: {
      // 确保外部化处理那些你不想打包进库的依赖
      external: ['vue'],
      output: {
        dir: path.resolve(__dirname, './dist')
      }
    },
    emptyOutDir: false
  }
});

配置package.json

{
  "name": "plugin-vue-components",//插件名
  "private": false,//发布到npm 需要设置false
  "version": "0.1.13",//插件版本号
  "files": [//发布到npm 需要包含的目录和文件
    "dist"
  ],
  "type": "module",
  "style": "./dist/style.css",
  "main": "./dist/plugin-vue-components.umd.ts",//入口
  "module": "./dist/plugin-vue-components.es.ts",
  "typings": "./dist/packages/index.d.ts",//类型
  "exports": {
    ".": {
      "types": "./dist/packages/index.d.ts",// exports优先级高于main、module
      "import": "./dist/plugin-vue-components.es.ts",
      "require": "./dist/plugin-vue-components.umd.ts"
    },
    "./resolver": {//兼容unplugin-vue-components按需自动引入,路径必须一致
      "types": "./dist/resolver.d.ts",
      "import": "./dist/resolver.mjs",
      "require": "./dist/resolver.js"
    },
    "./*": [
      "./*",
      "./*.d.ts"
    ]
  },
  "typesVersions": {
    "*": {
      "*": [
        "./dist/*",
        "./*"
      ]
    }
  },
  "scripts": {
    "dev": "vite",
    "build": "vite build && vite build --config vite.config.build.ts && vite build --config vite.config.build.resolver.ts ",
    "preview": "vite preview"
  },
  "dependencies": {
    "vue": "^3.3.4"
  },
  "devDependencies": {
    "@types/node": "^20.2.5",
    "@vitejs/plugin-vue": "^4.2.3",
    "sass": "^1.62.1",
    "typescript": "^5.1.3",
    "unplugin-vue-components": "^0.25.0",
    "vite": "^4.3.9",
    "vite-plugin-dts": "^2.3.0",
    "vue-tsc": "^1.6.5"
  },
  "description": "### 安装 * npm install --save plugin-vue-components",
  "repository": {
    "type": "git",
    "url": "https://gitee.com/jiangzhuqingfeng/plugin-vue-componets.git"
  },
  "keywords": [
    "io"
  ],
  "author": "872235631@qq.com",
  "license": "ISC"
}

编译并发布到npm

  • npm run build 编译
  • npm publish 发布到npm

npm 常用命令

  • npm config get registry 查看npm镜像
  • npm config set registry https://registry.npmjs.org 设置镜像
  • 淘宝镜像 https://registry.npm.taobao.org
  • npm 镜像 https://registry.npmjs.org
  • npm login 登录
  • npm login --auth-type=legacy
  • npm whoami 查看当前用户是否已登录
  • npm logout https://registry.npmjs.org 退出镜像的登录
  • npm publish 发布
风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。