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 🙏

© 2024 – Pkg Stats / Ryan Hefner

hins

v1.1.3

Published

[![codecov](https://codecov.io/gh/l-zoy/hins/branch/main/graph/badge.svg)](https://codecov.io/gh/l-zoy/hins) [![GitHub license](https://img.shields.io/github/license/l-zoy/hins)](https://github.com/l-zoy/hins/blob/master/LICENSE) ![node-current](https://i

Downloads

56

Readme

hins

codecov GitHub license node-current <ORG_NAME>

中间插件程序, 可以快速创建定制化 cli 工具

安装

npm install hins

用法

暴露一个核心类 Core

const { Core } = require('hins')
const core = new Core({
  // ...arguments
})

// 需要执行的命令
core.start({ ...arguments })

Core.start()

参数: object

{
  args?: object
  command: string
  reloadCommand?: boolean
}
  • args 接受任何参数, 类型是一个对象, 最后会传入命令插件
  • command 启动命令
  • reloadCommand 重新运行命令
// 这里先执行了 dev 命令,进入到 dev 插件,
core.start({ command: 'dev' })
// 有的时候需要做命令派发, 在dev插件命令内 做了一些计算,
// 最后得出执行webDev命令. 但是又不需要重新注册插件等前置步奏
core.start({ command: 'webDev', reloadCommand: true })

接受参数:

cwd

  • 工作区路径
  • Type: string
  • Default: process.cwd()

babelRegister

  • config 和 plugin 的运行时, 使其支持 ts 或 ESNext
  • Type: function
  • Default: () => {}

possibleConfigName

  • 读取配置文件的路径及文件名
  • Type: string[]
  • Default: []
{
  possibleConfigName: ['config.js']
}

运行时就会去传入 cwd 根目录下找 config.js 文件并读取

plugins

  • plugins 配置路径
  • Type: string[]
  • Default: []

可以是 绝对路径 或者 相对路径. 相对路径是相对传入的 cwd 参数

watchConfig

  • 是否监听配置文件, 如果发现更改则重新运行命令
  • Type: object
  • Default:
  // IChangeTypes:'add' | 'addDir' | 'change' | 'unlink' | 'unlinkDir'
  {
    changeLog: (type: IChangeTypes, path: string) => void
    reloadLog: (type: IChangeTypes, path: string) => void
  }

核心方法:

每个 plugin 都会接受一个 api 实例参数

describe 注册阶段执行,用于描述插件或插件集的 key、配置信息、启用方式等

参数: object

{
  key: string,
  config: {
    default: any,
    schema: (joi) => {
      return joi.string()
    }
  }
}
api.describe({
  key: 'history',
  config: {
    default: 'browser',
    schema(joi) {
      return joi.string()
    }
  }
})
// config
export default {
  history: 'node'
}

注:

  • config.default 为配置的默认值,用户没有配置时取这个
  • config.schema 用于声明配置的类型,基于 joi,如果你希望用户进行配置,这个是必须的,否则用户的配置无效

register 为 api.applyHooks 注册可供其使用的 hook

参数: object

{
  key: string,
  fn: Function,
  pluginId?: string,
  before?: string,
  stage?: number
}
// 可同步
api.register({
  key: 'foo',
  fn() {
    return 'a';
  },
});

// 可异步
api.register({
  key: 'foo',
  async fn() {
    await delay(100);
    return 'b';
  },
});

然后通过 api.applyHooks 即可拿到 ['a', 'b'],


const foo = await api.applyHooks({
  key: 'foo',
  type: api.ApplyHookType.add,
  initialValue: [],
});
console.log(foo); // ['a', 'b']
  • fn 支持同步和异步,异步通过 Promise,返回值为 Promise 即为异步
  • fn 里的内容需结合 api.applyHooks 的 type 参数来看
    • 如果是 api.ApplyHookType.add,需有返回值,这些返回值最终会被合成一个数组
    • 如果是 api.ApplyHookType.modify,需对第一个参数做修改,并返回
    • 如果是 api.ApplyHookType.event,无需返回值
  • stage 和 before 都是用于调整执行顺序的
  • stage 默认是 0,设为 -1 或更少会提前执行,设为 1 或更多会后置执行

提供三个便捷调用:

api.applyAddHooks({
  key: 'foo',
  initialValue: []
})

api.applyModifyHooks({
  key: 'modify',
  initialValue: 'bar'
})

api.applyEventHooks({
  key: 'event'
})

applyHooks 取得 register 注册的 hooks 执行后的数据

参数: object

{
  key: string,
  type:api.ApplyHookType,
  initialValue?: any,
  args?: any
}

相同 key 可能有多个 hook, api.ApplyHookType.add 会返回所有 hook 的数组合值

const foo = await api.applyHooks({
  key: 'foo',
  type: api.ApplyHookType.add,
  initialValue: []
})
console.log(foo) // ['a', 'b']

registerPlugins(plugins: string[]) 注册插件,参数为路径数组

api.registerPlugins([
  { key: 'preset2', apply: (api) => {} },
  require.resolve('./preset_3')
])

这里内联插件不会进行处理, 直接添加至待执行的插件列表, 因为插件的键名是依照文件路径生成的, 这里的 key 需要填写唯一值

registerCommand 注册命令

参数: object

{
  command: string,
  alias?: string,
  fn: function
}
api.registerCommand({
  command: 'generate',
  alias: 'g',
  fn: ({ args }) => {
    return `hello ${api.args.projectName}`
  }
})

alias 为别名,比如 generate 的别名 g fn 的参数为 { args }

registerMethod

参数: object

{
  name: string,
  fn?: Function,
}

往 api 上注册方法。可以是 api.register() 的快捷使用方式,便于调用;也可以不是,如果有提供 fn,则执行 fn 定义的函数。

api.registerMethod({
  name: 'foo',
  fn() {
    return 'foo'
  }
})

api.foo()
// 'foo'

configInstance

    watchConfig(): void;
    // 开启监听config文件

    在插件里使用api.configInstance.watchConfig开启监听配置文件, 当修改时会重启

周期钩子

onStart()

在执行命令函数前触发。可以使用 config

api.onStart(() => {
  // do something
})

onPluginReady()

在插件初始化完成触发。在 onStart 之前,此时 config 尚未解析好。

api.onPluginReady(() => {
  // do something
})

modifyConfig

修改最终配置,参数为最终 config 配置

api.modifyConfig((memo) => {
  return {
    ...memo,
    ...defaultOptions
  }
})

修改后的值不会再做 schema 校验