npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@yinxulai/eslint-plugin-peculiar

v1.0.4

Published

Peculiar ESLint plugin with custom function-related rules: definition allowance, signature linebreaks, and maximum parameter count.

Downloads

758

Readme

@yinxulai/eslint-plugin-peculiar

一个聚焦"函数定义"相关规则的 ESLint 插件:用 TypeScript 编写。

提供三个规则:

  1. func-definition — 配置允许哪些种类的函数定义
  2. func-signature-linebreak — 控制函数签名的换行风格
  3. func-param-destructuring — 禁止在函数参数中使用解构模式

安装

要求 ESLint ≥ 8.40(用到了 context.sourceCode 等较新的 API)。

npm install --save-dev @yinxulai/eslint-plugin-peculiar eslint

使用

旧式配置 (.eslintrc)

{
  "plugins": ["@yinxulai/peculiar"],
  "rules": {
    "@yinxulai/peculiar/func-definition": "warn",
    "@yinxulai/peculiar/func-signature-linebreak": ["warn", { "style": "single" }],
    "@yinxulai/peculiar/func-param-destructuring": "warn"
  }
}

或使用预设:

{
  "extends": ["plugin:@yinxulai/peculiar/recommended"]
  // 或 "plugin:@yinxulai/peculiar/strict"
}

Flat 配置 (eslint.config.js)

使用预设(推荐,命名空间短化为 peculiar):

import peculiar from '@yinxulai/eslint-plugin-peculiar'

export default [
  ...peculiar.configs['flat/recommended'],
  // 或者: ...peculiar.configs['flat/strict']
]

或手动注册插件并按需配置(命名空间必须和 plugins 的 key 一致):

import peculiar from '@yinxulai/eslint-plugin-peculiar'

export default [
  {
    plugins: { peculiar },
    rules: {
      'peculiar/func-definition': 'warn',
      'peculiar/func-signature-linebreak': ['warn', { style: 'single' }],
      'peculiar/func-param-destructuring': 'warn',
    },
  },
]

预设

recommended / flat/recommendedstrict / flat/strict 的 rule 配置完全一致,仅严重度不同warn vs error):

| 规则 | 行为 | | --- | --- | | func-definition | 都允许(不传 allow = 4 种函数定义全开) | | func-signature-linebreak | 不允许换行({ style: 'single' },强制签名单行) | | func-param-destructuring | 仅允许箭头函数解构({ allowIn: ['arrow'] },function / method 仍禁用) |

func-definitionfunc-param-destructuring 的"默认方向"是相反的:

  • func-definition 不传 allow = 4 种函数定义都允许
  • func-param-destructuring 不传 allowIn = 全部禁止

原因:前者的目标是"白名单"(开箱即用),后者的目标是"黑名单"(更严的代码规范)。


覆盖范围

所有规则都基于 ESLint/ESTree 的函数节点 触发,Visitor 访问以下节点类型:

| 节点类型 | 覆盖说明 | | --- | --- | | FunctionDeclaration | 顶层 function foo() {} 声明 | | FunctionExpression | const f = function () {} 表达式,及 class/object 方法内部的函数 | | ArrowFunctionExpression | const f = () => {} 箭头函数 | | TSDeclareFunction | declare function foo(): void TS 声明(仅 func-definition 视为 declaration) |

类与对象方法:class A { foo() {} } 里的 fooFunctionExpression,其 .parentMethodDefinition,会被归类为 methodconst o = { foo() {} } 里的 foo 同理(.parentProperty,且 method === true)。

嵌套函数:Visitor 会递归访问嵌套函数,但分类时只看直接父节点(isInsideMethod)。


规则

func-definition

配置允许的函数定义种类。

allow 选项(数组,元素可选 declaration / expression / arrow / method):

| kind | 含义 | 示例 | | --- | --- | --- | | declaration | 函数声明 | function foo() {} | | expression | 函数表达式 | const foo = function () {} | | arrow | 箭头函数 | const foo = () => {} | | method | 类/对象方法 | class A { foo() {} } |

默认:全部允许。

// 禁用函数声明和函数表达式,只允许箭头和方法
{ "@yinxulai/peculiar/func-definition": ["error", { "allow": ["arrow", "method"] }] }

数组为空 = 全部禁用。 数组含未知值(非 declaration / expression / arrow / method)会作为配置错误上报 invalidAllowOption,而不是 schema 报错。


func-signature-linebreak

控制函数签名的换行风格。

| style | 行为 | | --- | --- | | single | 签名必须一行 | | multiple | 签名必须多行,每个参数独占一行 | | consistent | 签名要么全在一行,要么多行且每个参数独占一行(默认) |

附加选项 maxLength:单行签名字符数超过该值时,必须改为多行(每个参数独占一行)。计算的是 () 之间(不含括号本身)的字符数,含注释。 显式写了 style: 'single' + maxLength 时,过长依然会触发 signatureTooLong 并自动修复为多行。

// 强制单行(不允许换行)
{ "@yinxulai/peculiar/func-signature-linebreak": ["error", { "style": "single" }] }

// 强制多行,每个参数独占一行
{ "@yinxulai/peculiar/func-signature-linebreak": ["error", { "style": "multiple" }] }

// 允许单行,但超过 80 字符必须多行
{ "@yinxulai/peculiar/func-signature-linebreak": ["error", { "style": "consistent", "maxLength": 80 }] }

不报错的场景:参数 < 2 个(没东西可换行)。

fix 安全护栏:自动修复仅在签名 () 内"无参数外注释"时生效。如果参数之间 / 之前 / 之后有内联块/行注释,fix 会只 report 不 fix(output: null),把决定权交给人工。


func-param-destructuring

禁止在函数参数中使用解构模式(ObjectPattern / ArrayPattern),包括 TypeScript 类型注解的情况。

allowIn 选项(数组,元素可选 function / arrow / method):

| kind | 含义 | 示例 | | --- | --- | --- | | function | 顶层函数声明/表达式 | function foo() {} / const foo = function () {} | | arrow | 箭头函数 | const foo = () => {} | | method | 类/对象方法 | class A { foo() {} } / const o = { foo() {} } |

默认:全部不允许(不传该选项 = 全部禁用,与 func-definition 默认方向相反)。

// 仅允许箭头函数解构
{ "@yinxulai/peculiar/func-param-destructuring": ["error", { "allowIn": ["arrow"] }] }

示例

// ❌ 报错
function Test({ a, b, c }: Props) {}
const handler = ({ event }) => doSomething(event)
class A { method([x, y]) {} }

// ✅ 不报错(重写为显式参数)
function Test(props: Props) { const { a, b, c } = props }
const handler = (event) => doSomething(event)
class A { method(coord) {} }
  • 同时检查 ObjectPatternArrayPatternfunction f([a, b]) {} 也会被禁止。
  • TypeScript 类型注解不影响检查:function f({ a }: { a: string }) {} 仍然报错(param 节点本身就是 ObjectPattern)。
  • 解构出来的属性是否被使用不在本规则范围,使用官方的 no-unused-vars
  • 用途之一是绕过 max-params 计数 —— function f({a, b, c, d, e}) 在官方 max-params 里只算 1 个参数,启用本规则可强制显式书写。

fix 条件:自动修复仅在"安全"场景下提供 —— 即:

  • 函数体是 BlockStatement(不是箭头表达式体)
  • 没有 this 形参(避免改写挪动其它形参索引)
  • 解构形参没有外层默认值(避免把默认值从 Pattern 上剥到 Identifier 上)

不满足上述条件时仍会报 paramDestructuring,但不带 fix。


开发

npm install
npm run build         # tsc → output/ (test 文件不会进 output)
npm test              # pretest (tsc --noEmit) + vitest 跑全部规则 + 插件结构测试
npm run coverage      # 附带 v8 覆盖率报告

测试栈:Vitest + ESLint 9 提供的 RuleTester(从 eslint 直接 import)。测试用 TypeScript 编写,并与对应实现文件并列放:

source/
  index.ts
  index.test.ts                # 插件结构测试
  rules/
    func-definition.ts
    func-definition.test.ts    # 规则测试
    func-param-destructuring.ts
    func-param-destructuring.test.ts
    func-signature-linebreak.ts
    func-signature-linebreak.test.ts
  utils/
    function-helpers.ts

tsc 通过 tsconfig.jsonexclude: ["**/*.test.ts"] 把测试文件挡在 output/ 外,不会污染发布包。npm testpretest hook 跑 tsc --noEmit,确保发布前类型已干净。

协议

ISC