Trình khởi động bootstrap trong Angular

Trình khởi động bootstrap trong Angular

Trong hướng dẫn này, chúng ta sẽ tìm hiểu về trình khởi động bootstrap và cách Angular hoạt động bên trong và khởi động ứng dụng của chúng ta.

Chúng ta sử dụng lệnh ng new để tạo một dự án Angular mới. Angular CLI sẽ tạo ra một ứng dụng đơn giản, cấu hình Typecript, Webpack, Karma và Protractor cho chúng ta.

Ứng dụng này khi chạy sẽ hiển thị một trang HTML đơn giản với một số liên kết hữu ích tới Angular.

Bây giờ chúng ta sẽ mổ xẻ ứng dụng này và xem điều gì sẽ xảy ra từ khi ứng dụng khởi động cho đến khi nó hiển thị trang HTML

Hướng dẫn này áp dụng cho Angular 2 đến phiên bản mới nhất của tức là Angular 8, Angular 9, Angular 10, Angular 11 và Angular 12.

Bootstrap là gì

Bootstrap là một kỹ thuật khởi tạo hoặc tải ứng dụng Angular.

Chúng ta hãy xem qua mã được tạo trong bài viết Tạo dự án Angular mới và xem điều gì xảy ra ở mỗi giai đoạn và cách component AppComponent được tải và hiển thị “app works!”. Angular thực hiện các bước sau để tải view đầu tiên của chúng tôi.

  1. File index.html.
  2. Tải ứng dụng và thư viện Angular, thư viện bên thứ ba.
  3. File main.ts là điểm vào ứng dụng.
  4. Module gốc.
  5. Component gốc.
  6. Template.

File index.html được tải đầu tiên

Ứng dụng web cần một điểm khởi đầu. Tệp Index.html thường là trang đầu tiên để tải. Hãy để chúng tôi mở tệp và xem nó chứa những gì. Bạn sẽ tìm thấy nó trong thư mục src.

<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <title>GettingStarted</title>
  <base href="/">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <link rel="icon" type="image/x-icon" href="favicon.ico">
</head>
<body>
  <app-root></app-root>
</body>
</html>

Không có tệp javascript nào trong index.html. Bạn cũng không thể thấy tệp CSS nào. Nội dung của tệp có thẻ HTML sau.

<app-root></app-root>

Angular tải như thế nào? Để tìm hiểu, hãy để chúng tôi build ứng dụng.

Build ứng dụng

Để chạy ứng dụng, chúng ta sử dụng lệnh Angular CLI ng serve hoặc lệnh NPM npm start (thực tế thì lệnh npm start sẽ chuyển thành ng serve.)

Lệnh ng serve sẽ biên dịch ứng dụng của chúng ta nhưng không lưu ứng dụng đã biên dịch vào ổ đĩa. Nó lưu nó vào bộ nhớ và khởi động máy chủ phát triển.

Chúng ta sử dụng lệnh ng build để biên dịch ứng dụng. Lệnh này sẽ biên dịch và sao chép các tệp đầu ra vào thư mục dist.

ng build

Sử dụng lệnh ng build --prod để biên dịch và phân phối ứng dụng cho môi trường sản xuất. Để kiểm tra/gỡ lỗi ứng dụng hãy sử dụng lệnh ng build. Bản build cho môi trường sản xuất sẽ được tối ưu hóa tốt hơn.

Bây giờ hãy vào thư mục dist và mở tệp index.html.

<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <title>GettingStarted</title>
  <base href="/">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <link rel="icon" type="image/x-icon" href="favicon.ico">
</head>
<body>
  <app-root></app-root>
 
  <script src="runtime-es2015.js" type="module"></script>
  <script src="runtime-es5.js" nomodule defer></script>
  <script src="polyfills-es5.js" nomodule defer></script>
  <script src="polyfills-es2015.js" type="module"></script>
  <script src="styles-es2015.js" type="module"></script>
  <script src="styles-es5.js" nomodule defer></script>
  <script src="vendor-es2015.js" type="module"></script>
  <script src="vendor-es5.js" nomodule defer></script>
  <script src="main-es2015.js" type="module"></script>
  <script src="main-es5.js" nomodule defer></script></body>
</html>

Bạn có thể thấy rằng trình biên dịch đã thêm 5 tệp javascript. Đó là runtime, polyfills, styles, vendormain. Tất cả các tệp này có hai phiên bản một là es5 và một là es2015.

Kể từ Angular 7, chúng ta có tính năng mới được gọi là tải polyfill có điều kiện. Bây giờ Angular biên dịch hai tệp javascript, một tệp cho es2015 và một tệp khác cho es5. Es2015 (es6) dành cho trình duyệt hiện đại và es5 là các trình duyệt cũ hơn, không hỗ trợ các tính năng mới của es2015.

Lưu ý: thuộc tính nomodule yêu cầu trình duyệt hiện đại bỏ qua và không tải file javascript. Do đó, các file es5 không được tải trong các trình duyệt hiện đại.

  • runtime.js: – Webpack runtime.
  • polyfills.js – Các tập lệnh polyfill để hỗ trợ nhiều trình duyệt hiện đại mới nhất.
  • styles.js – Tệp này chứa các quy tắc kiểu CSS chung được đóng gói dưới dạng tệp javascript.
  • vendor.js – chứa các tập lệnh từ thư viện lõi Angular và bất kỳ thư viện bên thứ 3 nào khác.
  • main.js – Chứa mã của ứng dụng.

Phiên bản Angular 2 chỉ tạo ra ba tệp script (inline.js, styles.bundle.js & main.bundle.js).

Các tệp này được thêm vào bởi trình tải module Webpack.

Webpack là gì?

Webpack là một trình đóng gói (bundler), nó quét ứng dụng để tìm kiếm các tệp javascript và hợp nhất chúng thành một (hoặc nhiều) tệp lớn. Webpack có khả năng đóng gói bất kỳ loại tệp nào như JavaScript, CSS, SASS, LESS, hình ảnh, HTML và phông chữ, v.v.

Angular CLI sử dụng Webpack như một trình đóng gói module (module bundler). Webpack cần nhiều tùy chọn cấu hình để hoạt động chính xác. Angular CLI thiết lập tất cả các tùy chọn cấu hình này cho Webpack.

Webpack duyệt qua ứng dụng để tìm các tệp javascript và các tệp khác và hợp nhất tất cả chúng thành một hoặc nhiều gói. Trong ứng dụng ví dụ của chúng ta, nó đã tạo ra năm tệp.

Tải ứng dụng

Sau khi index.html được tải, các thư viện lõi Angular, thư viện bên thứ ba sẽ được tải. Bây giờ Angular cần xác định điểm vào ứng dụng.

Điểm vào ứng dụng

Điểm vào của ứng dụng của chúng ta là tệp main.ts. Bạn sẽ tìm thấy nó trong thư mục src.

angular.json

Angular tìm ra điểm vào ứng dụng từ tệp cấu hình angular.json. Tệp này nằm trong thư mục gốc của dự án. Phần có liên quan của angular.json được hiển thị bên dưới:

Tệp angular-cli.json là tệp cấu hình trong Angular 5 trở về trước. Kể từ phiên bản Angular 6 nó là angular.json.

{
  "$schema": "./node_modules/@angular/cli/lib/config/schema.json",
  "version": 1,
  "newProjectRoot": "projects",
  "projects": {
    "GettingStarted": {
      "projectType": "application",
      "schematics": {},
      "root": "",
      "sourceRoot": "src",
      "prefix": "app",
      "architect": {
        "build": {
          "builder": "@angular-devkit/build-angular:browser",
          "options": {
            "outputPath": "dist/GettingStarted",
            "index": "src/index.html",
            "main": "src/main.ts",                        <====
            "polyfills": "src/polyfills.ts",
            "tsConfig": "tsconfig.app.json",
            "aot": false,
            "assets": [
              "src/favicon.ico",
              "src/assets"
            ],
            "styles": [
              "src/styles.css"
            ],
            "scripts": []
          },

Trường main nằm trong projects -> GettingStarted -> architect -> build -> options có giá trị là src/main.ts. Tệp main.ts là điểm vào của ứng dụng của chúng ta.

Tệp main.ts – điểm vào ứng dụng

Tệp main.ts được hiển thị bên dưới.

import { enableProdMode } from '@angular/core';
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
 
import { AppModule } from './app/app.module';
import { environment } from './environments/environment';
 
if (environment.production) {
  enableProdMode();
}
 
platformBrowserDynamic().bootstrapModule(AppModule)
  .catch(err => console.error(err));

Chúng ta sẽ tìm hiểu chi tiết về nội dung của file main.ts.

import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';

Dòng này import module platformBrowserDynamic từ thư viện @angular/platform-browser-dynamic.

PlatformBrowserDynamic là gì?

platformBrowserDynamic là module chịu trách nhiệm tải ứng dụng Angular trong trình duyệt.

Ứng dụng Angular có thể được khởi động theo nhiều cách và trên nhiều nền tảng. Ví dụ: chúng ta có thể tải ứng dụng của mình trong trình duyệt dành cho máy tính để bàn hoặc trong thiết bị di động với Ionic hoặc NativeScript.

Nếu bạn đang sử dụng nativescript, thì bạn sẽ sử dụng platformNativeScriptDynamic từ thư viện nativescript-angular/platform và sẽ gọi hàm  platformNativeScriptDynamic().bootstrapModule(AppModule). Đọc thêm về quy trình khởi động Angular Nativescript từ đây.

import { AppModule } from './app/app.module';

Dòng trên import module AppModule. AppModule là module gốc của ứng dụng. Các ứng dụng Angular được tổ chức dưới dạng module. Mọi ứng dụng được xây dựng trong Angular phải có ít nhất một module. Module được tải đầu tiên khi ứng dụng được tải được gọi là module gốc.

platformBrowserDynamic().bootstrapModule(AppModule)
  .catch(err => console.error(err));

platformBrowserDynamic tải module gốc bằng cách gọi hàm bootstrapModule và truyền cho nó tham chiếu đến module gốc của chúng ta là AppModule.

Module gốc

Trình khởi động của Angular tải module gốc của chúng ta là AppModule. AppModule nằm trong thư mục src/app. Mã của module gốc được hiển thị bên dưới:

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
 
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
 
@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    AppRoutingModule
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

Module gốc phải có ít nhất một component gốc. Component gốc được tải khi module được tải bởi Angular.

Trong ví dụ của chúng ta, AppComponent là component gốc của chúng ta. Do đó chúng ta import nó vào module gốc.

import { AppComponent } from './app.component';

Chúng ta sử dụng decorator @NgModule để xác định module Angular và cung cấp siêu dữ liệu về module.

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    AppRoutingModule
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

Metadata imports

Chúng ta cần liệt kê tất cả các module bên ngoài được yêu cầu bao gồm các module Angular khác, được sử dụng bởi module Angular này.

Metadata declarations

Metadata declarations là một mảng chứa danh sách các component, directive và pipe thuộc module Angular này. Chúng ta chỉ có một component trong ứng dụng của mình là AppComponent.

Metadata providers

Metadata providers là nơi chúng ta đăng ký các service chúng ta đã tạo. Dependency Injection trong Angular sẽ inject các service trong component, directive và pipe và các service khác.

Metadata bootstrap

Metadata bootstrap chứa danh sách component mà Angular sẽ tải khi module này được tải. Component phải là một phần của module này. Chúng ta muốn tải component AppComponent khi module AppModule được tải, do đó chúng ta đăng ký nó ở đây.

Angular đọc metadata bootstrap và tải AppComponent.

Component

Cuối cùng, chúng ta đến component AppComponent, đó là component gốc của AppModule. Mã của component AppComponent được hiển thị bên dưới:

import { Component } from '@angular/core';
 
@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  title = 'GettingStarted';
}

Class AppComponent có khai báo decorator @Component.

Decorator @Component cung cấp metadata về component cho Angular. Nó có 3 thuộc tính trong đoạn mã trên đó là: selector, templateURLstyleUrls.

Metadata selector

Metadata selector chỉ định bộ chọn CSS, nơi template của chúng ta sẽ được chèn vào HTML. Bộ chọn CSS trong mã của chúng ta là app-root.

Metadata templateURL

Metadata templateURL chứa một đường dẫn tới tệp template HTML, sẽ được hiển thị trong trình duyệt. Tệp template HTML này là app.component.html.

Metadata styleURLs

Metadata styleURLs chứa một hoặc nhiều đường dẫn tới tệp style CSS, sẽ được sử dụng để định kiểu cho template HTML. Tệp style CSS này là app.component.css.

Template

Component AppComponent định nghĩa template là app.component.html và bộ chọn CSS là app-root.

Nếu bạn để ý thì trong tệp index.html có khai báo thẻ app-root như sau:

<body>
  <app-root></app-root>
</body>

Angular khi gặp thẻ app-root trong tệp index.html sẽ hiển thị template của component AppComponent vào giữa các thẻ đó.

Source code

Tải xuống mã nguồn tại đây. Mã có sẵn trong thư mục GettingStarted

Phần kết luận

Trong hướng dẫn này, chúng ta đã tìm hiểu cách Angular hoạt động bên trong và khởi động ứng dụng của chúng ta.

Để lại một bình luận

Email của bạn sẽ không được hiển thị công khai. Các trường bắt buộc được đánh dấu *