jslint-org / jslint

JSLint, The JavaScript Code Quality and Coverage Tool
https://www.jslint.com
The Unlicense
3.62k stars 463 forks source link
coverage-report javascript jslint zero-config zero-dependency

JSLint, The JavaScript Code Quality and Coverage Tool

Douglas Crockford douglas@crockford.com

Status

Branch master
(v2024.11.24)
beta
(Web Demo)
alpha
(Development)
CI ci ci ci
Coverage coverage coverage coverage
Demo
Artifacts



Table of Contents

  1. Web Demo

  2. Web Demo Archived

  3. Quickstart Install

  4. Quickstart JSLint Report

  5. Quickstart V8 Coverage Report

  6. Quickstart JSLint in CodeMirror

  7. Quickstart JSLint in Vim

  8. Quickstart JSLint in VSCode

  9. Documentation

  10. Package Listing

  11. Changelog

  12. License

  13. Devops Instruction



Web Demo

screenshot



Web Demo Archived



Quickstart Install



To install, just download and save https://www.jslint.com/jslint.mjs to file:

#!/bin/sh

curl -L https://www.jslint.com/jslint.mjs > jslint.mjs

screenshot



To run jslint.mjs in shell:

#!/bin/sh

printf "console.log('hello world');\n" > hello.js

node jslint.mjs hello.js

screenshot



To import jslint.mjs in ES Module environment:

#!/bin/sh

node --input-type=module --eval '

/*jslint devel*/

// Import JSLint in ES Module environment.

import jslint from "./jslint.mjs";

let globals = ["caches", "indexedDb"];
let options = {browser: true};
let result;
let source = "console.log(\u0027hello world\u0027);\n";

// JSLint <source> and print <formatted_message>.

result = jslint.jslint(source, options, globals);
result.warnings.forEach(function ({
    formatted_message
}) {
    console.error(formatted_message);
});

'

screenshot



To import jslint.mjs in CommonJS environment:

#!/bin/sh

node --eval '

/*jslint devel*/
(async function () {
    let globals = ["caches", "indexedDb"];
    let jslint;
    let options = {browser: true};
    let result;
    let source = "console.log(\u0027hello world\u0027);\n";

// Import JSLint in CommonJS environment.

    jslint = await import("./jslint.mjs");
    jslint = jslint.default;

// JSLint <source> and print <formatted_message>.

    result = jslint.jslint(source, options, globals);
    result.warnings.forEach(function ({
        formatted_message
    }) {
        console.error(formatted_message);
    });
}());

'

screenshot



To JSLint entire directory in shell:

#!/bin/sh

# JSLint directory '.'

node jslint.mjs .

screenshot



Quickstart JSLint Report



To create a JSLint report in shell:

#!/bin/sh

printf "function foo() {console.log('hello world');}\n" > hello.js

# Create JSLint report from file 'hello.js' in shell.

node jslint.mjs \
    jslint_report=.artifact/jslint_report_hello.html \
    hello.js

screenshot

screenshot



To create a JSLint report in javascript:

#!/bin/sh

node --input-type=module --eval '

/*jslint devel*/
import jslint from "./jslint.mjs";
import fs from "fs";
(async function () {
    let result;
    let source = "function foo() {console.log(\u0027hello world\u0027);}\n";

// Create JSLint report from <source> in javascript.

    result = jslint.jslint(source);
    result = jslint.jslint_report(result);
    result = `<body class="JSLINT_ JSLINT_REPORT_">\n${result}</body>\n`;

    await fs.promises.mkdir(".artifact/", {recursive: true});
    await fs.promises.writeFile(".artifact/jslint_report_hello.html", result);
    console.error("wrote file .artifact/jslint_report_hello.html");
}());

'

screenshot

screenshot



Quickstart V8 Coverage Report



To create V8 coverage report from Node.js / Npm program in shell:

#!/bin/sh

git clone https://github.com/tryghost/node-sqlite3 node-sqlite3-sh \
    --branch=v5.0.11 \
    --depth=1 \
    --single-branch

cd node-sqlite3-sh
npm install

# Create V8 coverage report from program `npm run test` in shell.

node ../jslint.mjs \
    v8_coverage_report=../.artifact/coverage_sqlite3_sh/ \
        --exclude=tes?/ \
        --exclude=tes[!0-9A-Z_a-z-]/ \
        --exclude=tes[0-9A-Z_a-z-]/ \
        --exclude=tes[^0-9A-Z_a-z-]/ \
        --exclude=test/**/*.js \
        --exclude=test/suppor*/*elper.js \
        --exclude=test/suppor?/?elper.js \
        --exclude=test/support/helper.js \
        --include=**/*.cjs \
        --include=**/*.js \
        --include=**/*.mjs \
        --include=li*/*.js \
        --include=li?/*.js \
        --include=lib/ \
        --include=lib/**/*.js \
        --include=lib/*.js \
        --include=lib/sqlite3.js \
    npm run test

screenshot

screenshot

screenshot



To create V8 coverage report from Node.js / Npm program in javascript:

#!/bin/sh

git clone https://github.com/tryghost/node-sqlite3 node-sqlite3-js \
    --branch=v5.0.11 \
    --depth=1 \
    --single-branch

cd node-sqlite3-js
npm install

node --input-type=module --eval '

/*jslint node*/
import jslint from "../jslint.mjs";
(async function () {

// Create V8 coverage report from program `npm run test` in javascript.

    await jslint.v8CoverageReportCreate({
        coverageDir: "../.artifact/coverage_sqlite3_js/",
        processArgv: [
            "--exclude=tes?/",
            "--exclude=tes[!0-9A-Z_a-z-]/",
            "--exclude=tes[0-9A-Z_a-z-]/",
            "--exclude=tes[^0-9A-Z_a-z-]/",
            "--exclude=test/**/*.js",
            "--exclude=test/suppor*/*elper.js",
            "--exclude=test/suppor?/?elper.js",
            "--exclude=test/support/helper.js",
            "--include=**/*.cjs",
            "--include=**/*.js",
            "--include=**/*.mjs",
            "--include=li*/*.js",
            "--include=li?/*.js",
            "--include=lib/",
            "--include=lib/**/*.js",
            "--include=lib/*.js",
            "--include=lib/sqlite3.js",
            "npm", "run", "test"
        ]
    });
}());

'

screenshot

screenshot

screenshot



Quickstart JSLint in CodeMirror

  1. Download and save jslint.mjs, jslint_wrapper_codemirror.js to file.

  2. Edit, save, and serve example html-file below:

    
    <!DOCTYPE html>
    <html lang="en">
    <head>
    <meta charset="utf-8">
    <title>CodeMirror: JSLint Demo</title>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.10/codemirror.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.10/addon/lint/lint.css">
<script defer src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.10/codemirror.js"></script>
<script defer src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.10/mode/javascript/javascript.js"></script>
<script defer src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.10/addon/lint/lint.js"></script>
<script type="module" src="https://github.com/jslint-org/jslint/raw/beta/jslint.mjs?window_jslint=1"></script>
<script defer src="https://github.com/jslint-org/jslint/raw/beta/jslint_wrapper_codemirror.js"></script>

CodeMirror: JSLint Demo

This demo will auto-lint the code below, and auto-generate a report as you type.

3. Live example at https://www.jslint.com/jslint_wrapper_codemirror.html

[![screenshot](https://jslint-org.github.io/jslint/branch-beta/.artifact/screenshot_browser__2fjslint_2fbranch-beta_2fjslint_wrapper_codemirror.html.png)](https://jslint-org.github.io/jslint/jslint_wrapper_codemirror.html)

<br><br>
# Quickstart JSLint in Vim
1. Download and save [`jslint.mjs`](https://www.jslint.com/jslint.mjs), [`jslint_wrapper_vim.vim`](https://www.jslint.com/jslint_wrapper_vim.vim) to directory `~/.vim/`
2. Add vim-command `:source ~/.vim/jslint_wrapper_vim.vim` to file `~/.vimrc`
    - If above files were saved to custom-directory, then use that directory instead, e.g.:
        - save [`jslint.mjs`](https://www.jslint.com/jslint.mjs), [`jslint_wrapper_vim.vim`](https://www.jslint.com/jslint_wrapper_vim.vim) to directory `~/vimfiles/`
        - vim-command `:source ~/vimfiles/jslint_wrapper_vim.vim`
3. Vim can now jslint files (via nodejs):
    - with vim-command `:SaveAndJslint`
    - with vim-key-combo `<Ctrl-S> <Ctrl-J>`
- screenshot

[![screenshot](asset_image_jslint_wrapper_vim.png)](https://www.jslint.com/jslint_wrapper_vim.vim)

<br><br>
# Quickstart JSLint in VSCode
1. In VSCode, search and install extension [`vscode-jslint`](https://marketplace.visualstudio.com/items?itemName=jslint.vscode-jslint)
2. In VSCode, while editing a javascript file:
    - right-click context-menu and select `[JSLint - Lint File]`
    - or use key-binding `[Ctrl + Shift + J], [L]`
    - or use key-binding `[ Cmd + Shift + J], [L]` for Mac
- screenshot

[![screenshot](https://jslint-org.github.io/jslint/asset_image_jslint_wrapper_vscode.png)](https://marketplace.visualstudio.com/items?itemName=jslint.vscode-jslint)

<br><br>
# Documentation

- [jslint.mjs](jslint.mjs) contains the jslint function. It parses and analyzes a source file, returning an object with information about the file. It can also take an object that sets options.

- [index.html](index.html) runs the jslint.mjs function in a web page.

JSLint can be run anywhere that JavaScript (or Java) can run.

The place to express yourself in programming is in the quality of your ideas and
the efficiency of their execution. The role of style in programming is the same
as in literature: It makes for better reading. A great writer doesn't express
herself by putting the spaces before her commas instead of after, or by putting
extra spaces inside her parentheses. A great writer will slavishly conform to
some rules of style, and that in no way constrains her power to express herself
creatively. See for example William Strunk's The Elements of Style
[https://www.crockford.com/style.html].

This applies to programming as well. Conforming to a consistent style improves
readability, and frees you to express yourself in ways that matter. JSLint here
plays the part of a stern but benevolent editor, helping you to get the style
right so that you can focus your creative energy where it is most needed.

<br><br>
### API Doc
- https://www.jslint.com/apidoc.html

[![screenshot](https://jslint-org.github.io/jslint/branch-beta/.artifact/screenshot_browser__2f.artifact_2fapidoc.html.png)](https://www.jslint.com/apidoc.html)

<br><br>
### Directive `/*jslint*/`

<br>

##### `/*jslint beta*/`

```js
/*jslint beta*/
// Enable experimental warnings.
// Warn if global variables are redefined.
// Warn if const / let statements are not declared at top of function or
//    script, similar to var statements.
// Warn if const / let / var statements are not declared in ascii-order.
// Warn if named-functions are not declared in ascii-order.
// Warn if cases in switch-statements are not in ascii-order.


/*jslint bitwise*/
/*jslint bitwise*/
// Allow bitwise operator.

let foo = 0 | 1;


/*jslint browser*/
/*jslint browser*/
// Assume browser environment.

localStorage.getItem("foo");


/*jslint convert*/
/*jslint convert*/
// Allow conversion operator.

let foo = new Date() + "";
let bar = !!0;


/*jslint couch*/
/*jslint couch*/
// Assume CouchDb environment.

registerType("text-json", "text/json");


/*jslint devel*/
/*jslint devel*/
// Allow console.log() and friends.

console.log("hello");


/*jslint eval*/
/*jslint eval*/
// Allow eval().

eval("1");


/*jslint fart*/
/*jslint fart*/
// Allow complex fat-arrow.

let foo = async ({bar, baz}) => {
    return await bar(baz);
};


/*jslint for*/
/*jslint for*/
// Allow for-loop.

function foo() {
    let ii;
    for (ii = 0; ii < 10; ii += 1) {
        foo();
    }
}


/*jslint getset*/
/*jslint getset, this, devel*/
// Allow get() and set().

let foo = {
    bar: 0,
    get getBar() {
        return this.bar;
    },
    set setBar(value) {
        this.bar = value;
    }
};
console.log(foo.getBar); // 0
foo.setBar = 1;
console.log(foo.getBar); // 1


/*jslint indent2*/
/*jslint indent2*/
// Use 2-space indent.

function foo() {
  return;
}


/*jslint long*/
/*jslint long*/
// Allow long lines.

let foo = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";


/*jslint node*/
/*jslint node*/
// Assume Node.js environment.

require("fs");


/*jslint nomen*/
/*jslint nomen*/
// Allow weird property name.

let foo = {};
foo._bar = 1;


/*jslint single*/
/*jslint single*/
// Allow single-quote strings.

let foo = '';


/*jslint subscript*/
/*jslint subscript*/
// Allow identifiers in subscript-notation.

let foo = {};
foo["bar"] = 1;


/*jslint this*/
/*jslint this*/
// Allow 'this'.

function foo() {
    return this;
}


/*jslint trace*/
/*jslint trace*/
// Include jslint stack-trace in warnings.

console.log('hello world');
/*
1. Undeclared 'console'.
console.log('hello world');
Error
    at warn_at (...)
    at warn (...)
    at lookup (...)
    at pre_v (...)
    at jslint.mjs
2. Use double quotes, not single quotes.
console.log(...);
Error
    at warn_at (...)
    at lex_string (...)
    at lex_token (...)
    at jslint_phase2_lex (...)
    at Function.jslint (...)
    at jslint.mjs
*/


/*jslint unordered*/
/*jslint unordered*/
// Allow unordered cases, params, properties, variables, and exports.

let foo = {bb: 1, aa: 0};

function bar({
    bb = 1,
    aa = 0
}) {
    return aa + bb;
}

export {
    foo,
    bar
};


/*jslint white*/
/*jslint white*/
// Allow messy whitespace.

let foo = 1; let bar = 2;



Directive /*global*/

/*global foo, bar*/
// Declare global variables foo, bar.

foo();
bar();



Directive /*property*/

/*property foo, bar*/
// Restrict property-access to only .foo, .bar.

let aa = {bar: 1, foo: 2};



Directive /*jslint-disable*/.../*jslint-enable*/

/*jslint-disable*/

JSLint will ignore and treat this region as blank-lines.
Syntax error.

/*jslint-enable*/



Directive //jslint-ignore-line

// JSLint will ignore non-fatal warnings at given line.

eval("1"); //jslint-ignore-line



Package Listing

screenshot_package_listing.svg



Changelog

screenshot_changelog.svg



License



Devops Instruction



pull-request merge

This PR will ...

This PR will additionally:

``` - verify `commit into jslint-org:beta` - click `Create pull request` - verify ci-success for pull-request - https://github.com/jslint-org/jslint/actions/workflows/on_pull_request.yml - wait awhile before continuing ... - click `Rebase and merge` - verify ci-success for upstream-branch-beta - https://github.com/jslint-org/jslint/actions - `shGitPullrequestCleanup` - verify ci-success for origin-branch-alpha - https://github.com/kaizhu256/jslint/actions - `git push upstream alpha -f` - verify ci-success for upstream-branch-alpha - https://github.com/jslint-org/jslint/actions - click `Delete branch`

### branch-master commit - `shGitPullrequest master beta` - verify ci-success for origin-branch-alpha - https://github.com/kaizhu256/jslint/actions - `git push upstream alpha -f` - verify ci-success for upstream-branch-alpha - https://github.com/jslint-org/jslint/actions - goto https://github.com/jslint-org/jslint/compare/beta...kaizhu256:jslint:branch-v2024.11.24 - click `Create pull request` - input `Add a title` with: `# v20yy.mm.dd` - input `Add a description` with: ``` - - ``` - verify `commit into jslint-org:beta` - click `Create pull request` - verify ci-success for pull-request - https://github.com/jslint-org/jslint/actions/workflows/on_pull_request.yml - wait awhile before continuing ... - click `Rebase and merge` - verify ci-success for upstream-branch-beta - https://github.com/jslint-org/jslint/actions - `shGitPullrequestCleanup` - verify ci-success for origin-branch-alpha - https://github.com/kaizhu256/jslint/actions - `git push upstream alpha -f` - verify ci-success for upstream-branch-alpha - https://github.com/jslint-org/jslint/actions - click `Delete branch` - `git push origin beta:master` - verify ci-success for origin-branch-master - https://github.com/kaizhu256/jslint/actions - `git push upstream beta:master` - verify ci-success for upstream-branch-master - https://github.com/jslint-org/jslint/actions

### branch-master publish - `git push upstream beta:master` - verify ci-success for upstream-branch-master - https://github.com/jslint-org/jslint/actions - goto https://github.com/jslint-org/jslint/releases/new - input `Choose a tag` with: `v20yy.mm.dd` - click `Create new tag: v20yy.mm.dd on publish` - verify correct-year `20yy` - select `Target: master` - select `Previous tag:auto` - input `Release title` with: `v20yy.mm.dd - ` - input `Describe this release` with: ``` - - ``` - click `Generate release notes` - click `Set as the latest release` - click `Preview` and review - click `Publish release` - verify ci-success for upstream-branch-publish - https://github.com/jslint-org/jslint/actions - verify email-notification `Successfully published @jslint-org/jslint@20yy.mm.dd`

### vscode-jslint publish - goto https://github.com/jslint-org/jslint/tree/gh-pages/branch-beta/.artifact/jslint_wrapper_vscode - click `vscode-jslint-20yy.mm.dd.vsix` - click `Raw` to download - goto https://marketplace.visualstudio.com/manage/publishers/jslint - right-click `Update` - upload downloaded file `vscode-jslint-20yy.mm.dd.vsix` - click 'Upload' - verify email-notification `[Succeeded] Extension publish on Visual Studio Marketplace - vscode-jslint`