Thế giới rộng lớn của JavaScript

Thế giới rộng lớn của JavaScript
Photo by Pankaj Patel from Unsplash

Chúc mừng năm mới 🥳 🎇

JavaScript, ngôn ngữ lập trình phổ biến nhất hiện tại và ngày càng đóng vai trò quan trọng hơn trong thế giới công nghệ. Nó đã xuất hiện từ rất lâu và không ai có thể phủ nhận vai trò của nó. Trong bài viết này, tôi sẽ trình bày về thế giới của JavaScript (từ những gì tổng hợp được).

JavaScript là gì?

JavaScript là một ngôn ngữ lập trình, được tạo ra bởi Brendan Eich vào năm 1995. Đó là những năm đầu bùng nổ về trình duyệt web với cuộc chiến của 2 ông lớn lúc bấy giờ: Internet Explorer và Netscape Navigator. Hai trình duyệt đua nhau đưa ra những tính năng mới lạ cho người dùng và không ai được phép dừng lại, vì dừng lại nghĩa là thua cuộc.

Tác giả của JavaScript, Brendan Eich là một chuyên gia công nghệ làm việc cho Netscape, và ông đã cố gắng tạo ra một ngôn ngữ lập trình chạy ở phía client, cho phép các lập trình viên front end có thể đưa một vài chương trình nhỏ vào trang web của họ, khiến nó trở lên “động” hơn và dễ tương tác hơn. Một yêu cầu khác với ngôn ngữ này là nó phải mềm dẻo, dễ học và dễ lập trình.

Chính tác giả Brendan Eich nói rằng ông mất 10 ngày làm việc (quá khủng 🤩) để đưa ra phiên bản đầu tiên của ngôn ngữ này. Để tạo ra ngôn ngữ này, ông đã học hỏi từ nhiều ngôn ngữ khác nhau. Dưới đây là một số những ngôn ngữ có tầm ảnh hưởng lớn nhất:

  • Scheme – hàm cũng là đối tượng first class, dynamic typing
  • Perl – weak-typing
  • Self – Dễ dàng cài đặt, object dựa trên prototype
  • Java – Cú pháp và convention chính

Ngôn ngữ lúc đầu được gọi là Mocha và sau đó được công bố cùng với trình duyệt của Netscape với cái tên quen thuộc bây giờ: JavaScript.

Sự khác biệt của Java và JavaScript

Đây là một câu hỏi khá “hãm” mà tôi từng gặp khi phỏng vấn xin việc. Vì tương đồng trong tên gọi, nhiều người thích hỏi câu này để tỏ ra nguy hiểm 🤬.

Câu trả lời của tôi đơn giản thôi: Hai ngôn ngữ này chẳng có điểm gì chung, ngoại trừ một số cú pháp JavaScript học hỏi từ Java như dấu chấm phẩy, dấu ngoặc nhọn, một số cách viết biểu thức, v.v… Thực ra, việc đặt tên cho ngôn ngữ cũng là một cách marketing của Netscape để quảng bá cho ngôn ngữ mới của họ, khi mà Java lúc đó là một công nghệ đột phá, đang cực kỳ được ca ngợi.

Bởi sự thành công quá lớn của JavaScript, Microsoft đã dịch ngược nó, tìm hiểu và phát hành một ngôn ngữ tương tự của riêng họ với tên là JScript.

Với lịch sử đi kèm với sự cạnh tranh, có rất nhiều cài đặt khác của JavaScript và chúng thường không tương thích lẫn nhau. Để khắc phục vấn đề này, vào năm 1997, Netscape đã đưa JavaScript cho tổ chức Ecma International (tên gọi cũ là ECMA) để tiêu chuẩn hóa nó. Và từ đó chúng ta có ECMAScript.

JavaScript vs ECMAScript

Kết quả của việc tiêu chuẩn hóa JavaScript là ECMAScript, và nó được chấp nhận một cách rộng rãi rằng nó là đặc tả kỹ thuật của ngôn ngữ. Tuy vậy, ngôn ngữ lập trình vẫn giữ tên cũ là JavaScript vì mọi người đã quá quen cái tên này.

Để phát triển ngôn ngữ, thêm các tính năng mới và khiến nó tương thích với tiêu chuẩn của các tổ chức khác, đặc tả kỹ thuật ECMAScript được thay đổi liên tục và đến nay vẫn tiếp tục thay đổi.

Dưới đây là một số mốc update đặc tả ECMAScript chính.

ECMAScript 1

Phiên bản đầu tiên được tiêu chuẩn hóa của JavaScript.

ECMAScript 2

Đặc tả được công bố năm 1998, khi mà nó được tiêu chuẩn hóa bởi ISO/IEC. Việc update của Ecma để nó phù hợp với các tài liệu của ISO/IEC.

ECMAScript 3

Năm 1999, một số tính năng mới được thêm vào ngôn ngữ. Những thay đổi chính bao gồm:

  • Regular expression
  • Lệnh điều khiển mới
  • Exception handling

ECMAScript 4

Đây chỉ là bản nháp, sau đó đã bị hủy bỏ vào năm 2008 vì những bất đồng xung quanh tính năng của ngôn ngữ. Cuối cùng người ta quyết định rằng, đặc tả này đi trước thời đại quá xa và cần có một bản trung gian ra mắt trước đó.

ECMAScript 5

Đặc tả này công bố năm 2009 nhưng tác dụng của nó thì rất lớn. Một số tính năng được thêm vào lần này:

  • Các hàm duyệt phần từ (map, reduce, filter, forEach);
  • JSON
  • Getter & setter
  • Làm việc với object đơn giản hơn

ECMAScript 5.1

Tương tự như ECMAScript 2, đặc tả này được ra để phù hợp với các tài liệu của ISO/IEC cho ECMAScript 5.

ECMAScript 6 (AKA ES6, ECMAScript 2015, Harmony)

Đây là lần đầu tiên JavaScript có một sự thay đổi rất lớn làm dậy sóng cộng đồng lập trình viên. Một số tính năng mới đó là:

  • Promises
  • Modules
  • Classes
  • Khai báo biến theo scope block (let)
  • Arrow functions
  • Template literal
  • Spread operator
  • De-structuring assignment
  • Parameter default values
  • Rest parameters
  • Symbols
  • Generator functions

ECMAScript 2016 (AKA ES7)

Đây chỉ là một sự thay đổi nhỏ cho ngôn ngữ, ví dụ thêm vào các phép toàn lũy thừa và phương thức <Array.includes>. Đến thời điểm này, việc lập trình theo đặc tả mới đã phổ biến nhưng nhiều trình duyệt vẫn chưa tương thích với đặc tả mới của ngôn ngữ (từ 2015 đã bắt đầu không tương thích), do đó, lập trình viên cần phải dùng các công cụ transpiler để đưa JavaScript về các phiên bản cũ hơn.

ECMAScript 2017 (AKA ES8)

Đưa thêm nhiều tính năng liên quan đến hàm async.

ECMAScript 2018

Mở rộng tính năng liên quan đến regular expressions, đồng thời đưa thêm cú pháp khai triển object. Đặc tả này cũng đưa thêm <Promise.finally> để bổ sung cho promise (code luôn chạy bất kể kết quả của promise là thế nào).

ECMAScript 2019 (AKA ES10)

Đặc tả mới đưa thêm <Array.flat><Array.flatMap>, đồng thời thay đổi cú pháp catch vốn đã nhận được nhiều nhận xét sau khi thêm vào asyncawait từ ES2017.

ECMAScript 2020 (AKA ES11)

Hiện tại bản đặc tả này vẫn ở dạng nháp, tuy nhiên khá chắc là nó sẽ được công bố. Lần này, ngôn ngữ được bổ sung Nullish Coalescing Operator và Optional Chaining Operator giúp code dễ đọc hơn. Promise cũng được mở rộng với allSettled, một lựa chọn thay thế cho <Promise.all>.

JavaScript dùng vào việc gì?

JavaScript với lịch sử là một ngôn ngữ client giúp trang web linh hoạt và dễ tương tác hơn đang ngày càng được phát triển theo nhiều hướng, bao gồm cả việc lập trình cho backend. Ngoài ra, thế giới cho các hệ điều hành di động cũng là một thế giới rất lớn.

JavaScript là ngôn ngữ của front end

JavaScript cùng với sự ra đời của AJAX (Asynchronous JavaScript and XML) năm 1999 (được chuẩn hóa vào năm 2006) đã trở thành một ngôn ngữ front end cực kỳ quan trọng. Trước khi AJAX xuất hiện, phần lớn tác dụng của JavaScript là để đưa các hiệu ứng hình ảnh và tương tác đơn giản cho người dùng. Do những logic này không có tương tác gì với server, ứng dụng của nó là tương đối nhỏ.

Với sự xuất hiện của AJAX, JavaScript bắt đầu được sử dụng như ngôn ngữ chứa logic của ứng dụng web. Ngày nay, thật khó mà tìm được một ứng dụng web nào không dùng đến JavaScript. Càng ngày, hệ sinh thái của JavaScript càng mở rộng và vai trò của nó càng quan trọng hơn nữa.

Các thư viện thao tác với DOM

Những bài toán cơ bản mà lập trình viên thường gặp phải khi làm việc với ứng dụng web đó là:

  • Gọi AJAX
  • Xử lý với DOM (Document Object Model – một cấu trúc dữ liệu được tạo ra bởi trình duyệt để phân tích cấu trúc trang web)
  • Nhận và phản hồi các thao tác của người dùng

JavaScript có sẵn các hàm để làm việc này, tuy nhiên không phải hàm nào cũng chạy được trên tất cả các trình duyệt. Các thư viện dưới đây sẽ giúp lập trình viên viết ứng dụng đơn giản hơn.

Prototype

Đây là một framework được công bố năm 2005 như là bản hộ trợ AJAX của Ruby on Rails. Nó mở rộng nhiều thành phần gốc của JavaScript để hoạt động giống với ngôn ngữ Ruby, đồng thời bổ sung class để lập trình hướng đối tượng, vốn là thứ JavaScript không có sẵn. Tuy nhiên framework này không thực sự thành công khi so sánh với những thư viện dưới đây.

jQuery

Thư viện này được công bố năm 2006 và không giống như Prototype, nó là một thư viện đúng nghĩa. Nó mở rộng ngôn ngữ JavaScript bằng cách bổ sung thêm các hàm để làm việc với DOM, event, và xử lý bất đồng bộ.

Một điểm quan trọng khiến jQuery được ưa thích, đó là nó hỗ trợ các plugin cho phép các lập trình viên mở rộng tính năng của thư viện. Đây là thư viện JavaScript thành công nhất, trở thành một công cụ gần như bắt buộc với front end trong nhiều năm liền. Ngày nay, nó vẫn được rất nhiều website sử dụng.

Mặc dù jQuery đã từng rất phổ biến, nó cung cấp rất nhiều hàm tiện ích cho lập trình viên, nhưng phải lưu ý rằng JavaScript hiện nay đã bổ sung nhiều hàm có tính năng tương tự, và do đó, việc dùng jQuery đã trở nên không bắt buộc. Hiện nay xu hướng là sử dụng JavaScript core hoặc nếu cần thì dùng các thư viện chuyên biệt cho một vấn đề nào đó (ví dụ fetch để gọi AJAX).

Các framework MVC

Khi sử dụng các thư viện làm việc với DOM, một điều tất yếu là dữ liệu cũng được lưu ngay trên DOM, và khi cần truy vấn hay thay đổi các giá trị này, lập trình viên cũng gần gọi đến DOM.

Cách làm này nhanh chóng trở nên lỗi thời với các ứng dụng phức tạp. Và có rất nhiều thư viện ra đời để giúp lập trình viên. Và các thư viện này đều triển khai theo mô hình MVC (Model-View-Controller). Một xu thế mới gần đây đó là trang web sẽ load trước một phần rất nhỏ và sẽ sử dụng AJAX để load tiếp dữ liệu rồi hiển thị thêm.

Những ứng dụng kiểu này thường là dạng SPA (single page application) và code của chúng thường chứa nhiều logic phức tạp. Và để lập trình những ứng dụng này, bắt buộc phải dùng một framework nào đó.

Backbone

Đây là một framework theo mô hình MVP (Model-View-Presenter) được công bố năm 2010. Nó tập trung vào tính năng lập trình ứng dụng SPA và tách biệt phần logic của ứng dụng và phần hiển thị. Các thành phần của ứng dụng tương tác dựa trên các event và nó cũng có router để cho phép ứng dụng thay đổi tùy theo URL.

Angular

Đây là framework của Google và nó tuân theo mô hình MVC (đúng ra nó là MVVC). Tương tự như Backbone, framework này tập trung vào việc tạo các ứng dụng SPA và tách biệt logic của ứng dụng và phần hiển thị.

Một tính năng thú vị của Angular đó là nó cho phép lập trình viên mở rộng HTML bằng cách tạo ra các tag mới sử dụng trong template như một phần của trang web.

Một tính năng độc đáo khác của Angular là nó cho phép 2-way binding dữ liệu giữa template và các đối tượng JavaScript (được sử dụng khi render HTML). Bằng cách làm này, mọi thay đổi của đối tượng sẽ update HTML tương ứng và ngược lại, khi HTML thay đổi thì đối tượng cũng được update giá trị.

Các framework dùng DOM ảo

Phần trước đã trình bày một số framework MVC và chúng đều làm việc với DOM thật. Việc hiển thị HTML của các ứng dụng này tương đối phức tạp khi cần chuyển đổi giữa dữ liệu nhận được từ server thành HTML, đồng thời trang web cũng phải nhận được thao tác của người dùng và phản hồi phù hợp.

Việc sử dụng DOM thật sẽ khiến code trở nên rất phức tạp. Và Facebook, một ông lớn khác trong ngành công nghệ, bắt đầu nghiên cứu một phương thức đơn giản hơn để làm việc đó. Tư tưởng ở đây là những gì được hiển thị sẽ phụ thuộc vào giá trị của một vài object nhất định, chứ không phải là từ rất nhiều tương tác khác nhau trong mô hình MVC truyền thống.

DOM ảo là gì?

DOM ảo thì đương nhiên không phải là DOM thật. Tuy nhiên, trước hết phải hiểu ý tưởng để tạo ra thứ này. Khi một object thay đổi, cái chúng ta cần là thay đổi DOM liên quan đến object đó và giữ nguyên những phần khác chứ không phải là render lại toàn bộ trang web.

Việc render DOM là một thao tác rất phức tạp, trước đây do trình duyệt hoàn toàn xử lý. Tuy nhiên, nhu cầu giờ đây là cần map DOM đó thành một thứ khác dễ thao tác, dể xử lý và quan trọng nhất là có thể xử lý từng phần nhỏ.

Nếu làm được điều đó, mỗi khi chúng ta thay đổi object, trong ta sẽ thay đổi thứ này, so sánh nó xem thay đổi gì và map ngược lại nó với DOM để hiển thị cho người dùng. “Thứ này” chính là DOM ảo.

React

React chính là framework mà Facebook đã tạo ra, là framework khai sinh ra khái niệm DOM ảo và cũng là framework đầu tiên triển khai thứ này. Học hỏi từ mô hình MVC tuy nhiên Facebook không triển khai mô hình này mà chỉ lấy phần view mà thôi. Phần view của React được triển khai dạng cây gần giống DOM gọi là component. Một component có thể có nhiều component con.

Mỗi component lại có state, props nhận khi khởi tạo và cách nó render tương ứng với các state, props của nó. Mỗi khi state thay đổi, một DOM ảo mới sẽ được sinh ra, so sánh với DOM ảo cũ và kết quả cuối cùng là sẽ update DOM thật cho người dùng (chỉ update phần thay đổi).

Những tương tác của người dùng với một component sẽ làm thay đổi state của nó, và nếu cần, component cha cần truyền callback để xử lý những tương tác này. Cách làm này khiến các component bớt phụ thuộc vào nhau và dễ dàng tái sử dụng hơn trong ứng dụng.

Một phát kiến lớn của framework này đó là, thay vì sử dụng các template HTML như trước, phần DOM ảo (vốn là mô phỏng HTML) lại được viết bằng một loại code trông như HTML trộn lẫn với JavaScript được gọi là JSX. Ngôn ngữ template này yêu cầu một công cụ compile để chuyển đổi nó thành JavaScript và HTML.

Flux & Redux

Cách tiếp cận chỉ cần component rất phù hợp với ứng dụng nhỏ. Tuy nhiên, những ứng dụng lớn hơn, như chính Facebook, cần một kiến trúc khác và họ phát triển một kiến trúc gọi là Flux. Trong mô hình này, state của component không được lưu trữ trên component và được lưu trữ độc lập ở một nơi khác (gọi là store).

Dựa trên mô hình của chính Facebook, một vài lập trình viên đã cho ra đời mô hình Redux đơn giản hơn. Redux nhanh chóng được ưa chuộng và được sử dụng rộng rãi cho đến tận bây giờ.

Thay vì trực tiếp update state, mô hình Redux yêu cầu lập trình viên phải sử dụng các reducer. Thay vì trực tiếp update object chứa state, reducer sẽ tạo ra các phiên bản mới thay thế cho phiên bản cũ, điều này có phép Undo/Redo các thao tác, đồng thời việc debug cũng dễ dàng hơn.

Vue

Vue ban đầu cũng tiếp cận theo hướng MVC giống như Angular nhưng tập trung vào sự đơn giản hơn. Tuy nhiên, các phiên bản gần đây đã chuyển hướng sang hướng DOM ảo và component giống như React.

Đây là một framework lũy tiến, có nghĩa là lập trình viên có thể bắt đầu từ phần view của framework và sau đó có thể thêm vào các thành phần phức tạp hơn nếu cần. Cách làm này tiến bộ hơn hẳn các framework khác do nó giảm thiểu các files và thư mục không cần thiết.

GraphQL

Việc sử dụng AJAX trong các ứng dụng hiện đại hơn, phức tạp hơn đang phát sinh một vấn đề: Các lời gọi AJAX có thể lấy thiếu hoặc thừa (thường là thừa) dữ liệu. Ngoài ra, cũng rất khó để cache dữ liệu.

Để giải quyết vấn đề này, Facebook đã phát triển một ngôn ngữ truy vấn, cho phép lập trình viên mô tả chính xác những dữ liệu cần thiết để hiển thị. Ngôn ngữ đó gọi là GraphQL. Những câu truy vấn này sẽ được thông dịch ra thành các câu truy vấn AJAX thông qua GraphSQL client. Vào thời điểm hiện tại, có 2 GraphSQL client:

  • Relay: đây là cài đặt đầu tiên của Facebook được tích hợp với React
  • Apollo: ứng viên đang lên

JavaScript được dùng cho back end

Mặc dù lịch sử là một ngôn ngữ client, nhưng nó đã bắt đầu được sử dụng cho backend khá sớm (từ giữa những năm 90). Thế nhưng, những phiên bản đầu tiên này rất chậm và cho đến trước năm 2008, việc thực thi JavaScript ở server là việc chỉ dành cho siêu nhân. Mọi việc thay đổi sau khi Google công bố V8 JavaScript engine cùng với phiên bản đầu tiên của trình duyệt Chrome.

V8

Khi thiết kế và lập trình lên V8 engine, Google đã sử dụng tính năng tối ưu hóa từ trình dịch của những ngôn ngữ cũ, đó là Self và Strongtalk. Vào thời điểm năm 2008 chắc không còn ai sử dụng những ngôn ngữ này nữa. Kết quả là họ đã tạo ra một trình dịch rất mạnh, tốc độ nhanh cho những ngôn ngữ dạng dynamic typing như JavaScript. Nó mạnh hơn bất cứ một JavaScript engine nào đang có vào thời điểm đó.

Mặt khác, cả trình duyệt Chrome và V8 engine đều được công bố dưới dạng mã nguồn mở (BSD license), điều đó cho phép tất cả mọi người được sử dụng nó, nhúng vào trong phần mềm của họ và phân phối lại một cách tự do.

Node

Không lâu sau khi V8 engine được công bố, một kỹ sư phần mềm người Mỹ tên là Ryan Dahl đã tạo ra một môi trường gọi là Node.js, nơi mà JavaScript có thể được thực thi bằng V8 engine mà không cần đến trình duyệt. Ngoài việc mang V8 engine lên server, Node.js cũng hỗ trợ các event, cho phép lập trình viên viết các dòng lệnh I/O dễ dàng (dưới dạng các xử lý bất đồng bộ).

Điều này cùng với tốc độ tuyệt vời của V8 engine khiến Node.js trở thành một công cụ rất phù hợp cho server để tạo ra các ứng dụng cần xử lý thời gian thự, khi mà yêu cầu xử lý I/O rất cao đồng thời cần một ngôn ngữ dễ đọc, dễ hiểu như JavaScript.

NPM

Bản thân JavaScript không được thiết kế cho server, đặc tả kỹ thuật của nó cũng vậy. Do đó, việc sử dụng JavaScript cho server yêu cầu rất nhiều thư viện bên ngoài. Để sử dụng các thư viện này hiệu quả, một yêu cầu tất yếu là cần một trình quản lý package dành riêng cho Node. Thông qua đó, lập trình viên có thể công bố package của mình, cài đặt package có sẵn và đưa nó vào ứng dụng của mình.

NPM (Node Package Manager) là một trình quản lý package như thế. Nó hoạt động với cơ chế khá giống với CPAN của Perl hay RubyGems.

JavaScript cho full stack

Có nhiều người đã cố gắng đóng gói JavaScript cho mọi thứ để tạo ra một công cụ full stack (tuy không thực sự nổi bật). Trong phần này tôi sẽ trình bày một số công cụ như thế.

Meteor

Đây là một framework lập trình web, sử dụng MongoDB làm database. Nó sử dụng cơ chế pub-sub, tức là client có thể nhận được những thay đổi khi mà dữ liệu được update trên server. Tuy nhiên, nó chưa có phần front end và có thể dùng bất cứ framework nào.

MEAN

Đây là một tổ hợp các công cụ, mà tên của nó là viết tắt của các công cụ đó:

  • MongoDB;
  • Express;
  • Angular;
  • Node.

Ngoài ra, lập trình viên có thể làm việc với bộ công cụ này thông qua lệnh mean.

MERN

Đây là một bộ công cụ khác, tương tự như MEAN nhưng thay Angular bằng React.

JavaScript cho mobile app

Mặc dù JavaScript gắn với thế giới web, nó vẫn được đưa lên công việc phát triển các app di động. Nó là một trong số những công cụ để lập trình dạng cross-platform (cùng một mã nguồn chạy trên nhiều hệ thống).

Apache Cordova

Apache Cordova cho phép phát triển ứng dụng di động bằng JavaScript, HTML và CSS. Nó cũng hỗ trợ cơ chế FFI mechanism, nhờ đó lập trình viên có thể tích hợp một số code native và kết hợp JavaScript với các hàm native đơn giản hơn.

Ionic Framework

Mặc dùng Apache Cordova đã cho phép lập trình ứng dụng bằng JavaScript, nó chưa thực sự cung cấp những tính năng bậc cao. Ionic là một framework đã làm được điều đó. Nó được tích hợp sẵn nhiều thành phần tiện ích: widget, chuyển trang và rất nhiều tiện ích khác nữa. Nó cũng tuân theo mô hình MVC quen thuộc.

React Native

React Native ứng dụng cách tiếp cận component của React lên các ứng dụng di động. Nhưng khác với những framework ở trên (cho phép chạy trực tiếp JavaScript và gọi các hàm native), React Native sẽ được compile thành native code và chạy trên nền tảng di động.

Nativescript

Nativescript là một framework khác mang những tư tưởng của Angular và Vue.js vào việc phát triển ứng dụng di động. Nó cũng cho phép thực thi JavaScript và gọi các hàm native.

Các công cụ để lập trình JavaScript

Module Loaders

Là một ngôn ngữ thực thi trên trình duyệt của người dùng, JavaScript thiếu các cơ chế để xử lý việc load các thư viện cho đúng thứ tự, giải quyết mối tương quan giữa các file. Để giải quyết vấn đề này, có nhiều hướng khác nhau đã được triển khai:

  • Asynchronous Module Definition (AMD)
  • CommonJS Modules
  • ES6 Modules

Trước khi ES6 xuất hiện, Node.js đã triển khai theo hướng CommonJS, tuy nhiên các lập trình viên front end thì yêu thích hình thức AMD hơn. Việc này gây ra sự phân hóa tương đối lớn trong cộng động những người lập trình JavaScript. Để thống nhất, có một phương thức gọi là Universal Module Definition (UMD) đã được đưa ra. Tuy nó giải quyết được vấn đề nhưng code của nó thì xấu không chấp nhận được.

Tuy nhiên, mọi khó khăn đã chấm dứt kể từ ES6, khi mà bản thân ngôn ngữ đã hỗ trợ cơ chế làm việc với các module.

Module Bundlers

Khi sử dụng module trong việc phát triển các ứng dụng web, một công việc thường gặp đó là dịch và gộp tất cả các file thành một file được sử dụng bởi trình duyệt. Những công cụ giúp làm việc đó gọi là module bundler và hiện tại có 2 công cụ phổ biến nhất:

Browserify

Đây là công cụ lâu đời nhất và nó cho phép lập trình viên sử dụng cú pháp của CommonJS để lập trình các ứng dụng web.

Webpack

Đây là công cụ mới hơn, nó không chỉ dịch JavaScript và có thể tích hợp những tài nguyên khác cho một ứng dụng web (ví dụ CSS). Nó cho phép những tài nguyên này có thể reload dễ dàng trên trang web khi mà có những thay đổi rất nhỏ trong source code.

Transpiler và các công cụ tương tự

Những phiên bản mới nhất của JavaScript (chính xác hơn là ECMAScript) thường không tương tích với toàn bộ trình duyệt. Thậm chí phải mất một vài năm các trình duyệt mới cập nhật để tương thích được. Vì vậy, lập trình viên cần phải sử dụng các transpiler để dịch JavaScript từ phiên bản mới thành code của các phiên bản cũ hơn (để có thể chạy được). Dưới đây là một vài công cụ như thế.

Babel

Babel là transpiler được dùng phổ biến nhất, nó có thể chuyển đổi JavaScript code theo những đặc tả mới nhất về các phiên bản cũ hơn để chạy được trên nhiều trình duyệt hơn. Nó rất mạnh mẽ và linh hoạt, cho phép tùy biến để có thể chuyển đổi nhiều phiên bản JavaScript khác nhau.

Web Assembly

Web assembly (tên gọi khác là wasm) là một ngôn ngữ lập trình bậc thấp, hiện đã được hỗ trợ bởi tất cả các trình duyệt. Nó được coi là một sự thay thế cho JavaScript. Tuy nhiên, hiện tại rất ích trình biên dịch có thể dùng để dịch ra ngôn ngữ này, đồng thời nó cũng thiếu cơ chế thu hồi rác (garbage collector).

Vì thiếu cơ thế thu hồi rác, việc dịch ra wasm yêu cầu lập trình viên phải sử dụng một ngôn ngữ mà không cần thu hồi rác (hay nói cách khác là lập trình viên phải code luôn phần đó) hoặc dịch luôn và môi trường thực thi cùng với code của ứng dụng.

TypeScript

Đây là một transpiler, cũng là một ngôn ngữ lập trình được tạo ra bởi Microsoft. Nó được coi là superset của JavaScript và TypeScript sẽ được dịch ra JavaScript để thực thi. Tôi sẽ có một bài chi tiết hơn về ngôn ngữ này.

Flow

Đây là một công cụ được phát triển bởi Facebook, để hỗ trợ lập trình viên JavaScript theo dạng static type tương tự như TypeScript. Tuy nhiên, Flow chỉ tập trình dạng kiểu dữ liệu của các biến mà không thêm các tính năng nào khác cho ngôn ngữ.

Elm

Elm mà một framework và một ngôn ngữ lập trình hàm (functional programming) lấy cảm ứng từ ngôn ngữ Haskell và sẽ được dịch ra JavaScript để thực thi trên trình duyệt. Ngôn ngữ này cũng tuân theo kiến trúc tương tự như Redux.

Không giống các ngôn ngữ khác, Elm đảm bảo 100% kiểu dữ liệu sẽ được hỗ trợ thông qua việc tự nhận diện kiểu dữ liệu của biến. Điều này giúp lập trình viên không cần thiết phải khai báo toàn bộ kiểu dữ liệu. Đồng thời, ngôn ngữ này được đánh giá là an toàn do nó không cho phép exception xảy ra.

ReasonML

Đây là công cụ Facebook sử dụng, nó là ngôn ngữ lập trình hàm và được dịch ra JavaScript. ReasonML có cú pháp của O’Caml và kiểu ngoặc nhọn quen thuộc của JavaScript. Có thể coi đây là phiên bản anh em của Elm (nhưng không quá chặt về lập trình hàm).

Task Runners

Code JavaScript ngày càng phức tạp hơn, và nhu cầu về việc tổ chức code JavaScript cũng khó hơn ngày trước rất nhiều. Có người thì cần sắp xếp các module để chạy cho đúng, người muốn chạy eslint trước để kiểm tra code, người thì cần dùng transpiler, người thì cần thêm obfuscate code, v.v…

Và để làm những việc đó, các lập trình viên cần những công cụ để có thể tự động hóa mọi việc (như make, ant hoặc rake) . Những công cụ như vậy gọi là task runner, và hiện tại có 2 công cụ được dùng phổ biến nhất (đều được viết bằng JavaScript).

  • Grunt: công cụ lâu đời nhất, trong đó tất cả công việc sẽ được thực hiện từng bước, kết quả sẽ được ghi ra các file tạm và sử dụng ở bước sau.
  • Gulp: công cụ mới hơn (nhưng cũng khá lâu đời), tương tự như grunt nhưng dùng dữ liệu trực tiếp trong bộ nhớ thay vì ghi ra file, do đó có tốc độ tốt hơn.

Các công cụ chạy bằng JavaScript

Express

Như đã nói ở phần trước, JavaScript vốn là ngôn ngữ sinh ra cho trình duyệt web, nhưng vẫn có người tìm cách đưa nó lên server. Và Express là một framework cho phép lập trình JavaScript trên server. Đây là một framework theo đuổi sự đơn giản (giống như Sinatra), mặc dù vậy, cộng đồng lập trình viên đã viết rất nhiều thư viện để tăng thêm tính năng cho nó.

MongoDB

V8 engine được dùng để tạo ra Node, nó cũng được dùng làm trình thông dịch cho MongoDB (một cơ sở dữ liệu NoSQL dạng document). Khi tương tác với cơ sở dữ liệu này, dữ liệu sẽ được quản lý dưới dạng JSON và các câu truy vấn sẽ gọi các hàm JavaScript. Điều này giúp đây là một hệ cơ sở dữ liệu rất phổ biến trong cộng đồng lập trình viên JavaScript.

Yeoman

Đây là một trình khởi tạo project được viết bằng JavaScript. Nó cho phép khởi tạo rất nhiều project JavaScript khác nhau, với cấu hình khác nhau (nhờ tương tác với người dùng). Ngoài JavaScript, nó cũng được sử dụng để khởi tạo các dự án Java.

Tương lai của JavaScript?

Thế giới của JavaScript quả thực rất rộng lớn, dù lịch sử của nó đã trải qua nhiều biến động mà khởi đầu chỉ có 10 ngày làm việc. Từ một ngôn ngữ client side để thêm vào các hiệu ứng cho đẹp mắt, giờ đây JavaScript đã là ngôn ngữ lập trình phổ biến nhất thế giới.

Sự biến động của JavaScript cũng phản ánh phần nào sự phát triển của thế giới phần mềm. Nhiều công cụ được tạo ra ban đầu chỉ là một phần mở rộng nhỏ, một bản vá tạm nhưng sau đó đã được nhân rộng và phát triển mạnh mẽ hơn nhiều.

Công nghệ ngày nay yêu cầu các ứng dụng web tốc độ hơn, an toàn hơn và dễ dùng hơn. Điều này khiến JavaScript cũng đang chịu áp lực cạnh tranh từ các ngôn ngữ khác. Nhiều người đã nghĩ đến việc thay thế JavaScript bởi một ngôn ngữ mềm dẻo hơn.

Web Assembly là một dự án như thế. Nếu nó thành công (tất nhiên là nó có thể thất bại), đó là thể là khởi đầu của một kỷ nguyên mới. Khi đó, thật khó để tưởng tượng được JavaScript sẽ như thế nào. Có thể nó vẫn được tiếp tục sử dụng, hoặc nó sẽ dần chìm vào quên lãng.

Tôi xin lỗi nếu bài viết có bất kỳ typo nào. Nếu bạn nhận thấy điều gì bất thường, xin hãy cho tôi biết.

Nếu có bất điều gì muốn nói, bạn có thể liên hệ với tôi qua các mạng xã hội, tạo discussion hoặc report issue trên Github.