Site icon Nhạc lý căn bản – nhacly.com

Lập trình desktop app với Electron | Blog | manhhomienbienthuy

Lâu lắm mới lại lập trình 🤣 Thật tình cờ là vừa trở lại lập trình thì gặp ngay công nghệ tiên tiến mới. Nói thế thôi chứ thực ra là cũ người mới ta. Electron ( trước kia gọi là Atom Shell ) đã Open từ rất lâu rồi, và những ứng dụng sử dụng công nghệ tiên tiến này cũng được sử dụng thoáng rộng ( ví dụ như tôi vẫn hằng ngày sử dụng Visual Studio Code và Microsoft Teams ) .

Bối cảnh

Dòng đời xô đẩy thế nào tôi lại được giao một dự án Bất Động Sản Proof of Concept ( PoC ). Và nhu yếu là cần giao một loại sản phẩm mẫu mà người mua hoàn toàn có thể thuận tiện thực thi và kiểm tra hoạt động giải trí. Trong trường hợp này không gì tốt hơn một ứng dụng chạy ngay trên máy tính, không nhu yếu setup hay thông số kỹ thuật gì nhiều .Ý tưởng bắt đầu là sẽ viết ứng dụng bằng Java, sau đó đóng gói, người mua chỉ cần cài JRE là hoàn toàn có thể chạy được. Tuy nhiên, tôi không có kinh nghiệm tay nghề gì về Java ngoại trừ chút kiến thức và kỹ năng học từ thời sinh viên. Vừa học vừa làm thì cũng được thôi nhưng dự án Bất Động Sản PoC thì không có nhiều thời hạn thế. Với kinh nghiệm tay nghề làm web nhiều năm thì lúc này Electron là một lựa chọn tốt. Với lựa chọn này thì bắt buộc phải biết NodeJS .

Tuy kinh nghiệm với JavaScript của tôi chỉ toàn là phía client, chưa bao giờ làm lập trình NodeJS, tuy nhiên nó cũng là JavaScript cả. Hơn nữa, ứng dụng không có yêu cầu cao về hiệu suất, nó chỉ cần chạy đúng logic là được. Suy đi tính lại thì Electron là lựa chọn hợp lý nhất.

Nói qua một chút ít về Electron, thì những ứng dụng viết bằng Electron không khác một trình duyệt web là mấy. Khi bật ứng dụng lên cũng có nghĩa là mở trình duyệt lên ( Electron có sẵn Chromium ở trong, tuy nhiên JavaScript engine của nó hơi khác một chút ít ) và tải một trang HTML. Việc của lập trình viên là sử dụng HTML, CSS, JS để tạo giao diện cho ứng dụng. Khi người dùng click những nút, thì lúc này có 2 giải pháp giải quyết và xử lý :

  1. Xử lý như một trang web bình thường, tức là sẽ submit form, gọi Ajax hay tương tự để gửi lên server, nhận kết quả và hiển thị cho người dùng. Với cách làm này, thì các framework như React hay VueJS sẽ là lựa chọn tuyệt vời cho phía client để có một ứng dụng thật “ngầu”. Về phía server, có thể sử dụng NodeJS hay bất cứ một ngôn ngữ lập trình nào khác, để lập trình web, quá trình truyền nhận dữ liệu tất cả thông qua API. Nhiều trang web được thiết kế sẵn theo hướng này có thể build app desktop rất nhanh, chỉ cần bỏ HTML, CSS, JS vào Electron build là xong, thế là vừa có web, vừa có app luôn.
  2. Ứng dụng Electron có 2 tiến trình, tiến trình chính (main) và renderer. Renderer là tiến trình mà bật Chromium và hiển thị HTML cho người dùng. Tuy là bật trình duyệt web và hiển thị, tuy nhiên tiến trình này có thể tiến hành một số xử lý trực tiếp bằng code NodeJS luôn (ví dụ có thể sử dụng fs để làm việc với files) chứ không bị giới hạn trong môi trường trình duyệt. Một vài xử lý yêu cầu phải chạy ở tiến trình main (ví dụ bật dialog), thì từ renderer có thể invoke một event để tiến trình chính thực hiện, kết quả sẽ được trả về cho renderer để hiển thị.

Với nhu yếu một ứng dụng đơn thuần, ít cần thiết lập hay thông số kỹ thuật thì tôi quyết định hành động sẽ viết ứng dụng theo hướng thứ 2 .

Lập trình ứng dụng đơn giản

Trong nội dung bài viết này, tôi sẽ trình diễn cách lập trình một ứng dụng đơn thuần. Ý tưởng là nhập vào một thư mục và rename tổng thể file trong thư mục đó thành 1 tên ngẫu nhiên có độ dài cố định và thắt chặt ( cũng tuỳ theo input ) .

Cài đặt và cấu hình

Trước hết, Electron chạy trên NodeJS nên yêu cầu máy tính phải cài sẵn NodeJS và npm. Với những người lập trình web thì những công cụ này không còn gì xa lạ nữa, nên trong bài viết này tôi không đi sâu vào chi tiết việc cài đặt này.

Sau khi đã có NodeJS thì việc tiếp theo là khởi tạo một project mới bằng lệnh và nhập những thông tin thiết yếu

USDnpm init

Câu lệnh sẽ khởi tạo 1 project NodeJS mới với file package.json chứa các thông tin mà chúng ta đã nhập vào. Bước tiếp theo là cài đặt electron để sử dụng

USDnpm install -D electron

Có thể nhiều người thắc mắc tại sao lại có -D trong câu lệnh trên. Nguyên nhân là bởi vì mục đích cuối cùng của project không phải là 1 package NodeJS. Mục đích cuối cùng là 1 ứng dụng chạy trên desktop, nên electron chỉ là devDependencies chứ không phải dependencies. Ngoài ra thì việc này có liên quan đến việc build app ở dưới.

Như đã nói ở trên, một ứng dụng Electron thực ra là mở một trình duyệt rồi tải trang HTML, do đó tôi cần thiết lập thêm những công cụ để build CSS, JS, v.v… Với ví dụ này tôi sử dụng TailwindCSS nên cần setup thêm những package sau :

USDnpm install -D postcss postcss-cli autoprefixer tailwindcss

Việc thông số kỹ thuật những công cụ này cũng không khó, tôi trọn vẹn làm theo hướng dẫn là được .

Viết ứng dụng

Về cơ bản ứng dụng sẽ gồm có 1 file HTML ( đặt tên tuỳ ý ), những file CSS, JS đi kèm với file HTML đó và 1 file NodeJS để để khởi động Electron bật ứng dụng. Cấu trúc thư mục của ứng dụng sẽ tựa như như dưới đây :

├── static
|   ├── src
|   |   ├── app.css // sẽ  build bằng tailwindcss thành /static/app.css
|   ├── app.js
├── index.html
├── main.js
└── package.json

Nội dung của file index.html như sau (màn hình có 2 trường input và 1 button)

html

    
    Simple app with Electron<p class="p">title>
    
    

    </p><div class="
flex flex-col
justify-center
items-center
gap-4
w-screen
h-screen
">
        <div class=" flex flex-row gap-4 justify-center items-center ">
            <label class=" text-right font-lg w-32 " for=" thư mục ">
                Select input
            <p class="p">label>
            </p><div class=" flex flex-row items-center w-96 ">
                <input class="
outline-none
flex-grow
border
border-gray-300
rounded-l
h-12
p-4
" name=" thư mục " id=" thư mục " disabled>
                <button class="
outline-none
bg-gray-200
hover : bg-gray-400
border-t
border-r
border-b
border-gray-300
h-12
px-4
- ml-1
rounded-r
" id=" folder-btn ">
                    <svg xmlns=" http://www.w3.org/2000/svg " class=" h-6 w-6 inline-block " fill=" none " viewbox=" 0 0 24 24 " stroke=" currentColor ">
                        <path stroke-linecap=" round " stroke-linejoin=" round " stroke-width=" 2 " d=" M5 19 a2 2 0 01-2-2 V7a2 2 0 012 - 2 h4l2 2 h4a2 2 0 012 2 v1M5 19 h14a2 2 0 002 - 2 v - 5 a2 2 0 00-2-2 H9a2 2 0 00-2 2 v5a2 2 0 01-2 2 z ">
                    <p class="p">svg>
                    Choose folder
                </p><p class="p">button>
            </p><p class="p">div>
        </p><p class="p">div>
        </p><div class=" flex flex-row gap-4 justify-center items-center ">
            <label class=" text-right font-lg w-32 " for=" length ">
                Filename length
            <p class="p">label>
            <input class="
border border-gray-200
focus : border-blue-500
outline-none
w-96
rounded-l
h-12
rounded
p-4
" value=" 16 " name=" length " id=" length ">
        </p><p class="p">div>

        </p><div class=" ml-36 w-96 text-left ">
            <button class="
outline-none
bg-blue-500
hover : bg-blue-700
px-8
py-2
text-white
uppercase
" id=" action-btn ">
                <svg xmlns=" http://www.w3.org/2000/svg " class=" h-6 w-6 inline-block " fill=" none " viewbox=" 0 0 24 24 " stroke=" currentColor ">
                    <path stroke-linecap=" round " stroke-linejoin=" round " stroke-width=" 2 " d=" M15 15 l - 2 5L9 9 l11 4-5 2 zm0 0 l5 5M7. 188 2.239 l. 777 2.897 M5. 136 7.965 l - 2.898 -. 777M13. 95 4.05 l - 2.122 2.122 m - 5.657 5.656 l - 2.12 2.122 ">
                <p class="p">svg>
                Run
            </p><p class="p">button>
        </p><p class="p">div>

        
	

</p></path></svg></button></div></label></div></path></svg></button></div></label></div></div>