For AI agents: the complete documentation index is available at https://rsdoctor.rs/zh/llms.txt, the full documentation bundle is available at https://rsdoctor.rs/zh/llms-full.txt, and this page is available as Markdown at https://rsdoctor.rs/zh/guide/rules/rule-custom.md.
close
  • 简体中文
  • 自定义扩展规则

    功能介绍

    考虑到用户会有特有的规则定义需求,Rsdoctor 除了内部已有的规则外,还提供了外部接口供用户定制自己的规则检查。外部扩展接口通过 extends 字段配置到 Rsdoctor 插件上,配置也放在 rules 字段内。

    • 示例如下:
    // src/rules/assets-count-limit.ts
    import { defineRule } from '@rsdoctor/core';
    
    export const AssetsCountLimit = defineRule(() => ({
      meta: {
        category: 'bundle',
        severity: 'Warn',
        title: 'assets-count-limit',
        defaultConfig: {
          limit: 10,
        },
      },
      check({ chunkGraph, report, ruleConfig }) {
        const assets = chunkGraph.getAssets();
    
        if (assets.length > ruleConfig.limit) {
          report({
            message: 'The count of assets is bigger than limit',
            detail: {
              type: 'link',
              link: 'https://rsdoctor.rs/zh/guide/start/quick-start', // This link just for show case.
            },
          });
        }
      },
    }));
    // rsbuild.config.ts
    import { RsdoctorRspackPlugin } from '@rsdoctor/core';
    import { AssetsCountLimit } from './rules/assets-count-limit';
    
    export default {
      tools: {
        bundlerChain: (chain) => {
          chain.plugin('Rsdoctor').use(RsdoctorRspackPlugin, [
            {
              linter: {
                level: 'Error',
                extends: [AssetsCountLimit],
                rules: {
                  'assets-count-limit': [
                    'on',
                    {
                      limit: 1, // rule custom configs
                    },
                  ],
                },
              },
            },
          ]);
        },
      },
    };

    可按照下面自定义规则详细步骤进行规则定义及编写。

    自定义规则步骤

    1. 安装

    编写自定义规则时,安装 @rsdoctor/core 并使用 @rsdoctor/core 中的 defineRule 函数来定义统一的 Rsdoctor 规则。

    npm
    yarn
    pnpm
    bun
    deno
    npm add @rsdoctor/core -D

    2. 编写规则

    编写规则需要先使用defineRule函数,它内部输入一个函数,此函数返回一个固定格式的对象。参考按照如下实例:

    // src/rules/some-rule.ts
    import { defineRule } from '@rsdoctor/core';
    
    const ruleTitle = 'check-rule';
    type RuleConfig = { limit: number };
    
    export const CheckRule = defineRule<typeof ruleTitle, RuleConfig>(() => ({
      meta: {
        category: 'bundle', // rule category
        severity: 'Warn', // rule severity
        title: ruleTitle, // rule title
        defaultConfig: { limit: 10 },
      },
      check({ chunkGraph, report, ruleConfig }) {
        if (chunkGraph.getAssets().length > ruleConfig.limit) {
          report({ message: 'Too many assets' });
        }
      },
    }));

    其中,meta 字段为此规则的固定配置和内容,check 字段为包含规则检查具体逻辑的回调,它们的类型如下。

    meta 对象

    外部规则的元数据类型参见:ExtendRuleMeta。

    属性含义
    • meta
      • category
        • info: 定义规则分类。
        • type: 'compile' | 'bundle'。
      • title
        • info:规则标题,用于在 Rsdoctor 报告页面中展示。
        • type:string | 泛型,用户可通过泛型下传。
      • severity
        • info: 规则等级。
        • type: 外部规则使用 'Ignore' | 'Warn' | 'Error'。
        • default: 'Warn'
      • defaultConfig
        • info:规则默认配置。自定义规则中可能需要特有的配置,defaultConfig 可用于配置默认的规则配置。
        • type:泛型,用户可通过泛型定义。如上面示例。
      • referenceUrl
        • info: 规则文档链接。
        • type: string。

    check 函数

    check 函数主要是用来做规则判断的,参数 ruleContext 是 Rsdoctor 在构建分析过程中所整合到的所有构建信息,类型定义如下。 可以在 check 函数的函数体内利用构建信息进行自定义的规则判断。判断后,如果规则检查出问题,可通过参数中的 report 方法进行上报,具体参见下一步。

    CheckCallback 类型
    type CheckCallback<Config = DefaultRuleConfig> = (
      context: RuleCheckerContext<Config>,
    ) => void | Promise<void>;

    RuleCheckerContext 类型定义请查看详情

    示例

    上面的 CheckRule 示例会检查资源数量,并在超过 ruleConfig.limit 时上报问题。

    3. 上报规则结果

    上报错误需要使用check 回调函数的参数中的 report 方法,report 方法的参数主要是包含以下的几个部分:

    • message:错误消息
    • document:文件数据, 用于描述报错代码文件位置及代码位置。
    • suggestions:规则建议。
    • detail:详细信息,主要是提供给前端的额外数据。

    详细类型定义查看:ReportData

    4. 规则结果展示

    report 函数会把自定义规则的错误信息传递给 compilation 的 errors 或 warnings,会在构建的时候在终端中输出构建规则结果提示,甚至中断构建。 同时,Rsdoctor 会在警示列表中展示自定义规则的结果,详情参见下方展示组件。

    • 基本规则警示组件

    展示组件

    基本规则警示组件

    • 组件类型

      LinkRule Type

    • 组件输入

      • type

        • 使用组件类型。
        • value: 'link'。
      • title

        • 规则标题。
        • type: string。
      • description

        • 规则描述。数据来源为 report 中的 message 或 detail.description:
          report({
            message: 'The count of assets is bigger than limit',
            detail: {
              // ......
              description: 'The count of assets is bigger than limit',
            },
          });
        • type: string。
      • level

        • 规则级别。
        • type:warn | error。
      • link:

        • 规则详情。数据来源为 detail.link:
          report({
            detail: {
              // ......
              link: 'http://....',
            },
          });
        • type:string。
    • 示例

    report({
      message: 'The count of assets is bigger than limit',
      detail: {
        type: 'link',
        link: 'https://rsdoctor.rs/zh/guide/start/quick-start', // This link just for show case.
      },
    });
    • 组件展示

    类型定义

    ExtendRuleMeta

    interface ExtendRuleMeta<
      Config = DefaultRuleConfig,
      Title extends DefaultRuleTitle = DefaultRuleTitle,
    > {
      title: Title;
      category: 'compile' | 'bundle';
      severity: 'Ignore' | 'Warn' | 'Error';
      referenceUrl?: string;
      defaultConfig?: Config;
    }

    这里展示的是外部规则接受的元数据。内部规则还需指定规则代码,并使用数值形式的严重等级。

    RuleCheckerContext

    interface RuleCheckerContext<Config> {
      /** 工程根目录 */
      root: string;
      /** 当前规则配置 */
      ruleConfig: Config;
      /** 工程配置 */
      configs: ConfigData;
      /** 构建错误 */
      errors: Error[];
      /** Chunk 图 */
      chunkGraph: ChunkGraph;
      /** 模块图 */
      moduleGraph: ModuleGraph;
      /** 依赖图 */
      packageGraph: PackageGraph;
      /** loader 数据 */
      loader: LoaderData;
      /**
       * 上报错误
       * @param {any} error - 错误数据
       * @param {any} replacer - 替换原错误
       */
      report(error: ReportData, replacer?: any): void;
    }

    ReportData

    interface ReportData {
      /** 错误消息 */
      message: string;
      /** 文件数据 */
      document?: ReportDocument;
      /** 诊断建议 */
      suggestions?: Suggestion;
      /**
       * 详细信息
       *   - 主要是提供给前端的额外数据
       */
      detail?: any;
    }
    
    /** Error file information */
    interface ReportDocument {
      /** file path */
      path: string;
      /**  Is it a transformed code */
      isTransformed?: boolean;
      /** code content */
      content: string;
      range: Range;
    }

    LinkRuleStoreData

    interface BaseRuleStoreData extends Pick<RuleMessage, 'code' | 'category'> {
      /**
       * unique of error
       */
      id: number | string;
      /**
       * title of alerts
       */
      title: string;
      /**
       * description of alerts
       */
      description?: string;
      /**
       * level of error
       */
      level: 'warn' | 'error';
      /**
       * rule doc link
       */
      link?: string;
    }
    
    interface LinkRuleStoreData extends BaseRuleStoreData {
      type: 'link';
    }

    CodeViewRule

    interface CodeViewRuleStoreData extends BaseRuleStoreData {
      type: 'code-view';
      file: {
        /**
         * file path
         */
        path: string;
        /**
         * the code content
         */
        content: string;
        /**
         * fix highlight range in source
         */
        ranges?: SourceRange[];
      };
    }
    
    /** Source code location */
    interface SourcePosition {
      line?: number;
      column?: number;
      index?: number;
    }
    
    /** Source code range */
    interface SourceRange {
      start: SourcePosition;
      end?: SourcePosition;
    }

    工具

    AST 处理

    规则的 check 回调提供 moduleGraph,可以通过 moduleGraph.getModules() 获取模块。如需基于 AST 检查,请使用支持项目语法的解析器解析 module.getSource().source 中可用的原始代码,并跳过没有源码的模块。@rsdoctor/core 不导出内部使用的 parser、asserts 和 Document。

    数据上报

    请跳转到数据上报进行查看