12/08/2018, 17:33

Tối ưu mã nguồn Javascript với Eslint

Để đánh giá chất lượng của một project, một trong số những yếu tố luôn được lưu tâm chính là mã nguồn, code có được được viết rõ ràng, tuân thủ coding conventions, hạn chế những đoạn mã dư thừa. Nếu bạn nhìn vào một dự án mà source code được viết thô xơ, lộn xộn, nó có thể khiến bạn mất tin tưởng ...

Để đánh giá chất lượng của một project, một trong số những yếu tố luôn được lưu tâm chính là mã nguồn, code có được được viết rõ ràng, tuân thủ coding conventions, hạn chế những đoạn mã dư thừa. Nếu bạn nhìn vào một dự án mà source code được viết thô xơ, lộn xộn, nó có thể khiến bạn mất tin tưởng vào đoạn code đó có thể thực hiện đúng chức năng mà bạn mong muốn.

Bên cạnh việc kiểm tra Coding convention thì Linters (Nhóm các phần mềm đọc code và cho biết đoạn code đó có bị lỗi về cú pháp hay code style không?) cũng là một công cụ thú vị để tìm các lỗi nhất định, ví dụ như các lỗi liên quan đến việc sử dụng biến toàn cục. Chỉ ra việc gán giá trị cho các biến chưa được khai báo hay sử dụng các biến chưa xác định, chính là một ví dụ về lỗi được chỉ ra bởi các Linters.

Một số linter cho JavaScript tiêu biểu có thể kể đến là JSLint, JSHint, và ESLint. Về bản chất thì 3 thằng này giống nhau. Trong bài viết này mình chỉ sẽ tập trung vào ESLint.

ESlint là công cụ mạnh được sử dụng nhiều với các Node.js package, và có thể cấu hình cho nhiều code style. Để cấu hình ESlint cho ứng dụng , đầu tiên bạn cần cài các package cần thiết:

npm install global babel-eslint eslint  eslint-plugin-react babel-preset-es2015 babel-preset-react

Sau đó bạn tạo file .eslintrc ở thư mục root của project:

{
    "parser": "babel-eslint",
    "parserOptions": {
        "ecmaVersion": 6,
        "sourceType": "module",
        "ecmaFeatures": {
            "experimentalObjectRestSpread": true,
            "jsx": true
        }
    },
    "env": {
        "es6": true,
        "amd": true,
        "jquery": true,
        "browser": true,
        "node": true
    },
    "globals": {
        "ion": true,
        "trans": true,
        "axios": true,
        "PropTypes": true,
        "Echo": true
    },
    "plugins": [
        "react"
    ],
    "extends": [
        "eslint:recommended",
        "plugin:react/recommended"
    ],
    "rules": {
         "no-console": 1,
         "eqeqeq": 2,
         "quotes": [2, "single"],
         "space-unary-ops": 0,
        "spaced-comment": 0,
        "strict": 2,
        "template-curly-spacing": 0,
        "use-isnan": 2,
        "valid-jsdoc": 0,
        "valid-typeof": 2,
        "vars-on-top": 0,
         ...
      }
}

Mỗi rule sẽ là 1 dòng như thế này, gồm có tên rule và cấu hình.

  • 1: là Warning
  • 2: là Error.

Nếu 1 rule cần thêm tham số cấu hình thì sẽ đặt nó trong cái array như ví dụ trên.

Sau khi cấu hình xong file trên, bạn chỉ cần chạy lệnh

eslint <đường_dẫn_đến_file_js>

Kết quả khi có lỗi như sau

  • "quotes": [1, "single"] :Cái này sẽ báo warning (vì mình dùng số 1), khi mình dùng dấu " (nháy kép) để khai báo hay sử dụng một cái string trong JS.
  • "space-before-blocks": 1 :Cái này sẽ nhắc mình thêm 1 dấu space trước khi mở ngoặc móc.
  • "no-trailing-spaces": 2
  • "no-multi-spaces": 2
  • "eqeqeq": 1 :Cái này sẽ warning khi bạn dùng == hoặc !=, để bạn luôn nhớ dùng === hoặc !== . Ở đây có giải thích lí do bạn nên dùng === thay vì ==
  • "valid-typeof": 1 : Tránh lỗi type khi so sánh type of, kiểu như nunber (đúng ra phải là number)
  • "no-unused-vars": [1, {"vars": "all", "args": "all"}]:Sẽ nhắc bạn về các biến được khai báo mà không sử dụng trong khai báo (vars) và trong đầu vào của hàm (args) -"no-unreachable": 1 : Cái này dùng để báo lỗi khí mà trong code có chỗ nào đó return trước 1 câu lệnh khác.
  • "no-console": 1 : Khỏi quên xóa console.logkhi debug.
  • "no-cond-assign": 1 : Tránh kiểu lỡ gõ nhầm lệnh gán trong phép so sánh, kiểu như thay vì so sánh a === 1 , thì lại gõ nhầm thành a = 1 nên câu lệnh if luôn chạy. Mình từng thấy cái này khi review code 1 lần rồi. Bạn chắc là không muốn bị bắt vì lỗi này đâu nhỉ             </div>
            
            <div class=
0