跳至主要內容

自己开发一个vuepress插件

MonoLogueChi建站笔记涨姿势大约 4 分钟

尝试自己开发一个 vuepress 插件,记录一下过程。

提示

本文以 vuepress1.x 为例,其他版本会有不同,仅供参考。

提示

经验证,本文部分代码有 bug,仅作为插件开发演示,请勿直接使用本文提供的代码。

提示

vuepress-plugin-smplayeropen in new window 经数次迭代更新,与初始版本已有较大差别。

咱们一边看 DEMO 一边讲。

基础知识

学习资料

JS CSS NODE 等基础的东西就省略了。

Vuepress Debug

开发插件一定要学会 Debug,否则排除错误只能靠猜。

vuepress dev docs --debug

我开发的插件

vuepress-plugin-smplayeropen in new window

开发插件

从 123 开始

直接先来最简单的,按照 Vuepress 的思想,config.js 也是一个插件,先编写一个最简单的插件来试试看。

示例来自 https://v1.vuepress.vuejs.org/plugin/option-api.html#nameopen in new window

// .vuepress/config.js
module.exports = {
  plugins: [
    [
      (pluginOptions, context) => ({
        name: "my-xxx-plugin",
        // ... the rest of options
      }),
    ],
  ],
};

然后运行 vuepress dev docs 就可以看到 my-xxx-plugin 插件被加载了。

本地调试插件

先说一下怎么调试本地插件,这里看完了别着急动手,一起看下一节。

这里有两种方式。

require 加载插件

第一种我不太推荐,方法仅供参考。

.vuepress 目录下创建一个目录,例如 my-xxx-plugin,然后创建为一个 npm 包,具体方法可以百度,也可以直接执行 npm init,然后安装引导运行。

再编写入口文件 index.js 和其他文件。

config.js 中引入插件包

module.exports = {
  plugins: [require("./my-xxx-plugin")],
};

pnpm 或 yarn

第二种方法是使用 pnpmyarn

这里推荐一个 pnpm,绝对是最好用的包管理工具,下面以 pnpm 为例,yarn 可以自行百度。

在 vuepress 项目之外的目录下创建一个 npm 包,具体方法可以百度。然后编写插件,再安装本地插件。

pnpm install ../vuepress-plugin-smplayer -D

编写插件

一些 npm 包基础的东西就不写了,这里就简单记录一些重要的内容。

入口文件

Vuepress 官网open in new window也明确说明了一点

A VuePress plugin module should be a CommonJS Module because VuePress plugins runs on the Node.js side.

上面说的这一点很重要,要牢记,再强调一遍,这句话很重要。

我要开发的这个插件非常简单,就是把几个 vuepress 组件注册为全局组件。

//index.js

const { resolve } = require("path");
const merge = require("deepmerge");
const config_default = require("./config/config_default");

module.exports = (opts, context) => ({
  define() {
    const config = merge(config_default, opts);
    return {
      BILIBILI: config.bilibili,
    };
  },
  enhanceAppFiles: resolve(__dirname, "utils/", "enhanceAppFile.js"),
});

简单解释一下,config_default.js 是插件的默认配置文件,opts 参数是从 config.js 中传入的配置。
我用了 deepmerge 合并配置。这仅仅是一个设计思路,有自己的想法就不要看这里了,重点是开发插件。

define 部分可以直接看 vuepress 的文档open in new window

enhanceAppFiles 也可以直接去看 vuepress 的文档open in new window

这两部分只是我用到的,具体请根据实际需求写。

enhanceAppFiles 内容就是注册 vue 组件,没啥好说的。

enhanceAppFiles.js

//enhanceAppFiles.js

import APlayer from "../components/APlayer.vue";

export default ({ Vue }) => {
  Vue.component("APlayer", APlayer);
};

Vue 组件

然后就是具体的组件,下面是一个简单示例。这一部分就是 Vue 相关的知识,了解怎么写 Vue 组件就 OK 了。

// APlayer.vue
<template>
  <div class="smplayer">
    <div ref="mmplayer" />
  </div>
</template>

<script>
import merge from "deepmerge";

export default {
  props: {
    src: {
      type: Object,
      required: true,
    },
    hls: {
      type: Boolean,
      default: DPLAYER.hls,
      required: false,
    },
  },
  mounted() {
    this.InitPlayer();
    this.$nextTick(() => {
      if (this.src.fixed) {
        const app = document.querySelector("#app");
        app.append(this.$el);
      }
    });
  },

  beforeDestroy() {
    this.DestroyPlayer();
  },
  methods: {
    InitPlayer() {
      if (this.hls && window && !window.Hls) {
        import(/* webpackChunkName: "hls" */ "hls.js/dist/hls.min.js").then(
          ({ default: Hls }) => {
            window.Hls = Hls;
          }
        );
      }

      Promise.all([
        import(/* webpackChunkName: "aplayer" */ "aplayer/dist/APlayer.min.js"),
        import(
          /* webpackChunkName: "aplayer" */ "aplayer/dist/APlayer.min.css"
        ),
      ]).then(([{ default: APlayer }]) => {
        let src = merge(APLAYER.src, this.src);
        this.player = new APlayer({
          container: this.$refs.mmplayer,
          ...src,
        });
      });
    },

    DestroyPlayer() {
      if (this.player && !this.src.fixed) {
        this.player.destroy();
      }
    },
  },
};
</script>

简单来说一下,可以接收参数 srchls 传入,在 mounted 初始化播放器,在 beforeDestroy 销毁播放器。大概就是这么简单。

测试插件

写完上面三个文件,然后用 pnpmyarn 安装插件,然后在 config.js 配置,再创建或修改文章测试。

<APlayer :src="aplayer" />

<script>
  export default {
    data() {
      return {
        aplayer: {
          audio: [
            {
              name: "年轻人要热爱祖国",
              artist: "音阙诗听/赵方婧",
              url: "/assets/audio/年轻人要热爱祖国.mp3",
              cover:
                "https://sm.sm9.top/api/music?server=Tencent&type=pic&id=001gv6xI4BNGiP",
              lrc: "/assets/audio/年轻人要热爱祖国.lrc",
            },
          ],
        },
      };
    },
  };
</script>

发布插件

如果是自己用的话,提交到 github 上,pnpm 或者 yarn 就可以直接安装,如果是想发布成一个插件,供大家使用,就使用 npm 发布。

注册 npm 账号open in new window,然后登陆,再发布就 OK 啦。

npm login

npm publish