使用vue-cli 3.x 开发并发布一个插件到npm

1,380 阅读2分钟

之前写了《发布一个npm包》,接着尝试写一个简单的基于vue的插件并发布到npm。

插件功能:

1.全屏loading插件

2.调用show(tips)方法启用 - tips为loading时的文案

3.调用hide()方法关闭

这次的插件使用了vue-cli 3.x。

一、vue-cli 3.x 初始化项目

首先确保自己电脑上安装了vue-cli 3.x,如果之前安装了低于3.0版本的可以手动卸载,重新安装3.0以上

1.卸载低版本的 vue-cli

npm uninstall vue-cli -g

2.安装新版本 @vue/cli

npm install -g @vue/cli

3.创建项目

vue create project-name  // project-name自定义项目名称

4.启动项目

npm run serve

二、新建插件目录

我在src下新建lib文件夹来存放我的插件

lib目录下新建 .vue文件写业务代码

lib目录下新建 .js文件作为插件的入口

新建完当前目录如下:

三、开发插件

1.在 .vue文件写插件的业务逻辑

<template>
  <div v-if="display" id="loadingContainer">
    <div class="textContainer">
      <div class="loading">
        <div class="circle circle1">
          <span></span>
          <span></span>
          <span></span>
          <span></span>
        </div>
        <div class="circle circle2">
          <span></span>
          <span></span>
          <span></span>
          <span></span>
        </div>
        <div class="circle circle3">
          <span></span>
          <span></span>
          <span></span>
          <span></span>
        </div>
      </div>
      <div class="text">{{ tips }}</div>
    </div>
  </div>
</template>

<script>
export default {
  // 注意name属性,组件的标签就是用这个name属性的值
  name: "FullScreenLoadingPlugin",

  data() {
    return {
      display: false,
      tips: "",
      opTips: "加载中..."
    };
  },

  methods: {
    show(tips) {
      this.tips = tips || this.opTips;
      this.display = true;
    },

    hide() {
      this.display = false;
    }
  }
};
</script>

<style lang="scss" scoped>
#loadingContainer {
  position: fixed;
  left: 0;
  right: 0;
  top: 0;
  bottom: 0;
  background-color: rgba($color: #000000, $alpha: 0.5);
  
  ...
  
<style>
  1. 入口文件 .js逻辑
// 引入业务代码的vue组件
import loading from "./FullScreenLoading";

// 定义一个插件的对象
const LoadingPlugin = {
  // vue规定插件必须暴露一个 install 方法
  // 第一个参数为vue构造器,第二个参数为可选的选项对象
  install(Vue, options) {
    // 使用vue构造器,Vue.extend()创建一个类
    const subClass = Vue.extend(loading);
    // 实例化子类,并挂载到HTMLElement实例上
    const Profile = new subClass({
      el: document.createElement("div")
    });
    document.body.appendChild(Profile.$el);
    // 处理可选的参数
    // 在Vue.use(xxx, options)的第二个参数传入tips则会初始化全屏加载中的默认文字
    // 例如Vue.use(xxx, { tips: "请稍等..." })
    if (options) {
      if (options.tips) {
        Profile.opTips = options.tips;
      }
    }
    // 添加实例方法,挂载到vue原型上
    Vue.prototype.$fullScreenLoading = Profile;
  }
};

// 导出对象
export default LoadingPlugin;

js文件中两个方法可以阅读vue官方文档:

install

Vue.extend()

到这,组件就开发完成了!

四、本地测试插件

npm run serve

这里我在Home.vue页面测试

<template>
  <div class="home">
    <img alt="Vue logo" src="../assets/logo.png" />
  </div>
</template>

<script>
// @ is an alias to /src
// import HelloWorld from "@/components/HelloWorld.vue";
import Vue from "vue";
import FullScreenLoadingPlugin from "../lib/index";
Vue.use(FullScreenLoadingPlugin);

export default {
  name: "Home",

  created() {
    this.$fullScreenLoading.show("请求中...");
    setTimeout(() => {
      this.$fullScreenLoading.hide();
    }, 2000);
    setTimeout(() => {
      this.$fullScreenLoading.show();
    }, 3000);
  }
};
</script>

测试完成继续下一步。

五、打包组件

vue-cli 给我们提供了库文件打包的命令

参考链接:库构建

vue-cli-service build --target lib --name outputName --dest myLib [entry]
// --targe 默认为构建应用,改为 lib 即可启用构建库模式
// --name 后面跟的是输出的文件名称
// --dest 后面跟的是输出目录,默认为dist,这里我改为plugin
// entry: 入口文件,默认src/App.vue,这里我改为 src/lib/index.js

在package.json文件的script中添加一个命令打包插件

"lib": "vue-cli-service build --target lib --name full-screen-loading-plugin --dest plugin src/lib/index.js"

执行命令npm run lib,打包组件 打包完成后,会输出如下文件:

这里有一个坑!

在上面打包完的文件里面 css 和 js 是分离的!导致插件发布到npm后样式丢失!

这里需要增加一个配置,让 css 样式强制内联在输出的 js 里面!

在根目录新建 vue.config.js 文件:

module.exports = {
  css: {
    extract: false
  }
};

这样打包出来就没有css文件了:

这些文件的含义在库构建里面有说明。

六、发布插件到npm

1.在根目录创建文件 .npmignore,忽略发布文件

.DS_Store
node_modules
/dist
/public
/src
babel.config.js
vue.config.js
*.map
*.html


# local env files
.env.local
.env.*.local

# Log files
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*

# Editor directories and files
.idea
.vscode
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?

2.更改 package.json 文件的信息

记得把 private 属性删除或者改为 false

name:包名,我这里用了带命名空间的;

author:作者;

version:版本号;

description:描述信息;

main:入口文件,这里应该是打包后的入口;

private:是否私有,这里必须是false才能发布到npm,默认false;

keywords:关键词描述。

3.发布

记得切回npm源

nrm use npm
npm login  // 登录
npm publish --access public  // 发布

发布成功:

npm官网搜索:

七、在项目中使用该组件

npm i @jackycai/full-screen-loading-plugin

main.js

import FullScreenLoadingPlugin from "@jackycai/full-screen-loading-plugin";
Vue.use(FullScreenLoadingPlugin);

// 或者添加自定义配置
Vue.use(FullScreenLoadingPlugin, { tips: "请稍等..." });

项目中调用:

this.$fullScreenLoading.show();
setTimeout(() => {
  this.$fullScreenLoading.hide();
}, 2000);

// 也可以在 show 方法中添加自定义的文字
this.$fullScreenLoading.show("全屏插件转圈圈...");

大功告成!

插件源码