如何通过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
相关产品推荐
相关产品推荐

