Tương lai là TypeScript

Cách đây 2 năm, tôi có đăng một bài viết về TypeScript. Lúc đó, tôi thực sự cũng không chắc lắm về tương lai của nó. Là công nghệ sinh sau đẻ muộn, TypeScript sẽ rất khó bắt kịp các đàn anh đi trước. Nhưng 2 năm sau, tôi đã có suy nghĩ khác, và giờ đây tôi có thể tự tin khẳng định rằng: tương lai chính là TypeScript.

Sau khi nghe xong câu chuyện JavaScript được cha đẻ Brendan Eich tạo ra chỉ trong 10 ngày, ai cũng phải há hốc mồm vì ngạc nhiên. Họ ngạc nhiên vì tốc độ ra đời của JavaScript cũng gần tương đương với thời gian Thượng đế tạo ra vũ trụ (7 ngày). Tuy vậy, người đời cũng không khỏi lo sợ, hoang mang vì hoài nghi về chất lượng của cái JavaScript “sinh đẻ thần tốc”. Do số phận đưa đẩy, JavaScript giờ trở thành ngôn ngữ lập trình phổ biến nhất thế giới. Đây là một bất ngờ lớn, vì nếu ở thời điểm 15 năm trước, ai đó nói JavaScript sẽ thống trị thế giới thì sẽ được đưa vào nhà thương điên ngay lập tức (Java mới là kẻ thống trị lúc đó).

JavaScript không được thiết kế để viết ứng dụng doanh nghiệp lớn. Nếu ứng dụng chỉ vỏn vẹn vài chục dòng code, JavaScript không gây khó khăn gì. Nhưng khi số dòng code lên đến hàng ngàn, rắc rối bắt đầu nảy sinh. Kiểm tra lỗi trở nên khó khăn, sửa chữa code cũng không phải dễ. Nhiều khái niệm của JavaScript gây khá nhiều hiểu lầm (điển hình là từ khóa this và khái niệm functional scope), nhiều cơ chế của nó gây khó hiểu cho người mới bắt đầu (điển hình là closurehoisting) và nhiều điểm cú pháp của nó gây khó khăn khi sử dụng. Bên cạnh đó, cơ chế kế thừa theo prototype (prototypal inheritance) khiến ngay cả lập trình viên C# nhiều kinh nghiệm cũng phải chau mày, trợn mắt khi lần đầu tiên nhìn thấy chúng. Người ta bắt đầu ngao ngán JavaScript, họ muốn tìm một cách khác để viết code dễ hơn.

Trong những năm qua, cộng đồng lập trình viên đã đưa ra khá nhiều giải pháp nhằm hoàn thiện JavaScript với hi vọng biến nó thành một ngôn ngữ lập trình thực thụ. Nổi bật nhất là TypeScript, một ngôn ngữ mới được Microsoft phát triển trong nhiều năm (không phải 10 ngày) nhằm khắc phục các khuyết điểm lớn của JavaScript. Sau nhiều năm xông pha chiến trường, TypeScript đã thực hiện thành công sứ mệnh cứu rỗi JavaScript. Ngay cả ông lớn Google cũng tuyên bố dùng TypeScript để phát triển AngularJS 2.0. Điều này gây khá nhiều bất ngờ vì Google có một ngôn ngữ tên Dart cũng thực hiện chức năng tương tự TypeScript, với lại xưa nay Google và Microsoft vốn không ưa nhau lắm.

Để thực sự cảm nhận sức mạnh của TypeScript, ta phải tự tay dùng nó. Hãy xem qua một đoạn TypeScript sau:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class Girl {
    constructor(public name: string, public age: number) {}
    display(): void {
        console.log("My name is " + this.name + " and I'm " + this.age + " years old.");
    }
}

class HotGirl extends Girl {
    constructor(name: string, age: number, public isLongLeg: boolean) {
        super(name, age);
    }
    display(): void {
        super.display();
        console.log("My legs are " + (this.isLongLeg ? "long" : "not long") + ".");
    }
}

Đoạn TypeScript này khá đơn giản. Tôi chỉ tạo một lớp Girl và cung cấp vài thuộc tính cơ bản. Sau đó, tôi tạo thêm lớp HotGirl để kế thừa những đặc điểm của Girl.

Bây giờ, ta xem code JavaScript được tạo ra từ TypeScript:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
var __extends = (this && this.__extends) || function (d, b) {
    for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
    function __() { this.constructor = d; }
    d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};

var Girl = (function () {
    function Girl(name, age) {
        this.name = name;
        this.age = age;
    }
    Girl.prototype.display = function () {
        console.log("My name is " + this.name + " and I'm " + this.age + " years old.");
    };
    return Girl;
})();

var HotGirl = (function (_super) {
    __extends(HotGirl, _super);
    function HotGirl(name, age, isLongLeg) {
        _super.call(this, name, age);
        this.isLongLeg = isLongLeg;
    }
    HotGirl.prototype.display = function () {
        _super.prototype.display.call(this);
        console.log("My legs are " + (this.isLongLeg ? "long" : "not long") + ".");
    };
    return HotGirl;
})(Girl);

Hầu hết lập trình viên sau khi nhìn thấy 4 dòng đầu tiên là đã cảm thấy chóng mặt, buồn nôn. Đây đúng là cơn ác mộng. Hãy tưởng tượng ta phải gõ bằng tay những dòng JavaScript này để sử dụng các tính năng cơ bản của lập trình hướng đối tượng. Vì JavaScript có cơ chế hoạt động khác thường, nên nó đòi hỏi ta phải dùng những design pattern đặc biệt để cấu trúc, sắp xếp code sao cho dễ quản lý và bảo trì. TypeScript đã lo phần này, nên ta không phải bận tâm. Giờ đây, ta có thể dồn tâm trí vào viết code để giải quyết bài toán thay vì tập trung vào vấn đề tổ chức, sắp xếp code. Điều này giải phóng lập trình viên khỏi những gánh nặng không cần thiết, từ đó nâng cao hiệu suất viết code.

Vì TypeScript có phong cách na ná những ngôn ngữ lập trình hướng đối tượng truyền thống như C# hay Java, lập trình viên của những ngôn ngữ này có thể chuyển qua dùng TypeScript rất nhanh chóng và dễ dàng. Trong trường hợp công ty thiếu người, ta có thể chuyển một vài lập trình viên C# hoặc Java sang dự án web và dùng TypeScript thay vì dùng trực tiếp JavaScript như trước kia. Những lập trình viên này sẽ không cảm thấy bỡ ngỡ, lạc lỏng trong một môi trường lạ như JavaScript, thay vào đó là một cảm giác quen thuộc như đang làm việc với chính ngôn ngữ của họ.

Cách đây 5 năm, Scott Hanselman (lập trình viên khét tiếng của Microsoft) có một bài viết gây xôn xao về JavaScript. Trong đó, ông tuyên bố JavaScript chính là ngôn ngữ assembly của web. Bài viết nhận được nhiều ý kiến trái chiều. Thậm chí vài năm sau, vấn đề JavaScript có phải là assembly cho web vẫn còn tranh cãi quyết liệt. Theo quan điểm của tôi, Scott đã quá đúng trong vấn đề này. Dù muốn hay không, JavaScript đã và đang trở thành assembly của web.

Hãy nhìn lại quy trình phát triển một ứng dụng web. Vào thời kỳ đầu, lập trình viên phải tự tay viết từng dòng HTML, CSS và JavaScript để tạo ra những trang web tĩnh. Tại thời điểm đó, chỉ cần 3 công nghệ này là quá đủ để làm web. Theo thời gian, xã hội phát triển, web cũng phát triển theo. Giờ đây, nó không chỉ là vài ba trang HTML được liên kết với nhau, nó đã trở thành một ứng dụng ngang ngửa với ứng dụng desktop. Công nghệ làm web từ đó mà trở nên phức tạp hơn. Lập trình viên web giờ đây phải thành thạo nhiều công nghệ cùng lúc, từ client cho tới server.

Những công nghệ xuất hiện trong thời kì đầu như JavaScript, mặc dù có nhiều cải tiến qua thời gian nhưng vẫn không thể bắt kịp tiến độ phát triển của web. Những điểm yếu của JavaScript giờ đã ăn sâu vào cộng đồng, để khắc phục chúng đòi hỏi phải thay đổi tận gốc rễ. Đây là một nhiệm vụ bất khả thi vì nếu thiết kế lại JavaScript hoàn toàn mới thì sẽ có hơn 90% trang web ngừng hoạt động. Khi một công nghệ đã quá phổ biến, thay đổi nhỏ nhất có thể gây ảnh hưởng rất lớn. Kết cục, ta phải sống chung với những khuyết điểm của JavaScript.

Với TypeScript, ta không phải bận tâm đến những khuyết điểm này. Mã TypeScript sẽ được biên dịch sang JavaScript và người lập trình không phải lo lắng về chất lượng JavaScript được sinh ra. Ta cũng thấy xu hướng này trong các ngôn ngữ khác của web như HTML và CSS. Các library và framework lớn đều không dùng HTML, CSS hay JavaScript để viết. Thay vào đó, lập trình viên dùng một ngôn ngữ khác như Jade, Sass, Less hoặc TypeScript để biên dịch ra HTML, CSS và JavaScript.

Không còn nghi ngờ gì nữa, JavaScript sớm muộn gì cũng sẽ trở thành một assembly của web. Ngày càng có nhiều ngôn ngữ được biên dịch sang JavaScript, và nổi bật nhất chính là TypeScript. Nếu là một lập trình viên web, tôi khuyên bạn nên bắt đầu nghiên cứu nó ngay. Ngoài ra, bạn cũng nên học quy trình phát triển web mới, sử dụng các công cụ tự động như Grunt, Bower, Yeoman để tăng tốc quá trình viết code. Sở hữu những kỹ năng tiên tiến này sẽ giúp bạn trở nên hấp dẫn hơn trong mắt nhà tuyển dụng, đồng thời túi tiền của bạn cũng phồng to hơn.