Cảm thấy thế nào khi học Javascript trong năm 2016
Cảm xúc khi học javascript y hệt như bài viết này nên mình dịch lại cho vui. Link gốc: https://hackernoon.com/how-it-feels-to-learn-javascript-in-2016-d3a717dd577f Này, tao có một web project mới, nhưng nói thật là tao không code nhiều về web trong vài năm gần đây và tao nghe nói là mảng ...
Cảm xúc khi học javascript y hệt như bài viết này nên mình dịch lại cho vui. Link gốc: https://hackernoon.com/how-it-feels-to-learn-javascript-in-2016-d3a717dd577f
Này, tao có một web project mới, nhưng nói thật là tao không code nhiều về web trong vài năm gần đây và tao nghe
nói là mảng này đã thay đổi chút ít. Mày là thằng web dev biết nhiều nhất ở đây đúng không?
Đúng ra là kĩ sư front end, nhưng không sao, mày tìm đúng người rồi đấy. Tao làm web ở năm 2016. Có thể kể ra các thứ như mô phỏng, trình chơi nhạc, các drone biết chơi đá bóng. Tao vừa trở về từ JsConf và ReactConf, nên tao biết các công nghệ mới nhất để làm web apps.
Ngon, Tao muốn tạo một page có thể hiển thị hoạt động mới nhất từ người dùng, do vậy tao chỉ cần lấy dữ liệu từ REST endpoint và hiển thị nó ở cái bảng mà có thể lọc được, và cập nhật nó nếu có thay đổi ở server. Tao đang nghĩ là nên dùng jQuery để lấy và hiển thị dữ liệu.
Ôi mẹ ơi, không, không thằng nào dùng jQuery nữa đâu. Mày nên dùng React, đây là năm 2016 rồi
Ờ, ok. React là cái gì thế?
Nó là một thư viện siêu cool do mấy thằng cu ở Facebook làm ra, nó cho phép mày xử lí các thay đổi rất dễ dang, do vậy quản lí rất dễ và hiệu năng ngon.
Ờ, có vẻ được. Tao có thể dùng React để hiển thị data từ server được không?
Tất nhiên, nhưng trước hết mày phải thêm React và React DOM vào trong webpage của mày
Sao lại cần 2?
Một cái là thư viện thật, còn cái kia là để làm việc với DOM, cái mà giờ mày có thể viết bằng JSX
JSX? Là cái gì thế?
JSX chỉ là một extension cho cú pháp JavaScript, nó trông giống như XML. Đại loại là một cách khác để viết DOM, mày cứ nghĩ nó như kiểu version tốt hơn của HTML là được.
HTML bị làm sao thế?
Đây là năm 2016. Không ai code trực tiếp bằng HTML nữa đâu
Chuẩn, thế tao thêm 2 thư viện đấy vào là dùng được React?
Không hẳn, mày cũng cần cài Babel, sau đó mày có thể dùng React
Thư viện khác à? Babel là clgt?
À Babel là một trình chuyển mã nguồn cho phép mày chuyển mã sang bất cứ một version cụ thể nào của JavaScript, trong khi mày có thể code ở version khác. Mày không cần phải thêm Babel để dùng ReactJS, nhưng nếu không, mày sẽ gặp vấn đề với ES5, mà nói thật, 2016 rồi thì mày nên code với ES2016+ như mấy thằng dev giỏi giỏi khác
ES5? ES2016+? Tao bắt đầu thấy loạn rồi. Nó là cái *** gì thế?
ES5 là viết tắt của ECMAScript 5. Nó là phiên bản mà hầu hết mọi người đều hướng tới vì nó được tích hợp ở hầu hết các trình duyệt hiện tại.
ECMAScript?
Uhm, mày biết đấy, JavaScript được chuẩn hoá vào năm 1999, sau khi ra mắt lần đầu vào năm 1995. Lúc đấy JavaScript có tên là Livescript và chỉ chạy trên trình duyệt Netscape. Lúc đấy nó là một mớ hỗn độn, may mắn là hiện tại mọi thứ đã rõ rang, và chúng ta có khoảng ... 7 phiên bản cho nó
7 phiên bản, và ES5 và ES2016+ là?
Phiên bản thứ 5 và thứ 7
Đợi chút, chuyện gì xảy ra với phiên bản thứ 6?
ES6 à. Mỗi phiên bản là một bản cải tiến của phiên bản trước đó, cho nên nếu mày dùng ES2016+, mày cũng dùng tất cả các đặc tính của phiên bản trước đó
Uhm, nhưng sao lại dùng ES2016+ thay vì ES6?
Hmm, mày có thể dùng ES6, nhưng để dùng các thứ ngon ngon như async hay await thì phải dùng ES2016+. Nếu không mày sẽ gặp vấn đề với các coroutines khi kiểm soát flow bằng cách block các hàm gọi bất đồng bộ.
Tao không hiểu mày đang nói cái gì. Mấy cái tên đấy thật rắc rối. Nhìn này, tao chỉ lấy một nhúm dữ liệu từ server, tao chỉ cần thêm jQuery từ một CDN và dùng AJAX để làm điều đó, tại sao tao không được làm thế?
Đây là năm 2016 rồi chú, không ai dùng jQuery nữa, nó sẽ dẫn đến một đống spaghetti code. Ai cũng biết điều đó.
Chuẩn. Vậy cách làm là thêm 3 thư viện để lấy data và hiển thị ở HTML table.
Hmm, mày sẽ thêm 3 thư viện nhưng dùng trình quản lí module để đóng gói chúng lại thành 1 file
Vậy à, trình quản lí module là cái gì thế?
Định nghĩa phụ thuộc vào môi trường, nhưng ở lĩnh vực web, thường thì là bất cứ thứ gì có thể làm việc với các module AMD hay CommonJS.
Chuuuẩẩẩẩẩn. Vậy AMD và CommonJS là clgt?
Định nghĩa. Chúng là các cách để diễn tả làm thế nào các thư viện và class JavaScript làm việc cùng nhau. Mày biết export và requires? Mày có thể viết nhiều file JavaScript định nghĩa AMD hoặc CommonJS API và có thể dùng các tool như Browserify để đóng gói chúng
OK, tao nghĩ tao hiểu. Browserify là cái gì thế?
Nó là tool cho phép mày đóng gói các phụ thuộc diễn tả CommonJS thành các files có thể chạy được ở trình duyệt. Nó được làm ra vì hầu hết mọi người công bố các phụ thuộc ấy ở npm registry
npm registry?
Nó là một repository công cộng rất lớn, là nơi mà những người thông minh đưa code và các phụ thuộc lên như là các modules.
Giống như CDN?
Không hẳn. Nó giống như một database trung tâm hơn, là nơi mà mọi người có thể công bố và tải các thư viện, do vậy mày có thể sử dụng chúng ở máy mày và sau đó upload lên CDN nếu mày muốn.
Ờ, giống Bower!
Uh, nhưng đây là năm 2016, không ai dùng Bower nữa đâu.
Uh, biết rồi... vậy tao cần tải các thư viện từ npm?
Chuẩn, ví dụ nhé, nếu mày dùng React, mày tải React module và import nó vào code của mày. Mày có thể làm thế với hầu hết các thư viện JavaScript thông dụng.
Oh, giống Angular!
Angular là cho 2015. Nhưng đúng rồi. Angular vẫn ở đấy, bên cạnh VueJS hay RxJS và các thư viện cool khác của năm 2016. Muốn biết về chúng không?
Cứ nói về React đã, tao đã nghe đến rất nhiều thứ rồi. Thế nếu tao muốn dùng React, tao tải nó từ npm và dùng Browserify?
Chuẩn
Có vẻ hơi phức tạp quá khi chỉ cần lấy một nhúm các phụ thuộc và kết nối chúng với nhau.
Đúng vậy, cho nên mày cần dùng trình quản lí task như Grunt hoặc Gulp hoặc Broccoli để chạy Browserify tự động. Chết tiệt, mày thậm chí có thể dùng Mimosa.
Grunt? Gulp? Broccoli? Mimosa? Mày đang nói cái đ** gì thế?
Trình quản lí task. Nhưng chúng không còn ngon nữa. Chúng được dùng ở năm 2015, lúc mà chúng ta dùng Makefiles, nhưng bây giờ chúng ta gói tất cả bằng Webpack.
Makefiles? Tao tưởng nó chỉ được dùng ở các project C/C++ thôi chứ?
Yeah, nhưng rõ ràng là ở lĩnh vực web, chúng ta khoái làm mọi thứ phức tạp và sau đó quay lại với cơ bản. Chúng ta làm vậy hàng năm, và hãy đợi đấy, chúng ta sẽ dùng assembly cho web trong vòng một hai năm tới.
Đệch. Mày có nhắc tới thứ gì mà gọi là Webpack?
Nó vừa là một trình quản lí module khác cho trình duyệt, vừa là một trình chạy task. Nó là một phiên bản tốt hơn của Browserify.
Oh, Ok. Sao nó lại tốt hơn?
Hmm, có thể nó không tốt hơn, nó chỉ là có nhiều ý tưởng hơn về việc làm thế nào để kết nối các phụ thuộc. Webpack cho phép mày có thể dùng các trình quản lí module khác nhau, và không chỉ cho CommonJS, mà ví dụ như các modules làm việc với ES6 thuần.
Tao bị loạn với cái đống CommonJS/ES6 rồi.
*Ai cũng vậy, nhưng mày không cần quan tâm nữa, đã có SystemJS rồi. *
Jesus christ, lại một cái tên xxx-js. Ok, thế SystemJS là cái gì?
Hmm, khác với Browserify và Webpack 1.x, SystemJS là một module loader động cho phép mày nối nhiều modules vào nhiều files thay vì một file lớn.
Đợi chút, tao tưởng là mình muốn đóng gói các thư viện vào 1 file lớn và load nó!
Đúng rồi, nhưng HTTP/2 đang tới, và đa-HTTP-request rõ ràng là tốt hơn
Đợi chút, vậy là chúng ta không thể chỉ thêm 3 thư viện gốc cho React?
Không hẳn. Ý tao là mày có thể thêm chúng như là các external script từ CDN, nhưng mày vẫn cần thêm Babel.
Đệch, đó là luật à?
Uhm, mày có thể thêm toàn bộ babel-core, nhưng nó sẽ không hiệu quả cho production. Ở production, mày cần phải làm một loạt pre-tasks để cho project của mày sẵn sàng, điều đó tương tự như kiểu làm cho việc triệu hồi quỷ Satan trông giống như luộc trứng. Mày cần phải minify assets, uglify chúng, inline css, defer scripts, và...
Được rồi, được rồi. Nếu mày không thêm trực tiếp thư viện vào CDN thì mày làm như nào?
Tao sẽ dịch nó từ Typescript bằng cách dùng combo Webpack + SystemJS + Babel.
Typescript? Tao tưởng mình đang code bằng JavaScript!
Typescript là JavaScript, rõ nghĩa hơn, là một mở rộng của JavaScript, cụ thể hơn là JavaScript ở phiên bản ES6. Mày biết đấy, là phiên bản thứ 6 nói lúc nãy.
Tao tưởng ES2016+ đã là mở rộng của ES6! TẠI SAO lại cần thứ Typescript này?
Oh, là bởi vì nó cho phép chúng ta dùng JavaScript như là typed language, và giảm lỗi run-time. 2016 rồi, mày nên thêm kiểu vào trong code JavaScript.
Và Typescript hiển nhiên làm điều đó.
Flow cũng vậy, mặc dù nó chỉ kiểm tra kiểu, còn Typescript là một mở rộng của JavaScript cần được dịch.
Dm... và Flow là gì?
Nó là một trình kiểm tra kiểu được tạo ra bởi mấy thằng ở Facebook. Bọn nó code bằng OCaml, vì lập trình hàm thực sự rất đẹp.
OCaml? Lập trình hàm?
Nó là cái mà bọn giỏi dùng hiện nay đấy chú, mày biết không, 2016? Lập trình hàm? Hàm bậc cao? Currying? Hàm pure?
Tao đ** biết cái gì cả.
Không ai biết lúc mới bắt đầu. Nhìn này, mày chỉ cần biết là lập trình hàm tốt hơn là OOP và đó là thứ chúng ta nên dùng ở 2016.
Đợi đã, tao học OOP ở trường, và tao tưởng nó ngon?
Uh, trước khi Java bị Oracle mua. Ý tao là OOP đã từng tốt vào lúc đấy, và vẫn được dùng hiện nay, nhưng giờ mọi người nhận ra là sửa trạng thái tương đương với việc đá trẻ con, cho nên bây giờ mọi người chuyển sang immutable objects và lập trình hàm. Bọn Haskell đã ra rả vậy mấy năm rồi, và đừng để tao nói về bọn Elm, may mắn là với web thì ta có các thư viện như Ramda cho phép chúng ta dùng lập trình hàm cho JavaScript thuần.
Có phải mày thả mốt đống tên để doạ tao không? Cái méo gì là Ramnda?
Không, là Ramda, giống Lambda. Mày biết thư viện của David Chamber không?
David gì cơ?
David Chambers. Pro. Là một trong những người phát triển Ramda. Mày cũng nên tìm hiểu về Erik Meijer nếu mày muốn học lập trình hàm nghiêm túc
Và Erik Meijer là…?
Cũng là một thằng lập trình hàm. Rất ngon. Lão có một đống bài thuyết trình mà xé vụn Agile trong khi mặc cái áo màu dị dị. Mày cũng nên xem qua Tj, Jash Kenas, Sindre Sorhus, Paul Irish, Addy Osmani
OK. Tao phải stop mày thôi. Mấy cái đấy đều tốt, nhưng tao nghĩ tất cả đều quá phức tạp và không cần thiết khi chỉ cần lấy dữ liệu và hiển thị nó. Tao tin là tao ko cần phải biết những người đấy hay phải học tất cả mấy thứ này để tạo một table với dữ liệu động. Quay lại React đi, tao làm thế nào để lấy dữ liệu từ server với React?
Hmm, mày thực tế không lấy dữ liệu bằng React, mày chỉ hiển thị dữ liệu bằng React thôi.
Ôi, đm. Vậy tao làm thế nào lấy dữ liệu?
Mày dùng Fetch để fetch dữ liệu từ server.
Xin lỗi, mày nói là dùng Fetch để fetch dữ liệu? Thằng nào đặt tên cho mấy cái tên này cần một quyển từ điển cổ ngữ.
Tao biết. Fetch là tên của một implementation tự nhiên để thực hiện XMLHttpRequests đến server.
Oh, là AJAX còn gì.
AJAX chỉ là cách dùng của XMLHttpRequests, nhưng chắc chắn rồi, Fetch cho phép mày làm AJAX dựa trên promises, là thứ mà mày có thể resolve để tránh địa ngục callback.
Địa ngục callback?
Uhm. Bất cứ lúc nào mày thực hiện một request bất đồng bộ lên server, mày phải đợi response, điều đó làm cho mày thêm một hàm vào trong một hàm, cái đó gọi là kim tự tháp callback từ địa ngục.
Ờ, ok. Vậy cái promise này giải quyết nó?
Đúng rồi. Bằng cách biểu diễn callback thông qua promises, mày có thể viết code dễ hiểu hơn, mock và test chúng, cũng giống như thực hiện nhiều request một lúc và đợi đến lúc tất cả chúng xong.
Cái đó có thể làm với Fetch à?
Uhm, nhưng chỉ khi user của mày dùng browser ngon, nếu không mày phải thêm Fetch polyfill hoặc dùng Request, Bluebird hoặc Axios.
Có bao nhiêu thư viện tao cần phải biết hả? Bao nhiêu?
Đây là JavaScript. Có hàng ngàn thư viện làm những việc giống nhau. Ta biết thư viện, thực tế là ta có những thư viện tốt nhất. Thư viện của chúng ta rất lớn, và thi thoảng ta thêm ảnh của Guy Fieri vào đấy.
Mày vừa nhắc Guy Fieri à? Thôi kệ mẹ nó. Bluebird, Request, Axios làm cái gì?
Chúng là các thư viện thực hiện XMLHttpRequests và trả về promise.
Hàm AJAX của jQuery chưa bắt đầu trả về promise à?
Chúng ta không dùng từ "J" ở năm 2016 nữa. Chỉ cần dùng Fetch và polyfill nếu nó không chạy trên browser hỗ trợ, hoặc là dùng Bluebird, Request hay Axios. Sau đấy quản lí promise với await trong hàm async và boom, mày có một flow xử lí chuẩn.
Đây là lần thứ 3 mày nhắc đến await nhưng tao không biết gì về nó.
Await cho phép mày block một lời gọi bất đồng bộ, cho phép mày có sự kiểm soát tốt hơn đối với thời gian dữ liệu được load, và trên tổng thể sẽ tăng tính dễ đọc của code. Nó ngon, mày chỉ cần lưu ý thêm stage-3 preset vào Babel, hoặc dùng plugin syntax-async-functions và transform-async-to-generator.
Thật là vãi đ**
Không, vãi đ** là ở chỗ mà cần phải dịch Typescript code và chuyển nó với Babel để dùng await.
Cái gì? Nó không có trong Typescript à?
Nó sẽ có trong version tới, nhưng version 1.7 chỉ hướng đến ES6, cho nên nếu mày muốn dùng await ở browser, mày cần phải dịch Typescript code sang ES6 và Babel sẽ chuyển nó sang ES5.
Cạn lời.
Nhìn này, nó dễ thôi. Code mọi thứ ở Typescript. Tất cả module dùng Fetch thì dịch nó sang ES6, chuyển nó với Babel ở stage-3 preset, và load nó với SystemJS. Nếu mày không dùng Fetch, polyfill nó, hoặc dùng Bluebird, Request hay Axios, và xử lí tất cả promise với await.
Chúng ta có định nghĩa rất khác nhau về sự dễ. Với cái nguyên tắc đấy, cuối cùng tao có thể lấy dữ liệu và hiển thị với React rồi đúng không?
App của mày có xử lí các thay đổi trạng thái không?
Err, tao không nghĩ thế. Tao chỉ cần hiển thị dữ liệu.
Ồ, cám ơn chúa. nếu không tao phải giải thích và implementation của nó như là Flummox, Alt, Fluxible. Mặc dù nói thật là mày nên dùng Redux.
Tao chuẩn bị bay trên mấy cái tên đấy. Một lần nữa, tao chỉ cần hiển thị dữ liệu.
Oh, nếu mày chỉ cần hiển thị dữ liệu, mày không cần React để bắt đầu. Mày sẽ ổn với templating engine.
Mày đùa tao à? Mày nghĩ thế này là vui à? Mày đối xử với bạn bè thế à?
Tao chỉ đang giải thích cái mày có thể dùng thôi mà.
Stop. Stop đê.
Ý tao là, nếu mày chỉ dùng templating engine, thì cũng nên dùng Typescript + SystemJS + Babel.
Tao chỉ cần hiển thị dữ liệu, không phải thực hiện Sub Zero’s original MK fatality. Mày chỉ cần nói với tao templating engine nào và tao sẽ bắt đầu từ đấy.
Cả đống, mày quen cái nào?
Ugh, không nhớ, lâu lắm rồi.
jTemplates? jQote? PURE?
Err, không, còn cái khác không?
Transparency? JSRender? MarkupJS? KnockoutJS? Đó là thứ có two-way binding
Cái khác?
PlatesJS? jQuery-tmpl? Handlebars? Một số người vẫn còn dùng chúng
Có thể. Có cái nào giống giống cái cuối không?
Mustache, underscore? Tao nghĩ đến cả lodash, nhưng đó là thứ dành cho 2014.
Err.. có thể nó vẫn mới.
Jade? DustJS
Không.
DotJS? EJS?
Không.
Nunjucks? ECT?
Không.
Mah, không còn ai thích CoffeeScript nữa. Jade?
Không, mày nó Jade rồi.
Pug, Jade. Ý tao là Jade bây giờ là Pug.
Đệch, không, không nhớ. Mày dùng cái gì?
Chắc chỉ cần dùng ES6 native template strings
Để tao đoán. Nó cần ES6.
Chuẩn
Là thứ mà phụ thuộc vào browser, tao cần Babel.
Chuẩn
Là thứ mà nếu tao muốn thêm mà không phải thêm toàn bộ thư viện, tao phải load nó từ npm
Chuẩn
Là thứ cần Browserify, hay Webpack, hay SystemJS.
Chuẩn
Nếu không là Webpack, cần phải có task runner.
Chuẩn
Nhưng, vì tao nên dùng lập trình hàm và typed language, tao cần phải dịch Typescript và add mấy thứ liên quan.
Chuẩn
Và gửi cho Babel nếu tao muốn dùng await.
Chuẩn
Tao có thể dùng Fetch, promise và quản lí flow và đấy là tất cả.
Đừng quên polyfill Fetch nếu nó không được hỗ trợ, Safari vẫn chưa hỗ trợ đâu.
Mày biết không, tao nghĩ chúng ta tiêu rồi. Thực ra là tao nghĩ tao tiêu rồi. Tao tiêu với web, tao tiêu với JavaScript.
Không sao, vài năm tới ta sẽ code bằng Elm hoặc WebAssembly
Tao mới chỉ quay lại backend. Tao không thể xử lí được cái đống thay đổi và phiên bản và compiler và transpiler này. Cộng đồng JavaScript thật là vãi đ** nếu nó nghĩ là ai cũng theo được.
Tao hiểu. Mày nên thử cộng đồng Python
Tại sao?
Đã bao giờ nghe Python 3 chưa?
Không biết cộng đồng Python có gì hay.