Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

vite 插件编写及断点调试 #38

Open
jsonz1993 opened this issue Feb 11, 2022 · 0 comments
Open

vite 插件编写及断点调试 #38

jsonz1993 opened this issue Feb 11, 2022 · 0 comments
Labels

Comments

@jsonz1993
Copy link
Owner

背景

前段时间在改造旧项目的时候,发现vite不支持自定义css-module的匹配,只支持默认的 .module.css 的后缀名。关于这个问题,在 github issues 已经有好多个讨论,support custom css modules suffixConfigure files to be processed as css-modulesSupport CSS Module configurable

这个问题其实社区也有解决的插件,比如 vite-plugin-transform-css-modules ,但是这个插件是利用babel来处理,可能会有点重(this one uses babel for parsing so it may be a bit heavy),而且更关键的一点是,vite内部就有css plugin用于处理这些包括css module等的css处理,我们外部又重新写了一个插件去处理css module,让人觉得很别扭。

如果是从vite内部去处理,那么这个问题就变得很简单,无非是在vite加多一个配置,从 .module.css 变成用配置来获取是否需要 css module 处理。于是我火速提了一个 PR feat(css): support custom regexp of css modules 改动的代码量也很少,只是加多了 一个配置判断。

// 核心改动
function isCssModule(
  modulesOptions: CSSOptions['modules'],
  id: string
): boolean {
  if (modulesOptions && modulesOptions.isCssModule) {
    const { isCssModule } = modulesOptions
    if (typeof isCssModule === 'function') {
      return isCssModule(id)
    } else if (
      typeof isCssModule === 'string' ||
      isCssModule instanceof RegExp
    ) {
      const regexp = new RegExp(isCssModule)
      return regexp.test(id)
    }
  }
  return modulesOptions !== false && cssModuleRE.test(id)
}

不过这个pr最终没有被通过,因为官方觉得增加一个选项会导致多很多文档和维护的工作量。而且认为这种事情要么你遵循官方的 .module 后缀,要么你写个插件去处理。

于是乎我把目光转向用插件去让内置的 css plugin 处理,而不是自己再实现 css module 的编译。

开发与调试

在编写插件之前,我们先要处理开发环境,至少能在运行时打断点,方便开发与调试。

1. git clone https://github.com/vitejs/vite
2. pnpm i
3. cd packages/vite && pnpm run dev
4. vsc 新建 launch.json
5. 开始断点调试代码
// launch.json
{
  // 使用 IntelliSense 了解相关属性。
  // 悬停以查看现有属性的描述。
  // 欲了解更多信息,请访问: https://go.microsoft.com/fwlink/?linkid=830387
  "version": "0.2.0",
  "configurations": [
    {
      "type": "pwa-node",
      "request": "launch",
      "name": "cli",
      "skipFiles": [
        "<node_internals>/**"
      ],
      // 传给vite 的参数
      "args": ["--config", "yourDemoPath/vite.config.ts", "--debug"],
      "program": "${workspaceFolder}/packages/vite/src/node/cli.ts",
      "cwd": "yourDemoPath",
      "sourceMaps": true,
      "outFiles": [
        "${workspaceFolder}/packages/vite/dist/**/*.js",
        "!**/node_modules/**"
      ],
    }
  ]
}

debbug

Vite 的插件和其他构件的插件基本一致,都是提供一些 hook ,然后在 hook API 中处理对应的逻辑,实现的思路就很简单了。

我这里的思路是:

首先,插件设置 enforce: pre ,这样能更快执行,因为有一些hook是 hookFirst(first non-null result is returned),比如我们要用到的 resolveId。

resolveId Hook,把我们要处理成 css module 的文件,返回成 xxx.module.ext 的形式,比如 basic.less => basic.module.less。这样当 vite/css plugin 处理时就会以为文件名是 .module.less,进而进行 css module 的处理。

最后因为我们这个 basic.module.less 实际是不存在的,所以需要在 load 中,如果访问的是我们虚构出来的文件,那么我们需要去读取真实的文件返回回去, fs.readFile('basic.less', 'utf-8')

具体代码实现可见 https://github.com/jsonz1993/vite-plugin-load-css-module

@jsonz1993 jsonz1993 added the vite label Jun 18, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

1 participant