You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过ESLint/Prettier实现字符串数组排序?自定义规则选哪款工具

用ESLint实现数组键字母排序更简单

首先明确:选ESLint更合适。Prettier的核心是统一代码格式(比如缩进、引号、换行),它不会触碰可能改变代码执行逻辑的操作,而数组元素的顺序属于逻辑范畴,Prettier本身不支持这类自定义规则,也不推荐用它做这类修改。ESLint则专门用于代码质量检查,支持自定义可修复规则,能精准操作AST(抽象语法树)实现你要的功能。

如何实现ESLint自定义规则

1. 编写自定义规则文件

在项目中创建一个规则文件,比如./eslint-rules/sort-keys-array.js,内容如下:

module.exports = {
  meta: {
    type: 'suggestion',
    fixable: 'code', // 开启自动修复能力
    docs: {
      description: '将字符串元素组成的数组按字母顺序排序',
    },
  },
  create(context) {
    return {
      // 监听数组表达式节点
      ArrayExpression(node) {
        // 过滤出有效的字符串字面量元素(跳过空元素)
        const validElements = node.elements.filter(el => 
          el && el.type === 'Literal' && typeof el.value === 'string'
        );
        if (validElements.length <= 1) return;

        // 获取当前数组的元素值和排序后的值
        const currentValues = validElements.map(el => el.value);
        const sortedValues = [...currentValues].sort((a, b) => a.localeCompare(b));

        // 已经排序则跳过
        if (currentValues.join(',') === sortedValues.join(',')) return;

        // 报告问题并生成修复方案
        context.report({
          node,
          message: '数组键请按字母顺序排序',
          fix(fixer) {
            // 保留原有的引号风格(单/双引号)
            const quote = validElements[0].raw[0];
            const sortedStr = sortedValues.map(val => `${quote}${val}${quote}`).join(', ');
            return fixer.replaceText(node, `[${sortedStr}]`);
          },
        });
      },
    };
  },
};

2. 在ESLint配置中引入规则

修改项目的.eslintrc.js,引入自定义规则:

module.exports = {
  // 其他原有配置(比如env、extends、parser等)
  rules: {
    // 启用自定义规则,设为error或warn
    './eslint-rules/sort-keys-array': 'error',
  },
};

3. 测试并运行修复

执行eslint --fix src/**/*.js(根据你的项目路径调整),符合条件的字符串数组就会自动按字母排序。

可选优化:指定仅排序特定数组

如果不想全局排序所有字符串数组,可以给规则加配置,比如只排序变量名为keys的数组:

修改规则的meta.schema增加配置项,然后在create函数中判断数组所属的变量名:

module.exports = {
  meta: {
    // ...原有meta配置
    schema: [
      {
        type: 'object',
        properties: {
          targetVarNames: {
            type: 'array',
            items: { type: 'string' },
          },
        },
      },
    ],
  },
  create(context) {
    const { targetVarNames = [] } = context.options[0] || {};
    return {
      VariableDeclarator(node) {
        // 仅处理指定变量名的数组赋值
        if (targetVarNames.includes(node.id.name) && node.init?.type === 'ArrayExpression') {
          // 这里复用之前的数组处理逻辑
          const validElements = node.init.elements.filter(el => 
            el && el.type === 'Literal' && typeof el.value === 'string'
          );
          if (validElements.length <= 1) return;

          const currentValues = validElements.map(el => el.value);
          const sortedValues = [...currentValues].sort((a, b) => a.localeCompare(b));
          if (currentValues.join(',') === sortedValues.join(',')) return;

          context.report({
            node: node.init,
            message: '数组键请按字母顺序排序',
            fix(fixer) {
              const quote = validElements[0].raw[0];
              const sortedStr = sortedValues.map(val => `${quote}${val}${quote}`).join(', ');
              return fixer.replaceText(node.init, `[${sortedStr}]`);
            },
          });
        }
      },
    };
  },
};

然后在ESLint配置中指定目标变量名:

rules: {
  './eslint-rules/sort-keys-array': ['error', { targetVarNames: ['keys', 'allowedKeys'] }],
},

这样就只会排序名为keys或allowedKeys的数组变量。

内容的提问来源于stack exchange,提问作者Rozrewolwerowany rewolwer

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.26 16:02:47