I. ESlint là gì?

ESLint là một tiện ích linting JavaScript mã nguồn mở ban đầu được tạo bởi Nicholas C. Zakas vào tháng 6 năm 2013. Căn cứ vào những quy chuẩn về cách viết code đã thống nhất từ trước trong công ty hoặc dự án sẽ đặt ra quy chuẩn viết code. Hầu hết các ngôn ngữ lâp trình đều có code linter riêng và đôi khi các linter được kết hợp vào trình biên dịch (complier).
Javascript là ngôn ngữ thuộc dạng loosely-typed, hay bị lỗi trong quá trình viết code. Và do không có quá trình biên dịch mã nên javascript sẽ được chạy theo thứ tự để tìm ra lỗi cú pháp. Công cụ như Eslint cho phép tìm ra lỗi ngay cả khi chúng chưa được chạy.

II. Lợi ích của ESlint là gì?

  • Giúp tự động phát hiện , cảnh báo bug trong quá trình viết code.
  • Tiết kiệm thời gian sửa lỗi.
  • Giúp code chuẩn hơn , dễ nhìn hơn.

III. Cài đặt ESlint?

Yêu cầu Node.js (>=8.10), npm 3+.
install thông qua npm :
npm install eslint --save-dev

cài đặt file config :
./node_modules/.bin/eslint --init

dùng lệnh để kiểm tra với Eslint :
./node_modules/.bin/eslint yourfile.js

III. Cấu hình ESLint

ESLint được thiết kế để có thể cấu hình tất cả mọi thứ, bạn có thể tắt các rule và chỉ chạy với thiết lập cơ bản. Có hai cách chính để định cấu hình ESLint:

  • Configuration Comments - sử dụng comment JavaScript để thêm config trực tiếp vào một file.
  • Configuration Files - sử dụng file JavaScript, JSON hoặc YAML để chỉ định thông tin cấu hình cho toàn bộ thư mục. Ví dụ như ở dạng tệp .eslintrc. * Hoặc eslintConfig trong tệp pack.json.

Nếu có Configuration Files trong thư mục gốc thì ESLint sử dụng nó nếu không thể tìm thấy bất kỳ file cấu hình nào khác.

Có một số thông tin có thể được cấu hình:

  • Environments - môi trường mà được thiết kế để chạy.
  • Globals - các biến toàn cục được truy cập trong khi thực chạy.
  • Rules - rule nào được bật và được set ở mức độ nào.

Chỉ định Parser

Theo mặc định, ESLint sử dụng Espree làm trình phân tích cú pháp. Bạn có thể tùy ý chỉ định rằng một trình phân tích cú pháp khác sẽ được sử dụng trong tệp cấu hình của bạn.
Ví dụ: phần sau chỉ định sử dụng Esprima thay vì Espree:

{
    "parser": "esprima",
    "rules": {
        "semi": "error"
    }
}

Chỉ định Processor

Để chỉ định bộ xử lý trong config file, chỉ định processcor bằng dấu gạch ngang "-". Ví dụ:

{
    "plugins": ["a-plugin"],
    "processor": "a-plugin/a-processor"
}

Chỉ định Environments

Để chỉ định môi trường, sử dụng từ khóa env và chỉ định môi trường bạn muốn bật. Ví dụ: phần sau đây cho phép môi trường trình duyệt và Node.js:

{
    "env": {
        "browser": true,
        "node": true
    }
}

Chỉ định biến Globals

Nếu đang sử dụng các biến toàn cục bên trong một file mà không muốn ESLint cảnh báo thì khai báo như sau:

{
    "globals": {
        "var1": "writable",
        "var2": "readonly"
    }
}

Chỉ định Plugins

ESLint hỗ trợ sử dụng plugin của bên thứ ba. Trước khi sử dụng plugin, bạn phải cài đặt nó bằng npm.

Để định cấu hình các plugin bên trong file cấu hình, sử dụng từ khóa "plugins"

{
    "plugins": [
        "plugin1",
        "eslint-plugin-plugin2"
    ]
}

Cấu hình Rules

Sau khi chạy --init eslint, tập tin .eslintrc sẽ được tạo ra. Đây là tập tin config của ESlint

{
    "rules": {
        "semi": ["error", "always"],
        "quotes": ["error", "double"]
    }
}

Từ khóa "semi" and "quotes" là tên của rules trong ESLint. Giá trị đầu tiên là kiểu lỗi , có thể là một trong 3 giá trị sau :

"off" hoặc 0 - tắt rule
"warn" or 1 - chế độ warning của rule
"error" hoặc 2 - chế độ error của rule (chế độ này sẽ hiển thị exit code là 1)

trong file .eslintrc cũng sẽ bao gồm dòng:

"extends": "eslint:recommended"

dòng này nghĩa là tất cả các rule có dấu check trong trang https://eslint.org/docs/rules/
sẽ được bật mặc định

Ngoài ra còn nhiều các phần có thể config khác bạn có thể tham khảo thêm tại https://eslint.org/docs/user-guide/configuring

Tự viết Rule

Nếu không thể tìm thấy rule cần sử dụng , bạn có thể viết một rule mới.
Mỗi rule trong ESLint đều có 3 file với tên đặt theo quy tắc cố định (ví dụ : no-extra-semi).

  • lib/rules : code của rule (vd : no-extra-semi.js)
  • tests/lib/rules : test file (vd : no-extra-semi.js)
  • docs/rules : file tài liệu (vd : no-extra-semi)

Ví dụ source file của rule :

/**
 * @fileoverview Rule to disallow unnecessary semicolons
 * @author Nicholas C. Zakas
 */

"use strict";

//------------------------------------------------------------------------------
// Rule Definition
//------------------------------------------------------------------------------

module.exports = {
    meta: {
        type: "suggestion",

        docs: {
            description: "disallow unnecessary semicolons",
            category: "Possible Errors",
            recommended: true,
            url: "https://eslint.org/docs/rules/no-extra-semi"
        },
        fixable: "code",
        schema: [] // no options
    },
    create: function(context) {
        return {
            // callback functions
        };
    }
};

Thuộc tính cơ bản của 1 rule :
meta : bao gồm metadata của rule

  • type (string) loại rule("problem", "suggestion", "layout")
  • docs (object) tài liệu miêu tả rules
  • fixable (string) là "code" hoặc "whitespace" : tự động sửa code

create đây là hàm thực thi ESlint
ví dụ array-callback-return :

function checkLastSegment (node) {
    // report problem for function if last code path segment is reachable
}

module.exports = {
    meta: { ... },
    create: function(context) {
        // declare the state of the rule
        return {
            ReturnStatement: function(node) {
                // at a ReturnStatement node while going down
            },
            // at a function expression node while going up:
            "FunctionExpression:exit": checkLastSegment,
            "ArrowFunctionExpression:exit": checkLastSegment,
            onCodePathStart: function (codePath, node) {
                // at the start of analyzing a code path
            },
            onCodePathEnd: function(codePath, node) {
                // at the end of analyzing a code path
            }
        };
    }
};

messageIds

Khi viết rule bạn phải viết cả phần test , do vậy để tránh viết lại trùng nhau bạn nên sử dụng messageIds để gọi .

// in your rule
module.exports = {
    meta: {
        messages: {
            avoidName: "Avoid using variables named '{{ name }}'"
        }
    },
    create(context) {
        return {
            Identifier(node) {
                if (node.name === "foo") {
                    context.report({
                        node,
                        messageId: "avoidName",
                        data: {
                            name: "foo",
                        }
                    });
                }
            }
        };
    }
};

// in the file to lint:

var foo = 2;
//  ^ error: Avoid using variables named 'foo'

// In your tests:
var rule = require("../../../lib/rules/my-rule");
var RuleTester = require("eslint").RuleTester;

var ruleTester = new RuleTester();
ruleTester.run("my-rule", rule, {
    valid: ["bar", "baz"],
    invalid: [
        {
            code: "foo",
            errors: [
                {
                    messageId: "avoidName"
                }
            ]
        }
    ]
});

Tự động sửa lỗi

Chúng ta có thể dùng hàm tự sửa lỗi trong ESLint để sửa lỗi tự động. Ví dụ:

context.report({
    node: node,
    message: "Missing semicolon",
    fix: function(fixer) {
        return fixer.insertTextAfter(node, ";");
    }
});

Ngoài ra bạn có thể tham khảo thêm các thành phần khác tại https://eslint.org/docs/developer-guide/working-with-rules

IV. Kết luận

ESLint là một công cụ cực kỳ hữu ích giúp bạn tiết kiệm thời gian và tránh các lỗi thường gặp, nếu có thể bạn nên xài cho dự án của mình vừa chuẩn hóa code vừa tăng hiệu suất làm việc. Hy vọng bài viết sẽ giúp ích phần nào cho các bạn và các bạn code càng ngày càng đẹp hơn.

V. Nguồn tham khảo

https://eslint.org/