wesaynih / infrastructure

© 2016 The Knights Who Say NIH — Do NOT fork this repository without permission.
http://frameless.io/
Other
0 stars 1 forks source link

Configure our specific needs for JavaScript style checking #8

Open Robbert opened 8 years ago

Robbert commented 8 years ago

There are a couple of eslint rules I initally wanted to use but prove problematic:

return uri.path      === base.path
    && uri.authority === base.authority
    && uri.query     === base.query
    && uri.scheme    === base.scheme;
/** @type {Array.<string>} */
URI.prototype.dirs;

Fortunately the Closure Compiler also supports detection of unused expressions, so it isn't a blocking issue, but during development it would still be great to have eslint errors for unused code inside Sublime.

var match = /** @type {Array.<string>} */ (URI.regexp1.exec(string));
e = /** @type {Error} */ (e);
e = /** @type {Error} */ (e);

I would like to tweak the implementation of this rule to recognize JSDoc comments.

var n = 0, l = 1E5;
for (; n < l; n += 2) {
}
Robbert commented 8 years ago

I think it would be good to configure all settings explicitly, even when we use the same value as the implicit default.

Yolijn commented 8 years ago

I suggest we try to use an eslint rule for overwriting the no-unused-expressions check. This way we could get warnings during development (in Sublime) but not for commit checks.

Robbert commented 8 years ago

I'm leaning towards single quotes for JavaScript and CSS, double quotes for HTML.

Reasons:

var href = explicit ? "" : ".";
var snippet = '<a href="?q=test">hello world</a>';
var href = explicit ? '' : '.';
var snippet = '<a href="?q=test">hello world</a>';

@Yolijn Decision day!

Robbert commented 8 years ago

Just found out I can convert the entire codebase to single quotes with this oneliner on the command line:

eslint --fix --no-eslintrc --rule "quotes: ['error', 'single', { 'avoidEscape': true }]" src/
Robbert commented 8 years ago

Single quotes it is! Jay.

Robbert commented 8 years ago

Curly braces on the same line or the next line?

function (a) {
    if (a) {
        return 1;
    }
    else {
        return -1;
    }
}

Or:

function (a)
{
    if (a)
    {
        return 1;
    }
    else
    {
        return -1;
    }
}

Or:

function (a)
{
    if (a) {
        return 1;
    } else {
        return -1;
    }
}

Or:

function (a)
{
    if (a) {
        return 1;
    }
    else {
        return -1;
    }
}

Or:

function (a) {
    if (a) {
        return 1;
    }
    else {
        return -1;
    }
}

Example scripts:

Observations:

Robbert commented 8 years ago

Regarding the eqeqeq rule:

// Before implementing `valueOf`:
if (xslTemplate.qName.namespaceURI === "http://www.w3.org/1999/xhtml" &&
    xslTemplate.qName.name === "script") {
}

// After implementing `valueOf`:
if (xslTemplate.qName == "{http://www.w3.org/1999/xhtml}script") {
}

Regarding the option allow-null:

Robbert commented 8 years ago

I've forked and tweaked eslint to support configuring custom types in valid-typeof.js.

When you use npm link to use this fork you can now use:

{
  "rules": {
    "valid-typeof": ["error", { "allow": ["unknown"] }]
  }
}

This way typeof foo !== "unknown" won't result in an error.

Robbert commented 8 years ago

I have disabled the no-control-regex option to allow implementing expressions such as:

Character.NON_LOWER_ASCII = /[^\x00-\x7f]/g

The use case for this test is of course accidental uses of control characters, and it seems that it is all too easy to put an escape slash in front of a zero: 0 -> \0. Perhaps it is wise to disallow this one, and explicitly require the more verbose \x00.

Robbert commented 8 years ago

With great power comes great responsibility: I'm moving the rule: ["off"] for a couple of checks to the specialized src/.eslintrc.json. This means that some things are only allowed in library code, and not in application code.

For example:

Also, because we need to prevent minifying of properties sometimes:

Robbert commented 8 years ago

I guess we should have the setup for the test/ directory, where we can disable some rules because we want our code to work in edge cases or test for XSS vulnerabilities.

Robbert commented 8 years ago

These are best left to Closure Compiler:

The following are ES6 rules and need to be defined when we start using ES6. Currently set to off:

Some rules are disabled because they are taken care off by other rules:

Robbert commented 8 years ago

Regarding init-rule-declaration, I would want to enforce declarations for primitive literals, but not for more memory heavy values like objects and arrays.

Bad:

var index, length, obj,
    array = [];
index = 0;
length = array.length;

if (enabled) {
    obj = {};
}

Good:

var obj,
    index = 0,
    length = array.length,
    array = [];

if (enabled) {
    obj = {};
}

This is not possible with eslint currently, but we could implement it.

Robbert commented 8 years ago

The should be warnings in wealth/ and errors in frameless/:

"lines-around-comment": [2, { "allowBlockEnd": true } is causing a lot of errors for unfinished commented out code after a return value:

function ()
{
    ...

    return output;

    // TODO: Finish implementation
    /*
    for (var ...
    */
}

Of course we shouldn't allow this in the high-quality repository, but we should enable warnings for this in the meantime.

Robbert commented 8 years ago

no-dupe-args is desirable, but I like using duplicate vars for unused variables in callback functions for String.prototype.replace:

regexp.replace(function ()_, firstName, _, _, lastName) {
});
Robbert commented 8 years ago

"operator-linebreak": ["error", "before"] currently seems to require all binary operators to be spread accross lines. Of course this is highly undesirable. We need to tweak the implementation to test for situations on which the left-hand side and right-hand side are on different lines, and only then report the situation.

Robbert commented 8 years ago

max-statements-per-line is buggy for { "max": 1 }.

Robbert commented 8 years ago
Robbert commented 8 years ago

Related reading:

  1. https://engineering.mongodb.com/post/succeeding-with-clangformat-part-1-pitfalls-and-planning/
  2. https://engineering.mongodb.com/post/succeeding-with-clangformat-part-2-the-big-reformat/