- vừa được xem lúc

Thay đổi cấu hình ứng dụng web (Angular/ Reactjs) bằng biến môi trường mà không cần rebuild

0 0 17

Người đăng: Sunteco Tech Team

Theo Viblo Asia

Mở đầu

Quá trình triển khai phổ biến hiện nay của các Single Page Application (SPA) là Code => Build => Package => Deploy.

Trong đó Build phase sẽ biên dịch code từ frame work thành code HTML, CSS, JS mà trình duyệt có thể hiểu được. Package phase đóng gói code đã được biên dịch vào một Web server image (Nginx, Apache) và sau đó Deploy phase sẽ triển khai Image lên các Container Engine Platform (Docker, K8S, Aws ECS, Sun Spinner...).

Trong phase Build, build command với tham số biến môi trường, các file config chứa biến môi trường tương ứng sẽ được biên dịch cùng với source code. Cách làm truyền thống này đáp ứng được hầu hết các yêu cầu trong quá trình phát triển nhưng vẫn tồn tại một số hạn chế:

  • Tiêu tốn thời gian build không cần thiết: Do mỗi môi trường yêu cầu một phase build khác nhau mặc dù Source code sau khi biên dịch không có gì khác nhau ngoài các biến môi trường. Trên thực tế các dự án mình đã trải qua, quá trình build production của ứng dụng Angular mất khoảng 15 phút, thời gian build của reactjs thậm chí còn lên tới 30 phút hoặc hơn nữa. Thời gian build có thể thay đổi phụ thuộc khối lượng source code và cách optimize, nhưng rõ ràng những con số trên đáng để cân nhắc một giải pháp tối ưu hơn cho thời gian triển khai CICD.
  • Không đủ linh hoạt cho các bài toán Cloud solution, dynamic config: Các bài toán về ứng dụng cloud, multi-tenant sẽ không khả thi nếu source code sau khi build chỉ có thể làm việc với một bộ configuration duy nhất
  • Vấn đề bảo mật: Do dữ liệu cấu hình là một phần của source code, Mỗi thành viên đều có thể truy cập config của tất cả các môi trường, dẫn đến rủi ro về bảo mật và vận hành.

Các ứng dụng backend cũng gặp vấn đề này nhưng được giải quyết đơn giản bằng native environment của phía server, các biến môi trường có thể được inject qua phase Package nên một source code có thể làm việc với nhiều cấu hình khác nhau.

Cách giải quyết

Vậy giải pháp sẽ là phải làm sao để một bộ source code sau khi build có thể được inject các biến môi trường khác nhau tương tự như cách ứng dụng backend hoạt động. Sau đây là cách giải quyết vấn đề, nguyên lý chung này có thể áp dụng cho các web framework và ngôn ngữ khác nhau.

  1. Chuẩn bị giải pháp cho phép ứng dụng đọc cấu hình từ một nguồn độc lập với source code (File, API)
  2. Chỉnh sửa code của ứng dụng để thay thế các biến môi trường từ nguồn trên
  3. Đảm bảo cấu hình được load xong trước tiên, làm nguồn cho các render chức năng, giao diện về sau

Thực hành với Angular

Mặc định các file config tồn tại trong thư mục src/environments/ với format environment.<env name>.ts và chỉ dẫn build được đặt trong file angular.json. Với lệnh ng build --configuration=production Angular CLI sẽ thay thế file environment.ts bằng file environmen.prod.ts theo chỉ dẫn fileReplacement

Và các file logic code sẽ import và sử dụng biến môi trường từ file environment.ts. Ta sẽ bỏ qua các cài đặt mặc định của Angular để thực hiện giải pháp theo các nguyên lý đã nêu ở trên.

  1. Tạo một file cấu hình JSON có các key giống với file environment.ts trong src folder. Ví dụ env.json

  1. Cấu hình location của file env.json vào phần assets trong angular.json để webpack giữ nguyên file này như một file assets

  1. Tạo một service để đọc cấu hình từ file env.json, lưu ý vị trí tương đối của Service này với file env.json

  1. Đảm bảo dữ liệu config được load đầu tiên khi khởi động ứng dụng

  1. Kết quả

Vậy là ứng dụng đã đọc được nội dung từ một file hoặc từ một API độc lập. Nhưng từ từ đã, đến đây đã đạt được dự định ban đầu chưa, ta chưa thấy cách inject được giá trị configuration khác. Trên thực tế, sau khi tách file cấu hình ra khỏi phase Build là đã có thể giải quyết được vấn đề. Sau đây là một vài cách để thực hiện việc inject giá trị config.

  1. Inject value vào file env.json trong phase Package của quá trình CICD (thay thế giá trị của file này)
  2. Sử dụng API để lấy cấu hình từ phía backend không cần ghi đè file: Sử dụng API với các param đặc trưng cho phía client như IP, location, hostname... để làm parameter cho việc lấy cấu hình. Ví dụ một api với param /env?hostname=localhost:4200 sẽ trả về env với apiEndpoint là localhost:3000, hostname có thể lấy qua biến window.location của trình duyệt.
  3. Khi triển khai ứng dụng bằng các Container Engine Platform: các Engine này có hỗ trợ tính năng mount volume, lúc này trong phase Deploy, ta chỉ cần cấu hình mount các file chứa biến môi trường tương ứng từ hệ thống quản lý biến môi trường của Container Engine thay thế vào vị trí file env.json bên trong container chứa source code.

Đọc thêm:

Hướng dẫn cấu hình ConfigMap K8S

Hướng dẫn mount ConfigMap với Sun Spinner

Kết

Với các thay đổi theo hướng dẫn ở trên, có thể triển khai ứng dụng web với các biến môi trường khác nhau gần như ngay lập tức, các sửa đổi biến môi trường cũng được apply gần như real time.

Tham khảo các giải pháp cho hệ thống của bạn tại Sunteco Cloud

Trải nghiệm miễn phí hệ sinh thái Sunteco Cloud

Bình luận

Bài viết tương tự

- vừa được xem lúc

Cùng tìm hiểu về các hook trong React hooks

Đối với ai đã từng làm việc với React thì chắc hẳn đã có những lúc cảm thấy bối rối không biết nên dùng stateless (functional) component hay là stateful component. Nếu có dùng stateful component thì cũng sẽ phải loay hoay với đống LifeCycle 1 cách khổ sở Rất may là những nhà phát triển React đã kịp

0 0 87

- vừa được xem lúc

Khi nào nên (và không nên) sử dụng Redux

. Công việc quản lý state với những hệ thống lớn và phức tạp là một điều khá khó khăn cho đến khi Redux xuất hiện. Lấy cảm hứng từ design pattern Flux, Redux được thiết kế để quản lý state trong các project JavaScript.

0 0 118

- vừa được xem lúc

ReactJS: Props và State

Nếu bạn đã học ReactJS hay React Native, bạn sẽ thấy các Props và State được sử dụng rất nhiều. Vậy chính xác chúng là gì? Làm thế nào để chúng ta sử dụng chúng đúng mục đích đây.

0 0 47

- vừa được xem lúc

State và Props trong Reactjs

Hello các bạn, tiếp tục seri tìm hiểu về ReactJs hôm nay mình xin giới thiệu đến các bạn hai thứ mình cho là thú vị nhất của ReactJs là State và Props. State bạn có thể hiểu đơn giản là một nơi mà bạn lưu trữ dữ liệu của Component, từ đó bạn có thể luân chuyển dữ liệu đến các thành phần trong Compon

0 0 41

- vừa được xem lúc

Memoization trong React

. 1.Introduction. Memoization có liên quan mật thiết đến bộ nhớ đệm, và dưới đây là một ví dụ đơn giản:. const cache = {}.

0 0 43

- vừa được xem lúc

Nâng cao hiệu suất React Hooks với React.memo, Memoization và Callback Functions

1.Ngăn Re-render và React.memo. React.

0 0 71