ESLINT规则多次运行

发布于 2025-01-24 23:08:09 字数 3080 浏览 4 评论 0原文

我试图编写一个ESLINT规则,该规则确保name属性是在从其他错误/异常命名类延伸的类上定义的(并修复它们)。

据我所知,它可以单独地在astexplorer.net中起作用,但是当我与其他规则一起运行时,它最终会多次运行,因此名称属性最终会在结果中多次重复。 “ 文件。

我可以做些什么来防止其多次运行?我假设发生了什么事是它正在插入我的name ='className';,那么Prettier需要重新格式化代码,但可能是我的规则重新运行的?我不知道。

规则/修复代码如下所示。我尝试了使用 *修复和产量之类的事情,但这似乎也无济于事(请参阅下面的评论代码,基于 eslint文档

module.exports = {
    meta: {
        hasSuggestions: true,
        type: 'suggestion',
        docs: {},
        fixable: 'code',
        schema: [], // no options,
    },
    create: function (context) {
        return {
            ClassDeclaration: function (node) {
                const regex = /.*(Error|Exception)$/;
                // If the parent/superClass is has "Error" or "Exception" in the name
                if (node.superClass && regex.test(node.superClass.name)) {
                    let name = null;
                    const className = node.id.name;
                    // Test class object name
                    if (!regex.test(className)) {
                        context.report({
                            node: node,
                            message: 'Error extensions must end with "Error" or "Exception".',
                        });
                    }

                    // Find name ClassProperty
                    node.body.body.some(function (a) {
                        if (a.type === 'ClassProperty' && a.key.name === 'name') {
                            name = a.value.value;
                            return true;
                        }
                    });

                    // Name property is required
                    if (!name) {
                        context.report({
                            node: node,
                            message: 'Error extensions should have a descriptive name',
                            fix(fixer) {
                                return fixer.replaceTextRange(
                                    [node.body.range[0]+1, node.body.range[0]+1],
                                    `name = '${className}';`
                                );
                            },

                            // *fix(fixer) {
                            //     name = className;
                            //     yield fixer.replaceTextRange(
                            //         [node.body.range[0]+1, node.body.range[0]+1],
                            //         `name = '${className}';`
                            //     );
                            //
                            //     // extend range of the fix to the range of `node.parent`
                            //     yield fixer.insertTextBefore(node.body, '');
                            //     yield fixer.insertTextAfter(node.body, '');
                            // },
                        });
                    }
                }
            },
        };
    },
};

I'm trying to write an eslint rule that enforces making sure the name property is defined on any classes that extend from other Error/Exception named classes (and fixes them).

As far as I can tell, it works in the astexplorer.net individually, but when I'm running it alongside other rules, it ends up getting ran multiple times, so the name property ends up being repeated multiple times in the resulting "fixed" file.

Is there anything in particular I can do to prevent it being run multiple times? I'm assuming what's happening is that it's inserting my name = 'ClassName';, then prettier is needing to reformat the code, which it does, but then maybe it's re-running my rule? I'm not sure.

Rule/fix code shown below. I've tried things like using *fix and yield, but that doesn't seem to help either (see commented code below, based on information in the eslint documentation)

module.exports = {
    meta: {
        hasSuggestions: true,
        type: 'suggestion',
        docs: {},
        fixable: 'code',
        schema: [], // no options,
    },
    create: function (context) {
        return {
            ClassDeclaration: function (node) {
                const regex = /.*(Error|Exception)$/;
                // If the parent/superClass is has "Error" or "Exception" in the name
                if (node.superClass && regex.test(node.superClass.name)) {
                    let name = null;
                    const className = node.id.name;
                    // Test class object name
                    if (!regex.test(className)) {
                        context.report({
                            node: node,
                            message: 'Error extensions must end with "Error" or "Exception".',
                        });
                    }

                    // Find name ClassProperty
                    node.body.body.some(function (a) {
                        if (a.type === 'ClassProperty' && a.key.name === 'name') {
                            name = a.value.value;
                            return true;
                        }
                    });

                    // Name property is required
                    if (!name) {
                        context.report({
                            node: node,
                            message: 'Error extensions should have a descriptive name',
                            fix(fixer) {
                                return fixer.replaceTextRange(
                                    [node.body.range[0]+1, node.body.range[0]+1],
                                    `name = '${className}';`
                                );
                            },

                            // *fix(fixer) {
                            //     name = className;
                            //     yield fixer.replaceTextRange(
                            //         [node.body.range[0]+1, node.body.range[0]+1],
                            //         `name = '${className}';`
                            //     );
                            //
                            //     // extend range of the fix to the range of `node.parent`
                            //     yield fixer.insertTextBefore(node.body, '');
                            //     yield fixer.insertTextAfter(node.body, '');
                            // },
                        });
                    }
                }
            },
        };
    },
};

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

枯叶蝶 2025-01-31 23:08:09

事实证明,我将AST Explorer设置为错误的解析器,因此它向我展示了classProperty node的错误字符串名称。我应该改用propertyDefinition

Turns out I had the AST Explorer set to the wrong parser, so it was showing me the wrong string name for the ClassProperty node. I should have been using PropertyDefinition instead.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文