随着 Vue.js 3.0 的正式发布,Vue 生态系统也进入了一个新的阶段。在 Vue.js 3.0 中,Vite 成为了默认的开发工具,并替代了 Vue CLI 作为推荐的构建工具。同时,NPM 作为 JavaScript 包管理器,对于开发者来说也是一个必备的工具。那么本文将介绍如何使用 Vue3、Vite 和 NPM 打包并发布一个 Vue 组件。

一、准备工作

首先需要确保本地已安装 Node.js 和 NPM以及typescript,可以通过 node -v , npm -v和tsc -v 命令进行检查。如果没有安装,则需要先下载安装。

然后需要创建一个空文件夹,作为项目的根目录。

二、初始化项目

2.1初始化:

npm init

按照提示填写相关信息,生成 package.json 文件。


2.2创建typescript配置

执行

tsc --init

这时就会生成tsconfig.json配置文件


2.3安装 Vue3 和 Vite

npm install vue vite -D

-g:全局安装
-D:开发依赖,适合我们在开发阶段使用的依赖,包名会被注册到package.json中的devDependencies中,一般这种包只有在开发时使用,在开发完打包后我们可以在没有这些包的情况下继续运行项目。例如:eslit,less等
-S:生产环境,适合我们打包部署后还可以继续进行使用的包,包名会被注册到package.json中的Dependencies中,在开发完打包后需要继续使用才能正常运行的包,例如:echarts,jquery等

问:在这里为什么都选择-D?
答:在创建项目的时候我们也会安装vue和vite,所以在这里没必要在安装此插件的时候再次安装


2.4 目录结构

在这里插入图片描述
安装完毕后可以向我上面这样创建相应的ts文件和d.ts申明文件


三、编写代码

3.1 逻辑文件代码

在这里,我用的是之前写过的自定义指令-水印代码,关于自定义指令的实现请参照我另一篇博客:Vue3 自定义指令

代码如下:

//src/index.ts

import type { App } from "vue";
// watermark 样式
let style = `
display: block;
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
background-repeat: repeat;
pointer-events: none;
opacity:0.5;
`;

const getDataUrl = (binding: any) => {
  const rotate = -20;
  const canvas = document.createElement("canvas");
  // canvas.style.width = "500";
  // canvas.style.height = "500";
  const ctx = canvas.getContext("2d");

  ctx?.rotate((rotate * Math.PI) / 180);
  ctx.font = binding.font;
  ctx.fillStyle = binding.fillStyle;
  ctx?.fillText(binding.text || "机密文件", -10, 108);

  return canvas.toDataURL("image/png");
};

const waterMarker = {
  mounted(el: HTMLElement, binding: any) {
    init(el, binding);
  },
};

// 初始化
const init = (el: HTMLElement, binding: any = {}) => {
  // 设置水印
  setWaterMark(el, binding.value);
  // 监控
  createObserver(el, binding.value);
};

// 设置水印
const setWaterMark = (el: HTMLElement, binding: any = {}) => {
  const url = getDataUrl(binding);

  // 创建 waterMark
  const waterMark = document.createElement("div");
  waterMark.className = `water-mark`;
  style = `${style}background-image: url(${url});`;
  waterMark.setAttribute("style", style);
  el.setAttribute("style", "position: relative;");
  el.appendChild(waterMark);
};

const createObserver = (el: HTMLElement, binding: any) => {
  const waterMarkEl = el.querySelector(".water-mark");
  // Firefox和Chrome早期版本中带有前缀
  const MutationObserver =
    window.MutationObserver ||
    window?.WebKitMutationObserver ||
    window?.MozMutationObserver;
  // 监听节点变化
  const observer = new MutationObserver((mutationsList) => {
    console.log("mutationsList", mutationsList);
    if (mutationsList.length) {
      const { removedNodes, type, target } = mutationsList[0];
      const currStyle = waterMarkEl?.getAttribute("style");

      if (removedNodes[0] === waterMarkEl) {
        // 停止观察
        observer.disconnect();

        init(el, binding);
      } else if (
        type === "attributes" &&
        target === waterMarkEl &&
        currStyle !== style
      ) {
        waterMarkEl.setAttribute("style", style);
      }
    }
  });

  observer.observe(el, {
    childList: true,
    attributes: true,
    subtree: true,
  });
};

const install = (app: App) => {
  app.directive("waterMarker", waterMarker);
};

export default {
  install,
};


3.2 申明文件代码

//index.d.ts
import type { App } from "vue";
declare const waterMarker: {
  install: (app: App) => void;
};
export default waterMarker;


四、配置Vite

import { defineConfig } from "vite";

export default defineConfig({
  build: {
    lib: {
      // Could also be a dictionary or array of multiple entry points
      entry: "src/index.ts",
      name: "waterMarker",
      // the proper extensions will be added
      fileName: "water-marker",
    },
    rollupOptions: {
      // 确保外部化处理那些你不想打包进库的依赖
      external: ["vue"],
      output: {
        // 在 UMD 构建模式下为这些外部化的依赖提供一个全局变量
        globals: {
          waterMarker: "waterMarker",
        },
      },
    },
  },
});


这里通过 lib 配置项告诉 Vite 要打包的是一个库文件,并指定入口文件、库名称和输出文件名。同时,使用 rollupOptions 配置项将 Vue 外部化,以便在构建时不会将其打包进组件文件中,从而减小打包体积。


五、配置命令

5.1 编写打包命令

在 package.json 文件中添加打包命令:

{
  "scripts": {
    "build": "vite build"
  }
}

5.2 打包组件

执行以下命令进行打包:

npm run build

打包完成后,会在项目根目录下生成一个 dist 文件夹
在这里插入图片描述
接着,需要在 package.json 文件中添加必要的字段:

{
  "name": "water-marker-vue",
  "version": "0.0.2",
  "description": "",
  "main": "dist/my-lib.umd.js",
  "module":"dist/my-lib.mjs",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "build":"vite build"
  },
  "author": "",
  "license": "ISC",
  "files": [
    "dist",
    "index.d.ts"
  ],
  "devDependencies": {
    "vite": "^4.5.0",
    "vue": "^3.3.7"
  }
}



注意

  • name 字段必须是唯一的,且不能包含大写字母和空格
  • main 字段要指向打包后的 UMD 格式文件;
  • module 字段要指向打包后的 ES Module 格式文件;
  • files 字段指定了应该包含在发布包中的文件;发布时默认会包括 package.json,license,README 和main 字段里指定的文件。忽略 node_modules,lockfile 等文件。一般情况下,files 里会指定构建出来的产物以及类型文件,而 src,test 等目录下的文件不需要跟随发布。
  • dependencies 字段指定了依赖的 Vue和Vite 版本范围

六、发布

6.1 注册账户(第一次使用)

npm官网上注册并登录
在这里插入图片描述


6.2 命令登录 NPM 账户

npm login   # 登录 NPM 账户

6.3 发布

npm publish # 发布组件

发布成功后你可以npm上搜索你发布的包名,若能搜索到。则发布成功。
注意:包名一定是唯一的,且不能包含大写字母和空格。否则你将会出现以下的错误
在这里插入图片描述

七、下载插件并使用

经过以上步骤,我们就成功地将一个 Vue3 组件打包并发布至 NPM 了,接下来我们可以npm install 命令安装并使用该组件

import waterMarker from "water-marker-vue";

app.use(waterMarker);

<div class="box" v-water-marker="watermarkObj"></div>

以上为主要代码,我们便可以在页面中看到水印样式

在这里插入图片描述

Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐