头图

爸爸,我会开发Vite插件啦!

前言

大家好,我是倔强青铜三。是一名热情的软件工程师,我热衷于分享和传播IT技术,致力于通过我的知识和技能推动技术交流与创新,欢迎关注我,微信公众号:倔强青铜三。

在开始创建自己的Vite插件之前,强烈推荐你先阅读官方文档关于插件开发的相关内容。这将帮助你更好地理解Vite的架构以及其插件系统的能力。此外,根据最佳实践,你的插件名称应该以vite-plugin为前缀。这样做可以更容易地与其他工具和更广泛的Vite生态系统进行集成。

为Vite创建插件是定制项目构建过程以满足特定需求的绝佳方式。在本文中,我将通过我自己的vite-plugin-pretty-module-classnames插件为例,向你展示如何创建一个插件。这个插件通过在生成的类名中添加文件名(去掉-module后缀)来增强CSS模块的处理方式,使它们更易于阅读和调试。

第1步:需求分析

在Vite中使用CSS模块时,会自动生成唯一的类名以避免冲突。然而,这些名称在大型项目中可能显得有些难以理解。我的插件通过在类名中添加文件名(去掉-module后缀)来解决这个问题,使它们更有意义,更易于使用。

第2步:创建哈希

插件的核心是getHash函数,它基于类名生成一个哈希值。我们使用crypto模块来创建一个SHA-256哈希值,并将其截断为五个字符:

import { createHash } from "crypto";

function getHash(input: string): string {
  return createHash("sha256").update(input).digest("hex").slice(0, 5);
}

这个函数确保每个类都有一个唯一的标识符附加在其名称上,防止任何潜在的冲突。

第3步:生成唯一的类名

接下来,我们有sanitizeModuleClassname函数,它通过组合文件名、原始类名和哈希值来创建一个新的类名:

function sanitizeModuleClassname(
  name: string,
  filename: string | undefined
): string {
  if (typeof filename !== "string") {
    throw new Error("文件名必须是字符串且不能未定义。");
  }

  const parts = filename.split("?")[0].split("/");
  const lastSegment = parts.pop();

  if (!lastSegment) {
    throw new Error("文件名必须包含一个有效的文件名。");
  }

  const baseFilename = lastSegment.replace(/(\.vue|\.module)?(\.\w+)$/, "");

  const classname = `${baseFilename}__${name}`;
  const hash = getHash(`${classname}`);

  return `${classname}_${hash}`;
}

这个函数处理文件名,去掉-module后缀和其他不必要的部分,如扩展名。然后通过添加生成的哈希值来形成一个新的类名。

第4步:与Vite集成

现在,是时候创建插件本身了。我们定义它为PrettyModuleClassnames函数,它返回一个插件对象:

import type { Plugin, UserConfig } from "vite";

export default function PrettyModuleClassnames(): Plugin {
  return {
    name: "vite-plugin-pretty-module-classnames",
    config(config: UserConfig, {}) {
      if (
        typeof config.css?.modules === "object" &&
        config.css.modules.generateScopedName
      ) {
        throw new Error(
          "自定义的generateScopedName设置已经存在。vite-plugin-pretty-module-classnames插件不能与其他generateScopedName设置一起使用。"
        );
      }

      const newCssConfig = {
        ...config.css,
        modules: {
          ...config.css?.modules,
          generateScopedName: sanitizeModuleClassname,
        },
      };

      return {
        ...config,
        css: newCssConfig,
      };
    },
  };
}

这个插件检查CSS模块的generateScopedName设置是否已经配置。如果是,插件抛出一个错误以防止冲突。如果不是,它将我们的sanitizeModuleClassname函数添加到配置中,确保类名现在包含文件名且没有-module后缀。

第5步:使用插件

要在你的项目中使用这个插件,只需将其添加到你的Vite插件数组中:

import prettyModuleClassnames from './path-to-your-plugin';

export default {
  plugins: [prettyModuleClassnames()],
};

现在,你的项目将为CSS模块生成更具描述性和信息性的类名,包含文件名和一个唯一的哈希值。

结论

创建Vite插件可能一开始看起来令人生畏,但实际上这是一个有趣且有益的过程。这个例子展示了如何轻松地定制Vite以满足你的需求。尝试编写你自己的插件,将使你的项目变得更好!


倔强青铜三
21 声望0 粉丝