Nói nhảm chuyện Vue hay React và Coding Style
Có mấy chia sẻ nhỏ, mình muốn đưa ra để mọi người cùng thảo luận góp ý. Thread này không tập trung vào Technical nữa mà discuss về Coding Style & Working Performance, vốn là những thứ mình chỉ thực sự thấm sau hơn năm miệt mài với Vue. Xưa mình từng nghĩ ESLint là thứ rườm rà. Code team ...
Có mấy chia sẻ nhỏ, mình muốn đưa ra để mọi người cùng thảo luận góp ý. Thread này không tập trung vào Technical nữa mà discuss về Coding Style & Working Performance, vốn là những thứ mình chỉ thực sự thấm sau hơn năm miệt mài với Vue.
Xưa mình từng nghĩ ESLint là thứ rườm rà.
Code team còn chấp nhận đc, code một mình mà cũng xài Lint thì có vẻ rảnh; lo chạy đc là tốt rồi ai lại rỗi hơi đi quan tâm từng cái dấu chấm phẩy hay ngoặc kép ngoặc đơn, dù cho mình có biết đến prettier đi chăng nữa. Mình có khoảng năm sáu dự án viết một mình bằng cả Vue với React, không thèm lint; và hệ quả là lắm lúc quay trở lại những dự án tới cả trăm component đó sau vài tháng, nó giống như... địa ngục, một thành phố sau trận động đất huỷ diệt hay mấy thứ na ná vậy.
Không thể hiểu nổi chính cách tổ chức code của mình, không thể hiểu nổi mình đã viết gì trong một cái hàm 20 dòng khi đầu tiên nhìn vào là thấy... đau mắt chetconme đã.
Cũng tại thời đó mình mới học Vue, xây dựng app hoàn toàn thủ công không dựa vào các scaffold phổ biến như Vue-cli hay Nuxt, nên phải mất một thời gian rất dài mới nhận ra tầm quan trọng của Linter lẫn hiểu được cách thức tổ chức code của các scaffolder đó.
Có một dự án Vue mình quay lại tiếp quản tổng cộng 3 lần, cảm giác tệ hại phía trên xảy ra vào lần quay lại code thứ hai. Lần đó may mắn cũng là lần Vue CLI ra mắt phiên bản 3, mình cũng đang gánh một dự án khác & quyết định đến với Vue CLI chỉ vì bản tính ưa tò mò thử nghiệm (code nhanh code chậm không quan trọng bằng việc nghịch xem Vue CLI có gì hay ho k), và thiệt sự là... đống linter & prettier được tích hợp sẵn khiến mình code nhanh hơn rất nhiều, cùng với sự hỗ trợ đầy mạnh mẽ của WebStorm vốn là IDE ưa thích của mình. Tất nhiên, việc cài đặt thêm mấy thứ "rườm rà" đó vào dự án trước cũng khiến cho lần quay lại thứ 3 của mình sau đó nửa năm êm xuôi hơn, lại còn có thể tự tin bàn giao code cho mấy thằng em cùng công ty cũ & rũ bỏ cái mặc cảm "code mình chỉ có mình hiểu thôi chứ đ' ai hiểu nổi đâu!"
Cơ bản thì mình cũng khá lười việc đi tìm hiểu và so sánh 1 thứ mình quen thuộc với những thứ mình không hề đụng đến, nên mình sẽ không discuss vào việc tại sao nên dùng ESlint thay vì JSHint chẳng hạn. Tại mình thích và mình quen với nó thế thôi =)) cách sử dụng, mình cũng không muốn viết nhiều. Google từ khoá How to use ESlint là ra cả trăm kết quả na ná nhau ý mà.
Mấy mẹo tận dụng sức mạnh của IDE và Linter trong một dự án Vue.js/React
Trong giới hạn bài viết này mình đề cập đến WebStorm thôi nha. Mấy cái khác ít xài, hông biết =))
1. Tự động Fix lỗi Linter
WebStorm vốn cũng có một trang cài đặt cho mình tự quy ước Coding Style riêng, nhưng với mình mà nói thì cái tính năng có sẵn đấy khá là ngu vãi nồi. Nên mình chọn ESLint + Prettier, và cũng may là bản thân WebStorm integrate rất tốt với 2 thằng này bằng một cái menu tên là Reformat with Prettier. Vô trang cài đặt, tìm từ khoá Prettier, mục Keymap, gắn cho nó một cái Shortcut. Việc code trở nên đơn giản vô cùng, code đến đâu enter Shortcut đến đấy, khỏi lo ngứa mắt với mấy cái báo lỗi Linter của Webpack Dev.
2. Một số linter rules cực kì có ích trong Vue.js SFC (cũng là coding styles khuyên dùng)
Nếu siêng, có thể đọc hết tất cả tại đây.
- WebStorm hỗ trợ autocomplete props khi viết Components khá tốt, đổi lại là một số điều kiện (đến từ ESlint): không được khai báo kiểu prop là String mà phải là một Object kiểu (ví dụ không được declare type là
"Number"mà phải là Number, thứ nhất Object kiểu được WS hỗ trợ autocomplete, thứ hai, enter string nguy cơ sai tên kiểu rất cao) - Đừng vì lười mà khai báo props cho component kiểu như sau props : [ "foo", "bar" ],, cũng đừng khai báo types cho prop là null (tạm gọi là kiểu mẹ gì cũng được). Khai báo tên, kiểu (và default hay validation) rõ ràng cho mỗi prop để tránh nguy cơ data được truyền vào không đúng kiểu, console không đưa ra warning được, đến khi có lỗi lại debug trong đau khổ.
- Đặt tên rõ ràng cho mỗi Component sử dụng bằng hình thức import thông qua option name. Cái name đấy không có ích lắm cho code production nhưng rất có ích cho WS; bởi vì WS dựa vào mớ tên đó để autocomplete component khi code template (vừa gợi ý component, vừa tự động import và gắn nó vào option components, khỏi phải thủ công import và gắn mệt nghỉ nhé). Thử đi là biết!
- Sắp xếp các thuộc tính của Component cho đúng thứ tự từ trên xuống dưới, đừng tuỳ tiện, khi Component phình lớn ra thì việc đúng thứ tự đó rất tiết kiệm thời gian. Ví dụ như name -> components -> props -> data -> computed -> watch -> methods -> mấy cái lifecycle. Nếu khối lượng Component quá lớn mà không phân giải Component được thì tận dụng cặp comment # region/# endregion của WS cũng rất hay.
- Data của mỗi Component phải là một function. Evan You cũng đã có giải thích trên trang documentation rồi không nói lại. Xài Object như Root Component có vẻ thích hợp với những thằng lười nhưng lại dẫn đến một lỗi nguy hiểm chết người đấy.
- Cố gắng sử dụng scoped style hay tốt hơn nữa là cssmodule trong thẻ style. Bạn có thể dùng style thuần nếu đủ siêng năng chăm chỉ áp dụng quy ước BEM một cách thủ công (còn mình rất lười) hoặc chấp nhận đau đầu debug CSS vì lỗi xung đột classname đ' hiểu vì sao. Mình cũng không thích scoped style lắm, cảm giác nhìn vào html và thấy một đống data-v-cái-con-mẹ-gì-đó nó làm mình muốn ốm; chưa kể về mặt hiệu năng render thì DOM custom attribute cũng kém hơn id với class rất nhiều (đổi lại là sử dụng CSSModule cũng hơi tốn công sức hơn chút so với Scoped Style).
- Features của Vue với mình thì có hai dạng, khuyến khích áp dụng; hoặc chỉ nên dừng lại ở Trick, nghĩa là áp dụng càng ít càng tốt, lạm dụng những trick này sẽ khiến luồng dữ liệu pass qua các component trở nên rối như tơ vò không thể kiếm soát. Ví dụ: provide/inject, giao tiếp giữa các component cha/con thông qua $parent hay $refs. Rất mong các bạn recommend thêm cho mình một số feature tương tự và lý do để tương lai mình kiểm soát code tốt hơn.