Thứ năm, 10/01/2019 | 00:00 GMT+7

Kết xuất phía server với Angular Universal


Ứng dụng một trang (SPA) được đặt tên phù hợp - thực sự chỉ có một trang HTML duy nhất được cung cấp ban đầu cho khách hàng. Mọi chế độ xem mới được yêu cầu trong ứng dụng chỉ được tạo trên client thông qua JavaScript. Chu kỳ yêu cầu-phản hồi vẫn xảy ra, nhưng điều này thường chỉ xảy ra với các API RESTful cho dữ liệu; hoặc để lấy tài nguyên tĩnh, như hình ảnh.

Có rất nhiều lợi ích khi viết ứng dụng theo cách này. Tuy nhiên, bạn sẽ mất một số thứ, chẳng hạn như khả năng trình thu thập thông tin web duyệt qua ứng dụng của bạn và hiệu suất chậm hơn trong khi ứng dụng đang tải, điều này có thể mất một lượng thời gian đáng kể. Đi kèm với Hiển thị phía server (SSR) để thu hẹp khoảng cách.

SSR với Angular Universal

Ứng dụng Angular là một Ứng dụng một trang - nó chạy trong trình duyệt của khách hàng. Angular Universal, tuy nhiên, bạn cũng có thể chạy ứng dụng Angular của bạn trên server . Điều này cho phép bạn phân phát HTML tĩnh cho client . Với Angular Universal, server sẽ hiển thị trước các trang và hiển thị cho user của bạn nội dung nào đó , trong khi ứng dụng phía client tải ở chế độ nền. Sau đó, khi mọi thứ đã sẵn sàng ở phía client , nó sẽ chuyển đổi liền mạch từ hiển thị các trang do server hiển thị sang ứng dụng phía client . User của bạn sẽ không nhận thấy sự khác biệt, ngoài thực tế là thay vì đợi vòng quay “Đang tải” của bạn kết thúc, ít nhất họ có thể có một số nội dung để thu hút họ cho đến khi họ có thể bắt đầu sử dụng ứng dụng phía client đầy đủ tính năng.

SSR với Angular Universal yêu cầu các thay đổi trong cả ứng dụng client và ngăn xếp server để hoạt động. Đối với bài viết này, ta sẽ giả định đây là một ứng dụng Angular hoàn toàn mới, hầu như không được tạo bằng Angular CLI, tại phiên bản> = 7 . Bất kỳ công nghệ server nào cũng có thể chạy ứng dụng Universal, nhưng nó phải có khả năng gọi một hàm đặc biệt, renderModuleFactory() , được cung cấp bởi Angular Universal, bản thân nó là một gói Node; vì vậy việc cung cấp ứng dụng Angular này từ một server Node / Express có ý nghĩa đối với ví dụ này.

Thêm Universal vào ứng dụng của bạn

Ta sẽ sử dụng một giản đồ để đưa ta lên và đi nhanh chóng. Từ folder ứng dụng của bạn, mở một terminal và chạy lệnh sau:

$ ng add @nguniversal/express-engine --clientProject {{ name of your project }}

Bạn sẽ nhận thấy giản đồ này đã thực hiện một số thay đổi đối với ứng dụng của bạn, sửa đổi một số file và thêm một số file . Tôi sẽ lướt qua những thứ này không theo thứ tự cụ thể.

  1. angular.json : projects.{{project-name}}.architect.build.options.outputPath thay đổi thành “dist / browser”; và một projects.{{project-name}}.architect mới projects.{{project-name}}.architect được thêm vào, được gọi là “ server ”. Điều này cho phép Angular CLI biết về server / version Universal của ứng dụng Angular.
  2. package.json : ngoài việc thêm một số phụ thuộc mới (dự kiến), ta cũng nhận được một số tập lệnh mới: “compile: server”, “server: ssr”, “build: ssr”, “build: client-and-server -bó".
  3. server.ts : đây là server NodeJS Express. Rõ ràng, bạn không phải sử dụng cài đặt server chính xác này khi được tạo, mặc dù hãy lưu ý đến dòng app.engine('html', ngExpressEngine({...' . ngExpressEngine là một shell bọc xung quanh renderModuleFactory là loại nước sốt đặc biệt làm cho Universal hoạt động. Nếu bạn không sử dụng file server.ts chính xác này cho cài đặt của bạn , ít nhất hãy sao chép phần này ra và tích hợp vào file của bạn.
  4. webpack.server.config.js : cấu hình webpack để đóng gói server Express / Universal. , nếu bạn đang tích hợp Universal trong một ứng dụng hiện có, bạn có thể đang làm điều gì đó khác biệt. Tuy nhiên, vì ta đã thêm module Universal của bạn vào server , có toàn bộ biểu đồ phụ thuộc của Angular, điều này tạo nên một gói gọn gàng mọi thứ cần thiết cho bản dựng production . Cấu hình được sử dụng cùng với tập lệnh package.json mới “compile: server”.
  5. main.ts : điều này đã được sửa đổi để version trình duyệt của ứng dụng sẽ không bắt đầu khởi động cho đến khi các trang được hiển thị bởi Universal được tải đầy đủ.
  6. main.server.ts : file mới này về cơ bản chỉ xuất ra AppServerModule , là điểm nhập của version Universal của ứng dụng. Ta sẽ sớm thấy điều này.
  7. tsconfig.server.json : điều này cho trình biên dịch Angular biết nơi tìm module mục nhập cho ứng dụng Universal.
  8. app.module.ts : sửa đổi để thực thi phương thức tĩnh .withServerTransition trên BrowserModule nhập. Điều này cho version trình duyệt của ứng dụng biết rằng client sẽ chuyển đổi từ version server vào một thời điểm nào đó.
  9. app.server.module.ts : đây là module root chỉ dành cho version server . Bạn có thể thấy nó nhập AppModule của ta , cũng như ServerModule từ @angular/platform-server angle @angular/platform-server và khởi động cùng một AppComponent như AppModule. AppServerModule là điểm vào của ứng dụng Universal.

Khởi động ứng dụng global của bạn

Từ một dòng lệnh, hãy chạy lệnh sau:

$ npm run build:ssr && npm run serve:ssr

Giả sử bạn không gặp phải bất kỳ lỗi nào trong quá trình xây dựng, hãy mở trình duyệt của bạn tới http: // localhost: 4000 (hoặc bất kỳ cổng nào được cấu hình cho bạn) và bạn sẽ thấy ứng dụng Universal của bạn đang hoạt động! Nó sẽ không có gì khác biệt, nhưng trang đầu tiên sẽ tải nhanh hơn nhiều so với ứng dụng Angular thông thường của bạn. Nếu ứng dụng của bạn nhỏ và đơn giản, điều này có thể khó nhận thấy. Bạn có thể thử điều chỉnh tốc độ mạng bằng cách mở Công cụ dành cho nhà phát triển của Chrome và trong tab Mạng, tìm menu thả xuống có nội dung “Trực tuyến”. Chọn “3G chậm” để bắt chước thiết bị trên mạng chậm - bạn vẫn sẽ thấy hiệu suất tốt cho trang đích của bạn và bất kỳ trang được định tuyến nào mà bạn truy cập.

Ngoài ra, hãy thử xem nguồn trang (nhấp chuột phải vào trang và chọn “Xem nguồn trang”). Bạn sẽ thấy tất cả HTML bình thường trong <body> trùng với những gì được hiển thị trên trang web - nghĩa là, ứng dụng của bạn có thể bị trình thu thập thông tin web loại bỏ một cách có ý nghĩa. So sánh điều này với nguồn trang của một ứng dụng không phải Universal, và tất cả những gì bạn sẽ thấy trong <body><app-root> (hoặc bất cứ thứ gì bạn đã gọi là bộ chọn cho AppComponent khởi động của bạn ).

Những điều cần lưu ý

Vì một ứng dụng Universal chạy trên server chứ không phải trong trình duyệt, nên có một số điều bạn cần chú ý trong mã ứng dụng của bạn :

  • Kiểm tra việc bạn sử dụng các đối tượng dành riêng cho trình duyệt, chẳng hạn như window , document hoặc location . Chúng không tồn tại trên server . Dù sao thì bạn cũng không nên sử dụng chúng; thử sử dụng phần trừu tượng góc có thể tiêm vào, chẳng hạn như Document hoặc Location . Phương án cuối cùng, nếu bạn thực sự cần chúng, hãy gói cách sử dụng của chúng trong một câu lệnh có điều kiện, để chúng chỉ được sử dụng bởi Angular trên trình duyệt. Bạn có thể thực hiện việc này bằng lệnh các hàm isPlatformBrowserisPlatformServer từ @angular/common isPlatformServer @angular/common , đưa mã thông báo PLATFORM_ID vào thành phần của bạn và chạy các hàm đã nhập để xem bạn đang ở trên server hay trình duyệt.
  • Nếu bạn sử dụng ElementRef để xử lý một phần tử HTML, không sử dụng nativeElement để thao tác các thuộc tính trên phần tử. Thay vào đó, hãy tiêm Renderer2sử dụng một trong các phương pháp ở đó .
  • Xử lý sự kiện trình duyệt sẽ không hoạt động. Ứng dụng của bạn sẽ không phản hồi các sự kiện nhấp chuột hoặc các sự kiện trình duyệt khác khi chạy trên server . Tuy nhiên, bất kỳ liên kết nào được tạo từ routerLink sẽ hoạt động để chuyển .
  • Tránh sử dụng setTimeout , nếu có thể.
  • Đặt tất cả các URL cho các yêu cầu server là tuyệt đối. Yêu cầu dữ liệu từ các URL tương đối sẽ không thành công khi chạy từ server , ngay cả khi server có thể xử lý các URL tương đối.
  • Tương tự, bảo mật xung quanh các yêu cầu HTTP được cấp từ server không giống như các yêu cầu được cấp từ trình duyệt. Yêu cầu server có thể có các yêu cầu và tính năng bảo mật khác nhau. Bạn sẽ phải tự mình xử lý bảo mật đối với những yêu cầu này.

Đọc thêm


Tags:

Các tin liên quan

Cách cài đặt và cấu hình pgAdmin 4 ở Chế độ server
2018-10-19
Cách cài đặt Linux, Apache, MySQL, PHP (LAMP) trên Debian 8
2018-10-18
Cách cài đặt Linux, Nginx, MySQL, PHP ( LEMP) trên Debian 9
2018-09-13
Cách cài đặt, chạy và kết nối với Jupyter Notebook trên server từ xa
2018-09-12
Cách cài đặt và cấu hình Postfix làm server SMTP chỉ gửi trên Debian 9
2018-09-07
Cách cấu hình BIND làm server DNS Mạng Riêng trên Debian 9
2018-09-06
Thiết lập server ban đầu với Debian 9
2018-09-04
Cách cài đặt Linux, Apache, MariaDB, PHP (LAMP) trên Debian 9
2018-09-04
Cách phát triển ứng dụng Node.js TCP Server bằng PM2 và Nginx trên Ubuntu 16.04
2018-07-23
Cách thiết lập server VPN IKEv2 với StrongSwan trên Ubuntu 18.04
2018-07-16