封装组件发布至npm,支持unplugin-vue-components插件按需引入,超详细步骤!!

文章目录

一、封装组件

1、创建组件项目

npm create vite@latest

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

2、进入项目按照所需插件

cd fuyuComp
npm i
npm i sass -D
npm i unplugin-vue-components -D
npm i @types/node --D
npm i vite-plugin-dts -D

3、运行项目

npm run dev

4、删除文件

style.css
components

5、修改App.vue

<script setup lang="ts"></script>

<template>app.vue页面</template>

<style scoped></style>

6、修改main.ts文件

import { createApp } from “vue”;
import App from “./App.vue”;

const app = createApp(App);
app.mount(“#app”);

7、新建组件目录

在这里插入图片描述

fuyuComp/src/theme-chalk/fyCard.scss

.fy-card{
    background-color:brown;
    width: 500px;
    padding: 20px;
    color: #fff;
}

fuyuComp/src/theme-chalk/fyList.scss

.fy-list{
    background-color: yellow;
    width: 500px;
    padding: 20px;
}

fuyuComp/src/theme-chalk/index.scss

@import "./fyCard.scss";
@import "./fyList.scss";

fuyuComp/packages/fyCard/index.vue

<template>
    <div class="fy-card">
       我是 fyCard 组件
    </div>
</template>
<script lang="ts" setup></script>
<style lang="scss" scoped></style>

fuyuComp/src/packages/fyCard/index.ts

import fyCard from "./index.vue";

fyCard.install = function (app) {
    app.component("fyCard", fyCard);
};

export { fyCard };
export default fyCard;

fuyuComp/src/packages/fyList/index.vue

<template>
    <div class="fy-list">
        我是 fyList 组件
    </div>
</template>
<script lang="ts" setup></script>
<style lang="scss" scoped></style>

fuyuComp/src/packages/fyList/index.ts

import fyList from "./index.vue";
fyList.install = function (app) {
    app.component("fyList", fyList);
};

export { fyList };
export default fyList;

fuyuComp/src/packages/index.ts 导出所有组件

import fyCard from "./fyCard/index";
import fyList from "./fyList/index";
import "../theme-chalk/index.scss";

const components = {
    fyCard,
    fyList,
};

const install = function (app) {
    Object.keys(components).forEach((key) => {
        app.component(key, components[key]);
    });
};

export { fyCard, fyList };
export default {
    install,
};

fuyuComp/src/packages/index.d.ts

fuyuComp/src/resolver.ts

import type {
    ComponentResolveResult,
    ComponentResolver,
} from "unplugin-vue-components/types";

function getIoResolved(name: string): ComponentResolveResult {
    const packageName = "fuyu-comp";

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

    //因为name传入进来时首字母是大写的,但我们的组件首字母是小写的,所以需要对组件首字母大写转小写
    const compName = name.replace(name[0], name[0].toLocaleLowerCase());

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

const FuyuCompResolver = (): ComponentResolver => {
    return {
        type: "component",
        resolve: (name) => {
            //name就是组件的名称,name传入进来时,首字母默认就是大写的
            if (name.startsWith("Fy")) {
                //这里对是否为fy开头的组件做一个过滤处理
                return getIoResolved(name);
            }
        },
    };
};

export { FuyuCompResolver };
export default FuyuCompResolver;

fuyuComp/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(), //使用的typescript,需要生成*.d.ts声明文件
    ],
    build: {
        minify: true,
        lib: {
            entry: path.resolve(__dirname, "./src/resolver.ts"),
            name: "name",
            fileName: (format) => {
                if (format === "es") {
                    return "resolver.mjs";
                } else {
                    return "resolver.cjs";
                }
            },
            formats: ["es", "cjs"],
        },
        rollupOptions: {
            // 确保外部化处理那些你不想打包进库的依赖
            external: ["vue"],
            output: {
                dir: path.resolve(__dirname, "./dist"),
            },
        },
        emptyOutDir: false,
    },
});

fuyuComp/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: "fuyu-comp", //组件名
            fileName: (format) => `fuyu-comp.${format}.ts`,
        },
        rollupOptions: {
            // 确保外部化处理那些你不想打包进库的依赖
            external: ["vue"],
            output: {
                // 在 UMD 构建模式下为这些外部化的依赖提供一个全局变量
                globals: {
                    vue: "Vue",
                },
                // dir: resolve(__dirname, 'dist') //打包输出目录
            },
        },
    },
});

修改【src/package.json】文件

{
  "name": "fuyu-comp",
  "private": false,
  "version": "0.0.1",
  "files": [
    "dist"
  ],
  "type": "module",
  "style": "./dist/style.css",
  "main": "./dist/fuyu-comp.umd.ts",
  "module": "./dist/fuyu-comp.es.ts",
  "typings": "./dist/packages/index.d.ts",
  "exports": {
    ".": {
      "types": "./dist/packages/index.d.ts",
      "import": "./dist/fuyu-comp.es.ts",
      "require": "./dist/fuyu-comp.umd.ts"
    },
    "./resolver": {
      "types": "./dist/resolver.d.ts",
      "import": "./dist/resolver.mjs",
      "require": "./dist/resolver.cjs"
    },
    "./*": [
      "./*",
      "./*.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": {
    "element-plus": "^2.3.14",
    "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": "^3.5.3",
    "vue-tsc": "^1.6.5"
  },
  "description": "### 安装 * npm install --save fuyu-comp",
  "repository": {
    "type": "git",
    "url": "https://gitee.com/xxxxx/fuyu-comp.git"
  },
  "keywords": [
    "fy"
  ],
  "author": "fuyu",
  "license": "ISC"
}

8、打包

npm run build

打包后生成目录如下图
在这里插入图片描述

9、发布 npm

  1. 登录:npm login
    如果报错:npm ERR! Unexpected token < in JSON at position 0 while parsing near ‘<!DOCTYPE HTML PUBLI…’
    依次输入:
    npm config get registry
    npm config set registry https://registr.npmjs.org 【切换为npm镜像】
    npm login
    如果还报错,依次输入:【这次报错应该是网络错误】
    npm config get proxy
    npm config get https-proxy
    npm config set registry https://registry.npmjs.org
    npm login
  2. 输入账号:
  3. 输入:密码 【密码输入是看不见的,输入了就行】
  4. 输入邮箱:643164248@qq.com 【邮箱会收到验证码】
  5. 输入:验证码
  6. 发布:npm publish

二、创建另一个工程,测试使用组件

1、创建新的工程

npm init vite@latest useDemo --template vue
…此处省略创建步骤

2、安装组件插件

npm i fuyu-comp

3、注册组件插件的方式

(1)全局注册

【main.ts】全局注册组件

import fuyuComp from "fuyu-comp";
import "fuyu-comp/dist/style.css";

app.use(fuyuComp);

【xxx.vue】使用组件

<template>
    <fyCard></fyCard>
    <fyList></fyList>
</template>

(2)手动按需引入

【main.ts】全局引入样式

import "../theme-chalk/index.scss";

【xxx.vue】使用组件时再注册组件

<script setup lang="ts">
import { fyCard} from "fuyu-comp";
</script>
<template>
    <fyCard></fyCard>
</template>

(3)使用插件 unplugin-vue-components 按需引入 推荐使用此方式!!!

安装

npm i unplugin-vue-components -D

【vite.config.ts】配置按需引入
在这里插入图片描述

(4)使用插件 unplugin-vue-components 按需引入 若组件内部没有配置resolver.ts的组件插件,可使用此方式

安装

npm i unplugin-vue-components -D

【vite.config.ts】配置按需引入
在这里插入图片描述

三、关于组件内部使用其他组件插件,比如element-plus

1、组件工程安装element-plugin,并进行全局注册。 不推荐此方式

此种方式在使用此插件时,只有进行全局注册,组件内部使用的element-plus的组件才会生效
手动按需引入、插件按需引入都不生效。
全局注册还会使得组件插件变大
所以不推荐使用此种方式!!!

(1)安装element-plus

npm i element-plugin

(2)全局注册 element-plus

在【fuyuComp/src/packages/index.ts】中加入代码
在这里插入图片描述

(3)在组件中使用element-plus

在【fuyuComp/src/packages/fyCard/index.vue】文件直接使用

(4)修改插件版本

在【fuyuComp/package.json】文件中修改插件版本
在这里插入图片描述

(5)打包发布至npm

npm run build
npm publish

2、组件工程安装element-plugin,并进行按需注册。简易版

此种方式在使用组件插件时无论是全局注册、还是手动按需、插件按需注册都生效。

(1)安装element-plus

npm i element-plugin

(2)全局引入element-plus 样式

在【fuyuComp/src/packages/index.ts】中加入代码
在这里插入图片描述

(3)在【fuyuComp/src/packages/fyCard/index.vue】文件引入使用

在这里插入图片描述

(4)修改插件版本

在【fuyuComp/package.json】文件中修改插件版本
在这里插入图片描述

(5)打包发布至npm

npm run build
npm publish

3、组件工程安装element-plugin,并进行按需注册。完善版 推荐使用!!!

(1)安装element-plus

npm i element-plugin

(2)新建在src文件下新建目录plugins存放第三方插件的按需引入

在这里插入图片描述
fuyuComp/src/plugins/elementPlus/index.ts

import "element-plus/dist/index.css";
import en from "element-plus/es/locale/lang/en";

const install = (app, opts = {}) => {
    app.provide("$locale", opts.locale ? opts.locale : en);
};

export default {
    install,
};

fuyuComp/src/plugins/index.ts

import elementPlus from "./elementPlus";

export default {
    elementPlus,
};

(3)新建在src文件下新建组件fyConfigProvider存放国际化语言配置

在这里插入图片描述
fuyuComp/src/packages/fyConfigProvider/index.vue

<template>
    <el-config-provider :locale="locale">
        <slot></slot>
    </el-config-provider>
</template>

<script lang="ts" setup>
import { ElConfigProvider } from "element-plus";
defineProps({
    locale: {
        //语言包
        type: Object,
    },
});
</script>

fuyuComp/src/packages/fyConfigProvider/index.ts

import fyConfigProvider from "./index.vue";

fyConfigProvider.install = function (app) {
    app.component("fyConfigProvider", fyConfigProvider);
};
export { fyConfigProvider };
export default fyConfigProvider;

(4)在【fuyuComp/packages/index.ts】中加入代码,注册插件

在这里插入图片描述

(5)例如在fyCard组件中使用到国际化

在这里插入图片描述

(6)修改插件版本

在【fuyuComp/package.json】文件中修改插件版本
在这里插入图片描述

(7)打包发布至npm

npm run build
npm publish

(8)在另一个工程下载使用组件插件

npm i fuyu-comp

全局注册,配置国际化语言

【main.ts】
在这里插入图片描述

按需使用,配置国际化语言

在【vite.config.ts】配置,使用unplugin-vue-components按需引入组件插件
在这里插入图片描述
在【APP.vue】文件,使用fyConfigProvider组件来配置国际化语言
在这里插入图片描述

四、git下载完整示例代码

包含:组件插件工程fuyuComp、使用组件插件的工程useDemo

https://github.com/FuyuMiracle/npm-publish-comp-demo.git

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值