Compiler@NodeJS(三)- 自定义命令

接上篇:Compiler@NodeJS(二)- 强大的管道

本来早就应该写这篇文章的,只是忙的时候忙,闲的时候懒,导致拖了这么久。

不管内置多少命令,需求总是千变万化的,这时候内置命令就不够用了,需要使用者自己编写一些命令。现在来看看怎么做。more

一、内置命令

先来看看内置命令的文件结构是怎样的:

+--- compiler
    +--- cmds
        +--- copy
        +--- concat
            --- index.js
            --- README.md

每个命令都是cmds下面的一个单独目录,如copy、concat等等。每个命令下面都必须有一个index.js文件,作为这个命令的入口。index.js需要export一个属性(async)和一个方法(execute),这里拿concat命令来说明,如下:

var fs = require('fs'),
    path = require('path');

//指示该命令是异步执行的,默认为false,命令结束后会自动调用 nextTask;
//如果为true,则需在本命令执行完成之后主动调用 nextTask
exports.async = true;
//命令的入口函数
exports.execute = function(task, compileConfig, runOptions, nextTask){
    //省略……
}

当concat命令被调用的时候,compiler会找到concat目录下的index.js,require之后执行它的execute方法,execute的参数说明如下:

参数名 说明
task Object,这次命令调用要执行的任务,一个task包括任务id、任务要执行的命令(cmd)、任务的输入(source)、任务执行的输出目录(target)、任务的参数(params,也就是在config.json中配置的对应的params,比如下面示例代码中的custA_html中的params)
compileConfig Object,执行compiler时传入的配置,也就是config.json内容
runOptions Object,执行该任务时的运行时信息,包括compiler的目录、命令的目录(concat的绝对路径)、命令的文件名(index.js的目录+名字)
nextTask Function,告诉compiler继续执行下一个命令,在设置了exports.async=true时,需要该命令主动调用,如:nextTask()。

二、自定义命令

自定义命令的写法很简单:

  1. 只要建立一个目录,比如custA(这里我放到了项目根目录下的custom_cmds),创建index.js文件,并提供execute方法;
  2. 在config.json中配置该命令,让compiler知道哪里可以找到该命令。 有了自定义命令的config.json的样子应该是类似这样的:
{
    "sourceRoot": "./",
    "targetRoot": "./build",
    "fileFormat": "js,css,html,htm,png,gif,jpg,jpeg,wav,json",
    "cmds": {
        "custA": {//配置自定义命令
            "id": "custA",
            "root": "./custom_cmds/custA/"
        }
    },
    "rules": {
        "custA_html": {
            "cmd": "custA",//使用自定义命令
            "target": "./",
            "source": "./",
            "params": {}
                 }
        }
}

如代码所示,只要在cmds项中,添加一个custA的json描述,给出id和根目录(root),其他事情就不用管了。

三、组合命令

上一篇讲到,compiler最强大的是管道特性,可以用来将命令串联组合。有时候,一些任务可能需要很多个命令来组合完成,但是在每个rule里面写又不是很方便。这时候可以使用自定义命令的另外一种形式,组合命令。使用很简单,只要在config.json配置就行。

{
    "sourceRoot": "./",
    "targetRoot": "./build",
    "fileFormat": "js,css,html,htm,png,gif,jpg,jpeg,wav,json",
    "cmds": {
        "custB": "translate|copy,compress",
        "custC": "custB|ispriter"
    },
    "rules": {
        "translate_html": {
            "cmd": "custB",
            "parmas": {/*..*/}
        
    

其实组合命令就是把原有命令串、并联在一起,方便之后使用,同时组合命令还能再次被组合,是不是很神奇咧?哈哈。命令的组合原则可以看上一篇介绍。不过有点需要注意的,在使用组合命令时,传入的params需要一一对应,比较不顺手。如果是多次组合过的命令,params将变得更加复杂,不过暂时只能这样了。

嗯,到这里,自定义命令的教程就结束了。如果你还是不太明白,可以到github中查看内置命令的实现,如:template-pickeriofflineconcatcopy等等,毕竟千言万语不及代码两行嘛,哈哈。有任何问题也可在本文留言,或者邮件给我,欢迎试用,^_^。