Bàn về câu lệnh npm run build - tại sao cần phải build?

Bàn về câu lệnh npm run build - tại sao cần phải build?

Tin ngắn hàng ngày dành cho bạn
  • Từ lâu rồi suy nghĩ làm thế nào để tăng sự hiện diện thương hiệu, cũng như người dùng cho blog. Nghĩ đi nghĩ lại thì chỉ có cách chia sẻ lên mạng xã hội hoặc trông chờ họ tìm kiếm, cho đến khi...

    In cái áo này được cái tắc đường khỏi phải lăn tăn, càng đông càng vui vì hàng trăm con mắt nhìn thấy cơ mà 🤓

    (Có tác dụng thật nha 🤭)

    » Xem thêm
  • Một vòng của sự phát triển nhiều dự án khá là thú vị. Tóm tắt lại trong 3 bước: Thấy một cái gì đó phức tạp -> Làm cho nó đơn giản đi -> Thêm thắt tính năng cho đến khi nó phức tạp... -> Quay trở lại vòng lặp mới.

    Tại sao lại như vậy? Để mình lấy 2 ví dụ cho các bạn thấy.

    Markdown ra đời với mục tiêu tạo ra một định dạng văn bản thô "dễ viết, dễ đọc, dễ dàng chuyển thành một dạng gì đó như HTML". Vì thời đó chẳng ai đủ kiên nhẫn mà vừa ngồi viết vừa thêm định dạng cho văn bản hiển thị ở trên web như thế nào. Ấy vậy mà giờ đây người ta đang "nhồi nhét" hoặc tạo ra các biến thể dựa trên markdown để bổ sung thêm nhiều định dạng mới đến mức... chẳng nhớ nổi hết cú pháp.

    React cũng là một ví dụ. Từ thời PHP, việc khát khao tạo ra một cái gì đó tách biệt hẳn giao diện người dùng và phần xử lý logic chính của ứng dụng thành 2 phần riêng biệt cho dễ đọc, dễ viết. Kết quả là các thư viện UI/UX phát triển rất mạnh mẽ, mang lại khả năng tương tác với người dùng rất tốt, còn phần logic ứng dụng thì nằm ở một máy chủ riêng biệt. Bộ đôi Front-end, Back-end cũng từ đấy mà thịnh hành, không thể thiếu anh bồi bàn REST API. Ấy vậy mà giờ đây React trông cũng không khác biệt gì so với PHP là mấy, kéo theo là cả Vue, Svelte... lại cùng quy tất cả về một mối.

    Cơ mà không phải vòng lặp là xấu, ngược lại vòng lặp này mang tính tiến hoá nhiều hơn là "cải lùi". Nhiều khi lại tạo ra được cái hay hơi cái cũ thế là người ta lại dựa trên cái hay đó để tiếp tục lặp. Nói cách khác là chắc lọc tinh hoa từng tí một tí một á 😁

    » Xem thêm
  • Song song với các dự án chính thức thì thi thoảng mình vẫn thấy các dự án "bên lề" nhằm tối ưu hoặc cải tiến ngôn ngữ theo khía cạnh nào đó. Ví dụ nature-lang/nature là một dự án hướng tới cải tiến Go, mang lại một số thay đổi nhằm giúp cho việc sử dụng Go trở nên thân thiện hơn.

    Nhìn lại mới thấy hao hao JavaScript 😆

    » Xem thêm

Vấn đề

npm run build một câu lệnh không quá xa lạ với các lập trình viên JavaScript khi chuẩn bị phát hành phiên bản mới cho ứng dụng. Theo cách hiểu đơn giản, npm run build thực hiện công việc chuyển đổi mã trong dự án thành mã có thể chạy được trong trình duyệt hoặc Node.js.

Nhưng tại sao lại cần phải có bước build? Bản chất của việc build là gì? Có phải tất cả dự án JavaScript/Node.js cần phải build hay không? Hy vọng bạn đọc sẽ tìm được câu trả lời trong bài viết dưới đây.

NPM Scripts

package.json là một tệp quan trọng có trong hầu hết dự án JavaScript/Node.js. Chức năng của nó là lưu trữ thông tin dự án cũng như cấu hình và các lệnh sẽ được sử dụng. Lấy ví dụ, package.json lưu lại tất cả các thư viện để mỗi khi cần cài đặt các gói phụ thuộc (dependencies) chỉ cần chạy npm install.

scripts là một thuộc tính trong package.json, nó lưu giữ các giá trị trông giống như dưới đây:

{
  "scripts": {
    "dev": "vite",
    "tsc": "vue-tsc --noEmit",
    "build": "npm run tsc && vite build",
    "build-dev": "vue-tsc --noEmit && vite build --mode development",
    "serve": "vite preview"
  }
}

Khi đó nếu chúng ta gõ npm run build thì ở bên dưới câu lệnh thực sự được chạy đó chính là vue-tsc --noEmit && vite build. Nói cách khác build chỉ là tên đại diện cho câu lệnh thực sự muốn chạy. Nếu bây giờ tôi không thích build, đổi tên nó thành release cũng không thành vấn đề. Nếu muốn chạy, chỉ cần gõ npm run release. npm run release lúc này cũng giống như npm run build trước đó.

scripts sinh ra để che giấu đi sự phức tạp trong việc nhớ các câu lệnh sẽ được sử dụng trong dự án. Ở ví dụ trên, việc ghi nhớ npm run build so với vue-tsc --noEmit && vite build theo bạn thì cái nào dễ hơn? Trong một dự án không chỉ sử dụng một lệnh duy nhất mà con số có khi lên đến cả hàng chục. Chúng còn có khả năng móc nối đến nhau, nghĩa là lệnh này bằng nhiều lệnh khác cộng lại. Đấy là lúc scripts phát huy tác dụng là một nơi hoàn hảo để lưu trữ lại các giá trị.

Hãy nhìn vào dòng lệnh build trên, nó là sự kết hợp của tscvite build. Tạo ra nhiều lệnh ở cấp độ phân tử giúp bạn có thể tái sử dụng. Việc đặt tên cho chúng mang lại ý nghĩa gợi nhớ. Hãy hình dung khi mở package.json ở bất kỳ dự án nào ra mà thấy có build trong scripts thì chắc hẳn đó chính là lệnh có liên quan đến việc sắp sửa phát hành một phiên bản mới cho ứng dụng.

Sự phức tạp của giới Trình duyệt/Node.js

Sự phức tạp của giới trình duyệt/Node.js

Bản thân JavaScript mang nhiều sự phức tạp, nhiều khi bạn không thể hiểu nổi tại sao typeof null == 'object' và vô số những điều vô lý đến thuyết phục khi làm việc với nó. Để giải thích thì có nhiều lý do, một trong số đó là sự phân mảnh của JavaScript. Nếu như với các ngôn ngữ khác, muốn sử dụng chỉ cần tải bản cài đặt về rồi cài vào máy là xong. Sau khi viết mã, muốn triển khai ứng dụng lên máy chủ thì chỉ cần sử dụng đúng phiên bản đã cài đặt trước đó là gần như chắc chắn thành công.

JavaScript thì ngược lại, cho phép chạy mã JavaScript hay không là quyền thuộc về trình duyệt. Mà trình duyệt thì có rất nhiều loại và không phải cái nào cũng tuân thủ theo quy tắc của JavaScript. Nếu như JavaScript phát hành một phiên bản mới thì trình duyệt ngay sau đó phải tung bản cập nhật để hỗ trợ. Điều gì xảy ra nếu người dùng không chịu cập nhật trình duyệt, hoặc trình duyệt không mặn mà với việc chạy đua theo các tính năng mới nhất của JavaScript? Nói cách khác, một đoạn mã JavaScript chạy được trên trình duyệt này chưa chắc đã chạy trên trình duyệt khác. Điều đó khiến cho lập trình viên JavaScript phải vò đầu bứt tai khi giải quyết bài toán "Hỗ trợ tối đa người dùng Internet".

Node.js hạn chế được sự phân mảnh hơn, vì nó chỉ sử dụng V8 của Chrome. Sử dụng Node.js đồng nghĩa với việc bạn phải dùng V8. Mặt khác, Node.js chạy phía máy chủ nên không phải giải quyết bài toán khó như trình duyệt.

Nhìn lại thực tế, không phải người dùng nào cũng có phiên bản trình duyệt mới nhất. Không phải tất cả đều sử dụng Chrome hay Firefox... Lập trình viên luôn e ngại rằng liệu mã sắp viết ra đây có tương thích với tất cả người dùng? Ý tưởng của các công cụ hỗ trợ viết một lần - dùng cho tất cả xuất hiện từ đây.

Có thể bạn đã nghe nói đến babel.js, đây là thư viện chuyển đổi mã JavaScript mới hơn về mã mà hầu hết các trình duyệt có thể chạy được. Hiểu đơn giản nếu bạn muốn dùng các cú pháp JavaScript mới nhất mà vẫn có thể chạy được trên các trình duyệt cũ thì babel.js giúp làm điều đó. Tất cả điều cần làm là cài đặt babel, viết mã rồi sử dụng nó để chuyển đổi mã bạn vừa viết. Đó là lúc lệnh build xuất hiện. Trong build có thể là câu lệnh có sử dụng babel như ví dụ dưới đây.

{
  "scripts": {
    "build": "babel src -d lib"
  }
}

Với sự ra đời của nhiều Framework hỗ trợ xây dựng ứng dụng dựa trên phản ứng như Angular, React, Vue... càng làm xuất hiện thêm nhiều công cụ chuyển đổi mã hơn nữa. Về cơ bản, các Framework che giấu sự phức tạp khi phát triển và cho đến lúc phát hành bằng những công cụ như webpack, rollup, vite... Điều đó giúp cho nhà phát triển ứng dụng tập trung vào công đoạn viết mã nhiều hơn so với việc đi trả lời câu hỏi liệu ứng dụng của tôi có chạy tốt trên IE8?

Có phải tất cả ứng dụng cần phải build?

Câu trả lời là không. Như tôi đã nói build chỉ là một tên đại diện cho câu lệnh phức tạp. Nó còn mang ý nghĩa gợi nhớ. build thường xuất hiện trong dự án có sử dụng các công cụ hỗ trợ chuyển đổi mã đơn giản thành phức tạp ví dụ như babel, hay các công cụ đóng gói như webpack, rollup...

Nếu phát triển một ứng dụng JavaScript đơn giản mà không sử dụng các công cụ trên rõ ràng bạn không cần phải qua một bước build. Trình duyệt hay Node.js có thể chạy được những đoạn mã mà bạn viết.

Tổng kết

package.json là một tệp chứa các thông số và cấu hình cho dự án JavaScript/Node.js. scripts là một thuộc tính chứa các câu lệnh được chạy tương ứng mỗi khi sử dụng npm run. scripts giúp che giấu đi sự phức tạp của câu lệnh và mang ý nghĩa gợi nhớ, build bao hàm những yếu tố đó.

Vì vậy, các dự án mà có sử dụng đến công cụ hỗ trợ chuyển đổi mã như babel, webpack... thì mới cần đến build. Ngược lại, nếu phát triển dự án đơn giản thì không nhất thiết phải có bước build nữa.

Cao cấp
Hello

Bí mật ngăn xếp của Blog

Là một lập trình viên, bạn có tò mò về bí mật công nghệ hay những khoản nợ kỹ thuật về trang blog này? Tất cả bí mật sẽ được bật mí ngay bài viết dưới đây. Còn chờ đợi gì nữa, hãy bấm vào ngay!

Là một lập trình viên, bạn có tò mò về bí mật công nghệ hay những khoản nợ kỹ thuật về trang blog này? Tất cả bí mật sẽ được bật mí ngay bài viết dưới đây. Còn chờ đợi gì nữa, hãy bấm vào ngay!

Xem tất cả

Đăng ký nhận thông báo bài viết mới

hoặc
* Bản tin tổng hợp được gửi mỗi 1-2 tuần, huỷ bất cứ lúc nào.

Bình luận (0)

Nội dung bình luận...