Vite插件开发实战

本文共--字 阅读约--分钟 | 浏览: -- Last Updated: 2022-03-30

Vite是基于rollup打包的,有自己的封装的插件开发方式,还可以使用rollup插件。

以下插件是使用Vite自己插件开发方式开发的,具体文档在这里,该插件的作用是处理 public/index.html 模板时根据环境注释隐藏一些比如VConsole的开发环境调试工具的代码,此类代码在生产环境是不需要的。

interface EnvInfo {
  mode: string;
  command: string
}

export default function htmlEnv(): any {
  let envInfo = {} as EnvInfo;
  return {
    name: 'html-env',
    enforce: 'post',
    apply: 'build',
    config(config, env) {
      if (env) {
        envInfo = env;
      }
    },
    transformIndexHtml(html: string): any {
      const { mode } = envInfo;
      if (mode) {
        const regStr = `<!-- ${mode} ignore -->`;
        const reg = `(${regStr})(.|\n|\r)+(${regStr})`;
        return html.replace(new RegExp(reg, 'g'), '');
      }
      return html;
    },
  };
}

如果执行Vite命令是指明了–mode为prd,则效果会是这样。

将以下HTML中被注释 <!-- prd ignore --> 包裹的部分给删除掉。

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>
  <div id="app"></div>
  <!-- prd ignore -->
  <script src="https://unpkg.com/vconsole@latest/dist/vconsole.min.js"></script>
  <script>
    var vConsole = new window.VConsole();
  </script>
  <!-- prd ignore -->
</body>
</html>

以下是使用rollup插件开发方式开发的用于打包完成之后移动静态文件的插件

import fs from 'fs';
import path from 'path';
import globby from 'globby';

interface Options {
  hook?: string,
  targets: TargetConfig[],
}

interface TargetConfig {
 src: string | string[],
 dest: string
}

export default function move(options = {} as Options): any {
  const {
    hook = 'closeBundle',
    targets = [],
  } = options;

  let first = true;

  return {
    name: 'move',
    [hook]: async () => {
      if (first) {
        first = false;

        if (targets.length) {
          // eslint-disable-next-line no-restricted-syntax
          for (const target of targets) {
            const { dest, src } = target;
            if (!src || !dest) {
              throw new Error(`${JSON.stringify(target)} target must have "src" and "dest" properties`);
            }

            // eslint-disable-next-line no-await-in-loop
            const matchedPaths = await globby(src, {
              expandDirectories: false,
              onlyFiles: false,
            });

            matchedPaths.forEach((p) => {
              const fileAttr = path.parse(p);
              const { name, ext } = fileAttr;
              const destDir = dest.endsWith('/') ? dest : `${dest}/`;
              if (!fs.existsSync(destDir)) {
                fs.mkdirSync(destDir);
              }
              const destPath = `${destDir}${name}${ext}`;
              fs.renameSync(p, destPath);
            });
          }
        }
      }
    },
  };
}

使用

import { defineConfig, UserConfigExport } from 'vite';
import move from './rollup-plugin-move/index';

export default defineConfig(({ mode, command }) => {
  // 构建lib库时生效
  let config: UserConfigExport = {
    plugins: {
      move({
        targets: [
          {
            src: 'lib/js/*.css',
            dest: 'lib/style',
          },
        ],
      }),
    };
  }
  return config;
});