Plugin API

Oleg Gaidarenko edited this page Jul 8, 2015 · 11 revisions

Plugin example

You need:

your-package/
  package.json
  lib/index.js
  lib/presets/
    red-moo-presets.json
  lib/rules/
    your-rule.js
  lib/reporters/
    moonlight.js

In file ./your-package/lib/index.js (you'll find public API of Configuration in sources):

/**
 * @param {Configuration} conf
 */
module.exports = function (conf) {
  // plugin loading:
  conf.registerRule(require('./rules/your-rule.js')); // registering you rule
  conf.registerPreset('red-moo', require('../presets/red-moo-preset.json')); // and your preset
  // not supported: conf.registerReporter('moonlight', require('./reporters/moonlight.js'));
};

In ./your-package/package.json you need to define jscs dev dependency:

{
  "devDependencies": {
    "jscs": ">=1.8.0 <2.0.0"
  }
}

In ./your-package/lib/rules/your-rule.js (here you can take a look at rules in jscs repo):

module.exports = function () {};
module.exports.prototype.getOptionName = function () {
  return 'yourRule';
};
module.exports.prototype.configure = function (options) {
  assert(options === true || typeof options === 'object');
  // rule preparation and configuration
  this._options = options;
};
module.exports.prototype.check = function (file, errors) {
  // checking file
  if (this._options.color === 'red') {
    errors.add('red color', 1, 0);
  }
  file.iterate(function(node, parentNode, parentCollection) {
    if (!isValid(node)) {
      errors.add('invalid node found', node.loc.start);
    }
  });
  if (true) { // add an error
    errors.add('some error', 1, 0);
  }
};

In ./your-package/presets/red-moo-preset.json (see also presets in jscs repo as examples):

{
  "yourRule": {
    "color": "red"
  }
}

In ./your-package/lib/reporters/moonlight.js (Errors API, and reporters as examples):

/**
 * @param {Errors[]} errorsCollection
 */
module.exports = function(errorsCollection) {
    /**
     * Formatting every error set.
     */
    errorsCollection.forEach(function(errors) {
        if (!errors.isEmpty()) {
            /**
             * Formatting every single error.
             */
            errors.getErrorList().forEach(function(error) {
                console.log(errors.explainError(error) + '\n');
            });
        }
    });
};

Testing environment

If you'll will have a trouble with loading plugin in testing environment just put explicit relative path to main plugin file and all be fine:

var Checker = require('jscs/lib/checker');
var checker = new Checker();
checker.configure({
  // Put here explicit path to main plugin file
  plugins: ['./lib/index.js']
});

Using your plugin

To load and use your plugin you should just add it to plugins (or add your rules to additionalRules before v1.8). You can provide here relative path for local plugins, or just name for npm modules:

.jscsrc example with plugin as local module:

{
  "plugins": ["./your-package"],
  "yourRule": true
}

.jscsrc example with plugin as npm module:

{

  // If you package called "jscs-your-package" you can omit "jscs-" prefix in jscs config 
  // and just do 
  "plugins": ["your-package"], 
  "yourRule": true
}

Usign your plugin via deprecated additionalRules option:

{
  "additionalRules": ["your-package/lib/rules/*.js"],
  "yourRule": true
}

Reporters could be loaded only via command line atm. You can pass your own reporter to --reporter CLI option:

jscs --reporter=./your-package/lib/reporters/moonlight.js