Web Design

Sử dụng Electron để viết ứng dụng xuyên nền tảng

Thực tế đã là dev thì ai cũng muốn viết ứng dụng xuyên nền tảng, tức là một project nhưng build và chạy được trên nhiều nền tảng. Dù lí do phụ là gì, nhưng bao giờ cũng gồm một hoặc cả hai lí do chính, là để chứng tỏ kĩ năng, kĩ thuật và kinh nghiệm của bản thân và quan trọng hơn hết là tiết kiệm thời gian và công sức cũng như dễ sửa chữa, bảo trì. Chẳng hạn, bạn muốn ứng dụng của mình hỗ trợ cả ba hệ điều hành là Windows, macOS và (họ) Linux hoặc chí ít cũng là hai tên đầu tiên, thì bạn có xu hướng muốn viết ứng dụng xuyên nền tảng hơn là dùng Winform để viết cho Windows, AppKit cho macOS và GTK cho Linux. Hiện tại, đối với máy tính thì chúng ta có một cái tên “gạo cội”, tiếng tăm lẫy lừng trong giới lập trình là Qt với khả năng tương thích với rất nhiều nền tảng đích. Song, Qt lại được dựa trên C/C++ và sau này có Qml, tạo nên một số trở ngại nhất định đối với xu hướng hiện tại. Do vậy, một nền tảng mới ra đời, phù hợp hơn, và “dễ làm ăn” hơn là Electron của GitHub.

Electron

1. Electron là gì và nguyên tắc viết ứng dụng dựa trên Electron

Electron is an open source library developed by GitHub for building cross-platform desktop applications with HTML, CSS, and JavaScript. Electron accomplishes this by combining Chromium and Node.js into a single runtime and apps can be packaged for Mac, Windows, and Linux.

Nói theo hướng dễ hiểu nhất, Electron là nền tảng xây dựng ứng dụng Native cho nền tảng máy tính (và vừa hỗ trợ Android) bằng công nghệ Web với HTML, CSS và JavaScript. Như vậy, nếu bạn “cứng” về làm web (chứ không phải “wed” đâu xin thưa mấy chế) thì bạn hoàn toàn có thể làm một ứng dụng Native trên máy tính (và giờ có thêm Android) mà không cần thiết phải học qua C/C++ hay Java, cũng như các kiến thức về dựng window. Nói chung, chỉ cần có kiến thức tương đối về Web là đủ rồi.

2. Công nghệ phía sau Electron

Electron được hậu thuẫn bởi NodeJS, và nếu bạn chưa hiểu NodeJS hoạt động như nào thì xin mời bạn tìm hiểu sơ qua nó trước, cũng như bao gồm luôn các thư viện của Chromium project. Chính vì vậy mà các code HTML, CSS và JS của bạn có khả năng chạy và tương thích với APIs cơ bản của hệ thống đích, chí ít là một số thư viện về SQLite, trên nhiều nền tảng khác nhau. Do vậy, nếu bạn đang muốn viết một ứng dụng Native cho desktop mà không sử dụng nhiều APIs sâu của hệ thống thì Electron là một lựa chọn vô cùng hợp lí.

3. Một số ứng dụng được xây dựng bằng Electron

Electron khởi thủy là nền tảng (framework) để xây dựng Atom – một bộ Text Editor rất nổi tiếng của GitHub và là cái tôi sử dụng nhiều nhất – và sau này được GitHub chia sẻ ra cho cả cộng đồng lập trình sử dụng và phát triển. Ngay cả đối thủ – và sắp tới về chung một nhà – với Atom là Visual Studio Code cũng được dựng bằng Electron. Ngoài ra chúng ta cũng có những cái tên nổi tiếng khác như GitHub desktop (đương nhiên, hàng chính chủ mà), Simple Note và WordPress của Automattic, Slack (#) và một công cụ thiết kế khá nổi tiếng là Figma.

4. Một số ưu điểm và hạn chế của Electron

Hạn chế lớn nhất của Electron là việc nó ít hỗ trợ các APIs sâu hệ thống, vì nó chạy dưới nền NodeJS và Chromium. Vì vậy, nếu bạn muốn viết ứng dụng có sử dụng các APIs đặc trưng của hệ thống mà NodeJS chưa chính thức hỗ trợ, hoặc không có module trợ giúp nào từ cộng đồng NodeJS/NpmJS thì sẽ gặp không ít khó khăn. Nhưng nếu bạn chỉ muốn viết ứng dụng cho desktop ở mức tương đồng như ứng dụng mobile bằng React Native thì Electron tỏ ra vượt trội hơn Qt hay JavaFx. Bản thân tôi cũng thích Electron hơn hai tên kia, và khi viết ứng dụng Backup Viewer, tôi lựa chọn Electron dù cũng có đủ khả năng viết bằng Qt và JavaFx.

Hạn chế thứ hai là việc Electron cần hậu thuẫn của Chromium vì việc render window dựa vào tên này, cũng có lí thôi vì bản thân Chromium là đa nền tảng và NodeJS dựa vào bộ engine của Chromium mà! Vì vậy, dung lượng của một ứng dụng “Hello world” của Electron thôi cũng đã “ngót nghét” trên 50MB do bản đóng gói thêm các Chromium libs. Cũng do vậy mà khi ứng dụng chạy sẽ tiêu tốn RAM hơn so với ứng dụng “Hello world” làm bởi Qt hay JavaFx và có thể “ỳ ạch” trên các máy tính có cấu hình thấp.

Nhưng bù lại, bởi Electron app được dựng bằng HTML và CSS nên bạn tha hồ “style” nó theo bất kì cách nào bạn muốn. Chẳng hạn, Backup Viewer được thiết kế theo phong cách rất “Material Design”. Và vì nó chỉ được dựng bằng HTML, CSS và JS cũng như tính xuyên nền tảng của Chromium mà việc build project ra ứng dụng là hoàn toàn như nhau trên Windows, macOS và Linux, nghĩa là bạn không cần phải tối ưu hóa code cho bất kì nền tảng nào – trừ khi bạn muốn tương tác sâu với hệ thống.

Một điểm cộng nữa là bạn có khả năng build app cho Linux trên macOS, cũng như build cho macOS dưới dạng zip (dmg chỉ khả dụng trên Mac) trên Linux. Còn với Windows thì rất tiếc, nó chỉ chơi với mỗi nó mà thôi. Do đó, nếu bạn đang sở hữu cả Linux và Windows thì bạn có thể build cho tất cả các nền tảng. Khá hay đúng không?

5. Cài đặt Electron

Việc phát triển ứng dụng Electron được thực hiện trong môi trường NodeJS, và vì vậy, bạn phải có NodeJS trước. Nếu bạn chưa có NodeJS, hãy tham khảo cách cài đặt ở bài viết này của tôi. Để cài đặt Electron, bạn chỉ cần tiến hành qua NPM:

Hoặc nếu bạn chỉ muốn cài đặt cho mỗi project của bạn, hãy thay flag -g bằng –save hay –save-dev. Sau khi đã cài đặt xong, bạn tiến hành init từ NPM:

Tất nhiên, bạn sẽ trải qua thao tác thiết lập tập tin package.json. Sau khi thiết lập xong, để tạo project electron, bạn chỉ đơn giản là dùng câu lệnh bên dưới. Đó cũng là câu lệnh mà mỗi lần cho chạy project, bạn sẽ dùng:

Yêu cầu là bạn phải add node_modules của NodeJS (tức global modules) vào $PATH. Nếu không, bạn cần tự trỏ tới đúng tập tin thực thi electron. Tập tin gần gũi nhất là nằm trong /node_modules/.bin của thư mục project của bạn.

Bạn cũng có thể add câu trên vào npm run-script. Sau lần chạy đầu, project của bạn có dạng:

Trong đó, index.html là tập tin HTML chứa giao diện của ứng dụng, còn main.js là tập tin của Electron sử dụng để render giao diện chứ không phải là tập tin script để chạy trong index.html đâu bạn à. Để bắt đầu viết CSS và JS script thì bạn chỉ đơn giản là tạo chúng và liên kết trong HTML như làm Web bình thường. Để bắt đầu chạy ứng dụng, bạn chỉ cần dùng lệnh electron bên trên mà thôi. Nhưng sẽ có một bất tiện là khi thay đổi code, bạn phải chạy đi chạy lại câu lệnh trên. Để đơn giản hóa, khi save thì ứng dụng sẽ chạy lại, bạn chỉ cần cài đặt electron-rebuild từ NPM và require nó ngay dưới phần require các modules khác là được.

6. Đóng gói ứng dụng Electron

Thực tế Electron đã có sẵn các công cụ build tích hợp, nhưng việc build bằng chính Electron không dễ dàng cũng như yêu cầu khá nhiều dependencies như VS trên Windows, Xcode trên macOS và các bộ “thần thánh” build-essential trên Debian hay dbus-devel trên RedHat và quan trọng nhất, không thể thiếu là Python2 (không phải 3). Vì vậy, tôi sẽ giới thiệu cho các bạn sử dụng electron-builder là cái tôi sử dụng.

Đầu tiên, bạn cần có Python2 và cài đặt Electron-Builder qua NPM, -g hay –save-dev gì cũng được:

Trước khi build ra ứng dụng, cũng như nếu bạn có sử dụng các native modules (chẳng hạn sqlite), bạn cần build các modules trước bằng câu lệnh bên dưới, lưu ý nếu Electron-Builder không được cài đặt theo “-g” thì bạn cần trỏ tới tập tin thực thi của nó trong /node_modules/.bin

Trước khi build, bạn cần điều chỉnh tập tin package.json tương tự như sau:

Trong đó, appId có dạng tương tự như packageName của android, ví dụ com.example.myelectronapp. Nếu bạn có dự định build cho macOS, bạn phải có phần mac với category của macOS. Category gì cũng được.

Để build cho từng nền tảng, bạn sẽ sử dụng cách build sau:

Trong đó:

  • -p là platform mà bạn muốn build, các options gồm -m hay -mac cho macOS, -l hay -linux cho Linux và -w hay -win.
  • tpf là target-platform-format, tức là kiểu file bạn muốn build ra, phụ thuộc nền tảng -p. Dưới đây tôi liệt kê một số tham số chính bạn cần biết.
  1. Đối với -m hay -mac: mac, mas (cho Mac App Store), dmg và zip (dạng zip, build cho macOS được trên Linux).
  2. Đối với -w hay -win: nsis, msi, zip.
  3. Đối với -l hay -linux: AppImage, deb, rpm, tar.xz, zip và apk cho Android.

Ví dụ, tôi muốn build cho macOS dưới dạng zip, Linux dưới dạng AppImage, và Windows dưới dạng msi, tôi làm như sau:

Lưu ý: Bạn chỉ có thể build mas và dmg trên macOS, nếu bạn muốn build cho macOS trên Linux, bạn chỉ có thể build dạng zip mà thôi. Đối với Windows, bạn nên build trên Windows và trên Windows không hỗ trợ build cho macOS và Linux, hoặc có nhưng không ổn định và dễ bị gãy giữa chừng. Trên macOS bạn có thể build cho cả macOS và Linux dưới bất kì dạng nào.

Về Icon của ứng dụng: Trên Windows là .ico, trên macOS là .icns và trên Linux là .png. Bạn đặt chúng trong thư mục build, thư mục này nằm ngang hàng với package.json và node_modules. Nếu bạn build cho Linux trên macOS, bạn có thể bỏ qua tập tin .png.

Trên đây chỉ là những gợi ý để các bạn có thể sử dụng Electron-Builder ngay. Để tìm hiểu thêm về các options khác của nó, hãy tham khảo tại trang chính của nó. Với những kiến thức này, tôi hi vọng bạn đã có thể dựng một ứng dụng Electron xuyên nền tảng. Chúc các bạn vui vẻ code và thành công.

1 thought on “Sử dụng Electron để viết ứng dụng xuyên nền tảng”

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.