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

yo-power-generator

v0.7.1

Published

a power generator for yeoman

Downloads

272

Readme

Yo Power Generator

NPM version npm download Build Status codecov

a power generator implementation of yeoman.

一款功能丰富的yeoman generator的实现。

以下简称pg。

How To

Getting Started

1. 创建index.js

// generators/app/index.js
'use strict'

const path = require('path');

const args = {
  orgName: {
    prompting: {
      type: 'input',
      message: 'your org name(optional)'
    },
    option: { desc: '组织名称', type: String, default: '' }
  }
}
module.exports = require('yo-power-generator').getGenerator(args, {
  description: 'This is a scaffold demo'
  handlerDir: path.join(__dirname, 'handler'),
  templateDir: path.join(__dirname, 'templates')
});

更多配置请参考Generator配置

2. 创建模板文件

创建目录generators/app/templates,并在该目录下创建文件foo.tmpl.js,内容如下

// generators/app/templates/foo.tmpl.js
'use strict'

console.log('${orgName}');

3. 通过yo执行你的generator

首先将你的项目link到全局node_modules

$ cd {you_project_dir}
$ npm link

然后执行yo

$ mkdir /tmp/test
$ cd /tmp/test
$ yo {you_generator_name}

查看生成结果

$ cat /tmp/test/foo.js

通过 --form 选项获取到脚手架选项的 JSON 格式表单

yo {you_generator_name} --form

通过 --desc 选项获取到脚手架的描述信息

yo {you_generator_name} --desc

References

Generator配置

{
  handlerDir: 'dir/', // {string} template handler所在目录
  templateDir: 'dir/', // {string} template所在目录
  afterPropsSet: (props) => {}, // {function} props设置完毕后执行的回调
}

Generator参数

原 Yeoman 支持的参数分两种:prompting 与 option。pg 对其进行了一些改造,使其使用起来更加容易,并且更加强大。其格式如下:

const args = {
  key: {
    prompting: {
      // 除了name不需要填写外与yeoman的prompting格式一致,影响交互模式内容
    },
    option: {
      // 与yeoman的option格式一致,影响命令模式内容
    },
    child: {
      subKey: {
        // 与key的格式一致,支持无限递归

        // 以下是子参数特有配置
        callbacks: {
          // 决定是否触发子参数的回调(仅在交互模式下生效),answer为此前所有的用户回答
          trigger (answers) {
            return answers.key === 'val';
          }
        }
      }
    }
  }
}

支持 choice 别名显示(key,value 分离)

    prompting: {
      type: 'list',
      choices: [
        { key: 'jwt', display: '无状态jwt' },
        'session',
        { key: 'none', display: '无'}
      ],
      message: '请选择你采用的认证机制类型'
    }

在交互的时候会显示成

? 请选择你采用的认证机制类型 (Use arrow keys)
❯ 无状态jwt
  session
  无

在选择无状态jwt 后对应的值为 jwt

触发器

当选项包含 trigger 触发器时,只有满足了触发器条件时该选项才会被激活。

trigger 除了可以是一个函数,它还可以是一个 AbstractTrigger 实例对象的数组,此时只有当数组中的所有触发器的触发条件都为真时该选项才会被激活。

pg内置了一些常用的触发器

AnyAnswerTrigger

AnyAnswerTrigger 触发器会校验用户指定选项的答案值,如下面示例中仅在用户数据库 db 选项选择了 mysql 时才激活数据库连接池 dbPool 子选项。

const Trigger = require('yo-power-generator').Trigger;
const args0 = {
  db: {
    prompting: {
      type: 'list',
      choices: ['mysql', 'none'],
      message: '请选择你使用的数据库'
    },
    option: { desc: '数据库', type: String, default: 'none' },
    child: {
      dbPool: {
        prompting: { type: 'list', choices: ['druid', 'default'], message: '请选择你使用的数据库连接池' },
        option: { desc: '数据库连接池', type: String, default: 'none' },
        callbacks: {
          trigger: [
            new Trigger.AnyAnswerTrigger('db', 'mysql')
          ]
        }
      }
    }
  }
};
其使用方式如下
new Trigger.AnyAnswerTrigger('db', 'mysql')

相应的表单描述

{
  "type": "anyAnswerTrigger",
  "answer": "db",
  "value": ["mysql"]
}
NoAnyAnswerTrigger

NoAnyAnswerTrigger 触发器则刚好与AnyAnswerTrigger相反,它会校用户指定选项的答案,与你指定的任何一个值都不匹配时才会触发。

使用方式如下

new Trigger.NoAnyAnswerTrigger('db', 'mysql')

相应的表单描述

{
  "type": "noAnyAnswerTrigger",
  "answer": "db",
  "value": ["mysql"]
}

支持 choice 别名显示(key, value 分离)

    prompting: {
      type: 'list',
      choices: [
        { key: 'jwt', display: '无状态jwt' },
        'session',
        { key: 'none', display: '无'}
      ],
      message: '请选择你采用的认证机制类型'
    }

在交互的时候会显示成

? 请选择你采用的认证机制类型 (Use arrow keys)
❯ 无状态jwt
  session
  无

在选择无状态jwt 后对应的值为 jwt

实现你自己的触发器

你可以继承自 AbstractTrigger 实现自定义选项触发器,需要实现两个方法:

  • isTrigger(answers):触发逻辑判断,answers 为用户选项所选择答案集
  • toForm():触发器表单格式对象,用于在 --form 选项时获取脚手架选项表单

示例如下

const Trigger = require('yo-power-generator').Trigger;
class FooTrigger extends Trigger.AbstractTrigger {
  constructor () {
    super();
  }

  isTrigger (answers) {
    return true;
  }

  toForm () {
    return {
      type: 'fooTrigger'
    };
  }
}

module.exports = AnyAnswerTrigger;

Template

位置

模板需要放在templateDir指定的目录下,并且以一定的格式命名,pg会自动对该目录递归扫描,并进行渲染。

模板命名规则

文件名中包含tmpl字样且一定条件的文件才会被pg认为是一个模板,非模板文件不会被渲染。

以下举例了一些会被认为是模板的文件名,及其渲染后的名称

  • 包含.tmpl:foo.tmpl.js -> foo.js
  • 以.tmpl开头:.tmpl.Dockerfile -> Dockerfile
  • 以tmpl结尾:.gitignore.tmpl -> .gitignore

每个模板文件还可以指定其对应的Template Handler,如果未指定(如上述例子),则采用默认Temaplte Handler进行处理。

以下举例了会使用指定handler进行处理的模板的文件名,及其渲染后的名称

  • foo.tmpl_my_handler.js -> foo.js

模板文件还支持简单的条件化渲染,可以通过在文件名中包含if_cond来指定条件cond,pg会自动检查propsprops.conditions中是否存在key cond来决定是否渲染该文件

以下举例了能进行条件化渲染的模板的文件名,及其渲染后的名称

  • if_cond.foo.tmpl.js -> foo.js

Template Handler

每个模板都会经过一定的处理后被渲染成最终的文件并输出,在pg中这个过程是由被称为Template Handler的组件来处理的。

pg为你提供了默认的handler,你也可以定制自己的handler。

默认Handler

默认的Handler将使用loadsh的模板功能来处理模板内容。

自定义Handler

自定义的Handler需要放在handlerDir指定的目录下,格式如下

'use strict';

const AbstractTemplateHandler = require('yo-power-generator').AbstractTemplateHandler;

class MyTemplateHandler extends AbstractTemplateHandler {
  _handle0 () {
    // do something here
  }
}

module.exports = {
  key: 'custom',
  cls: MyTemplateHandler
};

常用工具类

File Utils

FileUtils提供了一些常用的工具方法,如将模板名称转换为文件名等,引入方式如下

const fileUtils = require('yo-power-generator').FileUtils;
// do something with fileUtils

Release Notes

CHANGELOG