os-jscs

0.1.6 • Public • Published

JSCodeSniffer v.2.x

Build Status NPM version

JSCodeSniffer is a node.js application that checks JavaScript code style consistency according to a provided coding style, just like phpcs. One can define a custom coding style by using described below JSON notation or use one of predefined standards.

Features

Setup

JS_CodeSniffer relies on node.js. If you don't have node.js installed, just follow the instructions: https://github.com/joyent/node/wiki/Installing-Node.js-via-package-manager

Make sure all the required dependencies installed

npm i

Make sure the binary is executable

chmod +x jscs

You can also create a symlink to make it globally available

ln -s jscs /usr/local/bin/jscs

Using JSCodeSniffer in the command line

Simply get detailed report on a target (file or directory) coding style according to jQuery Coding Style Guide

./jscs source-code.js --standard=Jquery

or

node jscs.js source-code.js  --standard=Jquery

or

./jscs js/dir1 file1.js js/dir2 file2.js --standard=Jquery

JS CodeSniffer Full Report Example

Get detailed report on the coding style for all .js/.json files of the 'lib' folder according to jQuery Coding Style Guide

./jscs lib --standard=Jquery --report-full

Get summary report

./jscs lib --report-summary

JS CodeSniffer Summary Report Example

Get XML report (which allows you to parse the output easily and use the results in your own scripts)

./jscs lib --report=xml

Get Checkstyle report (that is supported by wide range of 3rd party software. E.g. Jenkins via a plugin)

./jscs lib --report=checkstyle

Report to a file (by default report goes to stdout)

./jscs lib --report-file=filePath

Disable colors in the report

./jscs lib --highlight=0

Define width of report screen

./jscs lib --reportWidth=84

Using JSCodeSniffer as RequireJS (AMD) module

  1. Install the package or download and unpack it into you project folder
 npm i jscodesniffer
  1. Use RequireJS to load required modules
require( [ "<esprima-js-path>/esprima", "<pkg-path>/lib/Sniffer", "<pkg-path>/lib/Dictionary/en", "<pkg-path>/lib/Dictionary" ], function( esprima, Sniffer, en, Dictionary ) {
  var sniffer = new Sniffer( esprima ),
      dictionary = new Dictionary( en ),
      logger, messages;
 
    // Get sniffer report
    logger = sniffer.getTestResults( node.srcCode.value, { standard: "Jquery" } ),
    // Translate messages
    messages = dictionary.translateBulk( logger.getMessages(), true );
    // Output report
    console.log( messages );
});

Environments

Standard to sniff against can be enforced on the file by following instructions directly in the code

/* jscs standard:Jquery */

Old form introduced in version 1.x.x is also supported

/* @jscs standard:Jquery */

Real-Time Configuration

Adjusting options can be provided as manual standard in .jscsrc file placed in the root of your project. JSCodesniffer will search upward recursively until it finds any. It will extend the specified standard rule-sets with the defenitions provided in this real-time configuration file. .jscsrc syntax is pretty much the same as standard defenition file except it doesn't need to be UMD (just JSON). I you need disable particular rule-sets you can simply empty rule-set configurations:

{
  "Indentation"false,
  "QuoteConventions"false
}

Declaring coding style

Standard declaration are located in standard directory. You can store there in a file named after your custom standard name the rule-sets that you want your code be validated against. To make the defenition available for AMD/RequireJs, the JSON notation is supposed to be wrapped as a UMD module.

NOTE: Conventions 'Any ; used as a statement terminator must be at the end of the line' and 'Multi-line Statements is checked' are tested by JSHint and therefore not provided with sniffs (See [http://contribute.jquery.org/style-guide/js/#linting] for details).

{
  /*
    defines what characters allowed for line indentation
  */
    "Indentation": {
      "allowOnlyTabs": true,
      "allowOnlySpaces": true,
      "disallowMixed": true
    },
  /*
    defines if trailing spaces allowed for lines
  */
    "LineSpacing": {
      "allowLineTrailingSpaces": false
    },
  /*
    defines allowed range for line length
  */
    "LineLength": {
      "allowMaxLength": 80,
      "allowMinLength": 0
    },
  /*
    defines spacing conventions for comma punctuator
    Example:
    // good
    var foo, bar;
    // bad
    var foo , bar;
  */
    "CommaPunctuatorSpacing": {
      "disallowPrecedingSpaces": false
    },
  /*
    defines spacing conventions for semicolon punctuator
    Example:
    // good
    var foo;
    // bad
    var foo ;
  */
    "SemicolonPunctuatorSpacing": {
      "disallowPrecedingSpaces": false
    },
 
  /*
    defines scoping rules for compound statements
 
    Example:
    // good
    if ( true ) {
      var foo = "bar";
    }
    // bad
    if ( true ) var foo = "bar";
 
  */
    "CompoundStatementConventions": {
      "for": [
        "IfStatement",
        "SwitchStatement",
        "WhileStatement",
        "DoWhileStatement",
        "ForStatement",
        "ForInStatement",
        "WithStatement",
        "TryStatement"
      ],
      "requireBraces": true,
      "requireMultipleLines": true
    },
    /*
    defines spacing conventions for unary expressions
 
    Example:
    !!100 // good
    !! 100 // bad
    */
    "UnaryExpressionIdentifierSpacing": {
      "allowTrailingWhitespaces" : 0
    },
    /*
    defines spacing conventions for ternary conditionals
 
    Example:
    foo = true ? 1 : 0; // good
    foo = true ?1:0; // bad
    */
    "TernaryConditionalPunctuatorsSpacing": {
      "allowTestTrailingWhitespaces": 1,
      "allowConsequentPrecedingWhitespaces": 1,
      "allowConsequentTrailingWhitespaces": 1,
      "allowAlternatePrecedingWhitespaces": 1,
       /*
        Optional modifier.
        When undefined the sniffer treats nesting statements the same
            as regular
        When false, no rules applied for nesting statements
        When defined, the corresponding rules go for nesting statements
        foo( a?b:c )
        */
      "ifNesting": {
        "allowTestTrailingWhitespaces": 0,
        "allowConsequentPrecedingWhitespaces": 0,
        "allowConsequentTrailingWhitespaces": 0,
        "allowAlternatePrecedingWhitespaces": 0
      }
    },
    /*
    defines spacing conventions for empty constructs
    "for" qualifier takes an array of tokens compatible with
    Mozilla Parser AST (https://developer.mozilla.org/en-US/docs/SpiderMonkey/Parser_API)
 
    Example:
    obj = {}; // good
    obj = {  }; // bad
    */
    "EmptyConstructsSpacing": {
      "for": [
        "ObjectExpression",
        "ArrayExpression",
        "CallExpression"
      ],
      "allowWhitespaces": false
    },
   /*
    defines spacing conventions for object literals
 
    Example:
    obj = { prop: 1 }; // good
    obj = { prop:1 };// bad
    */
    "ObjectLiteralSpacing": {
      "allowKeyPrecedingWhitespaces": 1,
      "allowKeyTrailingWhitespaces": 0,
      "allowValuePrecedingWhitespaces": 1,
      "allowValueTrailingWhitespaces": 1
    },
   /*
    defines spacing conventions for array literals
 
    Example:
    arr = [ 1, 2 ]; // good
    arr = [1,2]; // bad
    */
    "ArrayLiteralSpacing": {
      "allowElementPrecedingWhitespaces": 1,
      "allowElementTrailingWhitespaces": 1,
      /*
      Optional modifier.
      "for" qualifier takes an array of tokens compatible with
      Mozilla Parser AST (https://developer.mozilla.org/en-US/docs/SpiderMonkey/Parser_API)
      When qualifier "for" is missing the exception rules gets applied for any node type
      */
      "exceptions": {
        "singleElement": {
          "for": [ "Literal" ],
          "allowElementPrecedingWhitespaces": 0,
          "allowElementTrailingWhitespaces": 0
        },
        "firstElement": {
          "for": [ "Literal" ],
          "allowElementPrecedingWhitespaces": 1
        },
        "lastElement": {
          "for": [ "Literal" ],
          "allowElementTrailingWhitespaces": 1
        }
      }
    },
   /*
    defines type of quotes to use across the code-base
 
    Example:
    foo = "text"; // good
    foo = 'text'; // bad
    */
    "QuoteConventions": {
      "allowDoubleQuotes": true,
      "allowSingleQuotes": false
    },
    /*
    defines naming conventions for variables
    Note: variable of all uppercase (including $_0-9) are considered as constants and ignored by the sniffer
 
    Example:
    var camelCase; // good
    var not_camel_case; // bad
    */
    "VariableNamingConventions": {
      "allowCase": ["camel"],
      "allowRepeating": true,
      "allowNumbers": true
    },
   /*
    defines naming conventions for functions
 
    Example:
    var PascalCase; // good
    var not_camel_or_pascal_case; // bad
    */
    "FunctionNamingConventions": {
      "allowCase": ["camel", "pascal"],
      "allowRepeating": true,
      "allowNumbers": true
    },
    /*
    defines naming conventions for new expressions
 
    Example:
    obj = new Constructor(); // good
    obj = new constructor(); // bad
    */
    "NewExpressionCalleeNamingConventions": {
      "allowCase": [ "pascal" ],
      "allowRepeating": true,
      "allowNumbers": true
    },
 
   /*
    defines spacing conventions for arguments
 
    Example:
    fn( 1, 2 ); // good
    fn(1,2); // bad
    */
    "ArgumentsSpacing": {
      "allowArgPrecedingWhitespaces": 1,
      "allowArgTrailingWhitespaces": 1,
      /*
        Optional modifier.
       "for" qualifier takes an array of tokens compatible with
        Mozilla Parser AST (https://developer.mozilla.org/en-US/docs/SpiderMonkey/Parser_API)
        When qualifier "for" is missing the exception rules gets applied for any node type
      */
      "exceptions": {
        "singleArg" : {
          "for": [ "FunctionExpression", "ArrayExpression", "ObjectExpression" ],
          "allowArgPrecedingWhitespaces": 0,
          "allowArgTrailingWhitespaces": 0
        },
        "firstArg": {
          "for": [ "FunctionExpression" ],
          "allowArgPrecedingWhitespaces": 0
        },
        "lastArg": {
          "for": [ "FunctionExpression" ],
          "allowArgTrailingWhitespaces": 0
        }
      },
      /*
        Optional modifier.
        When undefined the sniffer treats nesting statements the same
            as regular
        When false, no rules applied for nesting statements
        When defined, the corresponding rules go for nesting statements
        foo( bar(1,1) )
        */
      "ifNesting": {
        "allowArgPrecedingWhitespaces": 0,
        "allowArgTrailingWhitespaces": 0
      }
    },
  /*
    defines spacing conventions for parameters
 
    Example:
    function fn( foo, bar ){}; // good
    function fn(foo,bar){}; // bad
    */
    "ParametersSpacing": {
      "allowParamPrecedingWhitespaces": 1,
      "allowParamTrailingWhitespaces": 1,
      /*
      Optional modifier.
      When qualifier "for" is missing the exception rules gets applied for any node type
      */
      "exceptions": {
        "singleParam": {
          "for": [ "Literal" ],
          "allowElementPrecedingWhitespaces": 0,
          "allowElementTrailingWhitespaces": 0
        },
        "firstParam": {
          "for": [ "Literal" ],
          "allowElementPrecedingWhitespaces": 1
        },
        "lastParam": {
          "for": [ "Literal" ],
          "allowElementTrailingWhitespaces": 1
        }
      }
    },
    /*
    defines how methods can be placed when a chain of method calls is too long to fit on one line
 
    Example:
    // good
    elements
    .addClass( "foo" )
    .children();
 
    // bad
    elements.addClass( "foo" )
    .children();
    */
 
    "ChainedMethodCallsPerLineConventions": {
      "requireOnePerLineWhenMultilineCaller": true
    },
    /*
    defines spacing conventions for chains of method calls
    Example:
    // good
    elements.addClass( "foo" )
 
    // bad
    elements.  addClass( "foo" )
    */
    "ChainedMethodCallsSpacing": {
      "allowPrecedingPropertyWhitespaces": 0
    },
    /*
    defines spacing conventions for operators (including declarator)
 
    Example:
    foo = 1 + 1; // good
    foo = 1+1; // bad
    */
    "OperatorSpacing" : {
      "allowOperatorPrecedingWhitespaces": 1,
      "allowOperatorTrailingWhitespaces": 1
    },
    /*
    defines conventions for variable declarations
 
    Example:
    // good
    (function(){
      var foo, bar;
    })();
 
    // bad
    (function(){
      var foo;
      var bar;
    })();
    */
    "VariableDeclarationPerScopeConventions" : {
      "disallowMultiplePerBlockScope": true,
      "requireInTheBeginning": true
    },
    /*
    defines conventions for object declarations
 
    Example:
    // good
    o = { p1: 1, p2: 2 }
    // good
    o = {
      p1: 1,
      p2: 2
    }
    // bad
    o = {
      p1: 1, p2: 2 }
     */
    "ObjectLiteralConventions": {
      "requireOnePerLineWhenMultiline": true
    },
    /*
    defines conventions for array declarations
 
    Example:
    // good
    arr = [ 1, "two" ]
    // good
    arr = [
      1,
      "two"
    ]
    // bad
    arr = [
      1, "two" ]
    */
    "ArrayLiteralConventions": {
      "requireOnePerLineWhenMultiline": true
    }
  }

JSCodeSniffer and Continuous Integration

Setting up Apache Ant build script reporting to Jenkins Checkstyle plugin.

NOTE: If you have phpcs-ci ant target, invoke it prior to this one. Jscs will find created by phpcs checkstyle.xml and extend its body instead of overriding the report.

<target name="jscs-ci"
         description="Find coding standard violations using JS_CodeSniffer and print human readable output.">
  <exec executable="jscs">
   <arg value="--standard=Jquery" />
   <arg value="--report=checkstyle" />
   <arg value="--report-file=${basedir}/build/logs/checkstyle.xml" />
   <arg path="${basedir}/src" />
  </exec>
 </target>

Setting up Grunt task

Gruntfile.js

grunt.loadNpmTasks('grunt-contrib-jscs');
grunt.initConfig({
     // Validate against jQuery coding standard
     jscs: {
        options: {
            "standard": "Jquery"
        },
        all: ["js-folder"]
     }
  });

package.json

"devDependencies": {
    //..
    "grunt-contrib-jscs": "*"
  }

Using the Subversion pre-commit hook

A pre-commit hook is a feature available in the Subversion version control system that allows code to be validated before it is committed to the repository. Edit scripts/jscs-svn-pre-commit and replace JSCS value with your own path to JS CodeSniffer

JSCS = "/your-path/jscodesniffer"

Make a symlink of scripts/jscs-svn-pre-commit in your repository hooks folder. E.g.

ln -s /<full path>/scripts/jscs-svn-pre-commit /repositories/<project>/hooks/pre-commit

Using the git pre-commit hook

Make a symlink of scripts/jscs-git-pre-commit in your repository .git/hooks folder. E.g.

ln -s /<full path>/scripts/jscs-git-pre-commit /<project>/.git/hooks/pre-commit

githalytics.com alpha

Readme

Keywords

Package Sidebar

Install

npm i os-jscs

Weekly Downloads

0

Version

0.1.6

License

MIT

Last publish

Collaborators

  • roocuriel