× Giới thiệu Lịch khai giảng Tin tức Sản phẩm học viên

Angular CLI builders là gì và các thông tin cơ bản

20/07/2023 01:20

Cùng tìm hiểu một số thông tin và câu lệnh về Angular CLI builders ngay trong bài viết dưới đây bạn nhé

Một số lệnh CLI góc chạy một quy trình phức tạp trên mã của bạn, chẳng hạn như linting, xây dựng hoặc thử nghiệm. Các lệnh sử dụng một công cụ nội bộ có tên là Kiến trúc sư để chạy các trình xây dựng CLI , áp dụng một công cụ khác để hoàn thành tác vụ mong muốn.

Với phiên bản Angular 8, CLI Builder API ổn định và có sẵn cho các nhà phát triển muốn tùy chỉnh Angular CLI bằng cách thêm hoặc sửa đổi các lệnh. Ví dụ: bạn có thể cung cấp một trình tạo để thực hiện một tác vụ hoàn toàn mới hoặc để thay đổi công cụ của bên thứ ba nào được sử dụng bởi một lệnh hiện có.

Tài liệu này giải thích cách trình tạo CLI tích hợp với tệp cấu hình không gian làm việc và cho biết cách bạn có thể tạo trình tạo của riêng mình.

Angular CLI builders

Công cụ Kiến trúc nội bộ ủy nhiệm công việc cho các hàm xử lý được gọi là trình tạo . Hàm xử lý trình tạo nhận được hai đối số; một bộ đầu vào options(một đối tượng JSON) và một context(một BuilderContextđối tượng).

Việc tách các mối quan tâm ở đây cũng giống như với sơ đồ , được sử dụng cho các lệnh CLI khác có liên quan đến mã của bạn (chẳng hạn như ng generate).

  • Đối optionstượng được cung cấp bởi người dùng CLI, trong khi contextđối tượng được cung cấp bởi API Builder CLI
  • Ngoài thông tin theo ngữ cảnh, contextđối tượng, là một thể hiện của BuilderContext, cũng cung cấp quyền truy cập vào một phương thức lập lịch, context.scheduleTarget(). Bộ lập lịch thực thi chức năng trình xử lý trình tạo với một cấu hình đích nhất định .

Hàm xử lý trình tạo có thể đồng bộ (trả về giá trị) hoặc không đồng bộ (trả về Lời hứa) hoặc có thể xem và trả về nhiều giá trị (trả về Có thể quan sát). Giá trị trả về hoặc các giá trị phải luôn thuộc loại BuilderOutput. Đối tượng này chứa trường Boolean successvà errortrường tùy chọn có thể chứa thông báo lỗi.

Angular cung cấp một số trình tạo được CLI sử dụng cho các lệnh như ng buildvà ng test. Bạn có thể tìm thấy (và tùy chỉnh) các cấu hình đích mặc định cho các trình tạo này và các trình tạo CLI tích hợp khác trong phần "kiến trúc" của tệp cấu hình không gian làm việc , angular.json. Ngoài ra, hãy mở rộng và tùy chỉnh Angular bằng cách tạo trình tạo của riêng bạn, bạn có thể chạy trình tạo này bằng cách sử dụng ng runlệnh CLI .

Cấu trúc dự án Builder

Trình xây dựng nằm trong thư mục "dự án" có cấu trúc tương tự như không gian làm việc Góc, với các tệp cấu hình chung ở cấp cao nhất và cấu hình cụ thể hơn trong thư mục nguồn với các tệp mã xác định hành vi. Ví dụ: myBuilderthư mục của bạn có thể chứa các tệp sau.

CÁC TẬP TIN MỤC ĐÍCH
src/my-builder.ts Tệp nguồn chính cho định nghĩa trình tạo.
src/my-builder.spec.ts Tệp nguồn cho các bài kiểm tra.
src/schema.json Định nghĩa các tùy chọn đầu vào của trình tạo.
builders.json Định nghĩa nhà xây dựng
package.json phụ thuộc. Nhìn thấyhttps://docs.npmjs.com/files/package.json.
tsconfig.json Cấu hình TypeScript.

Xuất bản trình xây dựng lên npm(xem Xuất bản Thư viện của bạn ). Nếu bạn xuất bản nó dưới dạng @example/my-builder, hãy cài đặt nó bằng lệnh sau.

npm install @example/my-builder

Tạo một trình xây dựng

Ví dụ: tạo trình tạo sao chép tệp. Để tạo trình tạo, hãy sử dụng createBuilder()chức năng Trình tạo CLI và trả về một Promise<BuilderOutput>đối tượng.

src/my-builder.ts (xương xây dựng)
import { BuilderContext, BuilderOutput, createBuilder } from '@angular-devkit/architect';
import { JsonObject } from '@angular-devkit/core';

interface Options extends JsonObject {
  source: string;
  destination: string;
}

export default createBuilder(copyFileBuilder);

async function copyFileBuilder(
  options: Options,
  context: BuilderContext,
): Promise<BuilderOutput> {
}

Bây giờ hãy thêm một số logic vào nó. Đoạn mã sau truy xuất đường dẫn tệp nguồn và đích từ các tùy chọn của người dùng và sao chép tệp từ nguồn đến đích (sử dụngcopyFile()Phiên bản hứa hẹn của chức năng NodeJS tích hợp). Nếu thao tác sao chép không thành công, thao tác này sẽ trả về lỗi kèm theo thông báo về sự cố tiềm ẩn.

src/my-builder.ts (trình xây dựng)
import { BuilderContext, BuilderOutput, createBuilder } from '@angular-devkit/architect';
import { JsonObject } from '@angular-devkit/core';
import { promises as fs } from 'fs';

interface Options extends JsonObject {
  source: string;
  destination: string;
}

export default createBuilder(copyFileBuilder);

async function copyFileBuilder(
  options: Options,
  context: BuilderContext,
): Promise<BuilderOutput> {
  try {
    await fs.copyFile(options.source, options.destination);
  } catch (err) {
    return {
      success: false,
      error: err.message,
    };
  }

  return { success: true };
}

Xử lý đầu ra

Theo mặc định, copyFile()không in bất kỳ thứ gì ra đầu ra tiêu chuẩn của quy trình hoặc lỗi. Nếu xảy ra lỗi, có thể khó hiểu chính xác trình tạo đang cố gắng làm gì khi xảy ra sự cố. Thêm một số ngữ cảnh bổ sung bằng cách ghi thông tin bổ sung bằng LoggerAPI. Điều này cũng cho phép bản thân trình xây dựng được thực thi trong một quy trình riêng biệt, ngay cả khi đầu ra tiêu chuẩn và lỗi bị vô hiệu hóa (như trong mộtứng dụng điện tử).

Bạn có thể truy xuất một Loggerthể hiện từ ngữ cảnh.

src/my-builder.ts (xử lý đầu ra)
import { BuilderContext, BuilderOutput, createBuilder } from '@angular-devkit/architect';
import { JsonObject } from '@angular-devkit/core';
import { promises as fs } from 'fs';

interface Options extends JsonObject {
  source: string;
  destination: string;
}

export default createBuilder(copyFileBuilder);

async function copyFileBuilder(
  options: Options,
  context: BuilderContext,
): Promise<BuilderOutput> {
  try {
    await fs.copyFile(options.source, options.destination);
  } catch (err) {
    context.logger.error('Failed to copy file.');
    return {
      success: false,
      error: err.message,
    };
  }

  return { success: true };
}

Báo cáo tiến độ và trạng thái

API Trình tạo CLI bao gồm các công cụ báo cáo trạng thái và tiến trình, có thể cung cấp gợi ý cho các chức năng và giao diện nhất định.

Để báo cáo tiến trình, hãy sử dụng context.reportProgress()phương thức lấy giá trị hiện tại, tổng (tùy chọn) và chuỗi trạng thái làm đối số. Tổng số có thể là bất kỳ số nào; ví dụ: nếu bạn biết mình phải xử lý bao nhiêu tệp, tổng số có thể là số tệp và hiện tại phải là số được xử lý cho đến nay. Chuỗi trạng thái không được sửa đổi trừ khi bạn chuyển vào một giá trị chuỗi mới.

Bạn có thể thấy mộtví dụvề cách trình tslintxây dựng báo cáo tiến độ.

Trong ví dụ của chúng tôi, thao tác sao chép đã kết thúc hoặc vẫn đang thực thi, vì vậy không cần báo cáo tiến độ nhưng bạn có thể báo cáo trạng thái để trình tạo chính đã gọi trình tạo của chúng tôi biết điều gì đang xảy ra. Sử dụng context.reportStatus()phương thức để tạo chuỗi trạng thái có độ dài bất kỳ.

LƯU Ý :
Không đảm bảo rằng một chuỗi dài sẽ được hiển thị toàn bộ; nó có thể được cắt để phù hợp với giao diện người dùng hiển thị nó.

Truyền một chuỗi trống để xóa trạng thái.

src/my-builder.ts (báo cáo tiến độ)
import { BuilderContext, BuilderOutput, createBuilder } from '@angular-devkit/architect';
import { JsonObject } from '@angular-devkit/core';
import { promises as fs } from 'fs';

interface Options extends JsonObject {
  source: string;
  destination: string;
}

export default createBuilder(copyFileBuilder);

async function copyFileBuilder(
  options: Options,
  context: BuilderContext,
): Promise<BuilderOutput> {
  context.reportStatus(`Copying ${options.source} to ${options.destination}.`);
  try {
    await fs.copyFile(options.source, options.destination);
  } catch (err) {
    context.logger.error('Failed to copy file.');
    return {
      success: false,
      error: err.message,
    };
  }

  context.reportStatus('Done.');
  return { success: true };
}

Đầu vào của trình tạo

Bạn có thể gọi trình tạo một cách gián tiếp thông qua lệnh CLI hoặc trực tiếp bằng ng runlệnh Angular CLI. Trong cả hai trường hợp, bạn phải cung cấp các đầu vào bắt buộc, nhưng có thể để các đầu vào khác mặc định thành các giá trị được định cấu hình trước cho một mục tiêu cụ thể , cung cấp cấu hình ghi đè được đặt tên, xác định trước và cung cấp thêm các giá trị tùy chọn ghi đè trên dòng lệnh.

Xác thực đầu vào

Bạn xác định đầu vào của trình tạo trong lược đồ JSON được liên kết với trình tạo đó. Công cụ Kiến trúc sư thu thập các giá trị đầu vào đã phân giải thành một optionsđối tượng và xác thực các loại của chúng dựa trên lược đồ trước khi chuyển chúng đến hàm trình tạo. (Thư viện Schematics thực hiện cùng một loại xác thực đầu vào của người dùng.)

Đối với trình tạo ví dụ của chúng tôi, bạn muốn optionsgiá trị là a JsonObjectcó hai khóa: A sourcevà a destination, mỗi khóa là một chuỗi.

Bạn có thể cung cấp lược đồ sau để xác thực kiểu của các giá trị này.

src/schema.json
{
  "$schema": "http://json-schema.org/schema",
  "type": "object",
  "properties": {
    "source": {
      "type": "string"
    },
    "destination": {
      "type": "string"
    }
  }
}

Đây là một ví dụ rất đơn giản, nhưng việc sử dụng lược đồ để xác thực có thể rất hiệu quả. Để biết thêm thông tin, hãy xemTrang web lược đồ JSON.

Để liên kết việc triển khai trình tạo của chúng tôi với lược đồ và tên của nó, bạn cần tạo một tệp định nghĩa trình tạo mà bạn có thể trỏ đến trong tệp package.json.

Tạo một tệp có tên builders.jsongiống như sau:

người xây dựng.json
{
  "builders": {
    "copy": {
      "implementation": "./dist/my-builder.js",
      "schema": "./src/schema.json",
      "description": "Copies a file."
    }
  }
}

Trong package.jsontệp, hãy thêm một builderskhóa cho công cụ Kiến trúc sư biết nơi tìm tệp định nghĩa trình xây dựng của chúng tôi.

gói.json
{
  "name": "@example/copy-file",
  "version": "1.0.0",
  "description": "Builder for copying files",
  "builders": "builders.json",
  "dependencies": {
    "@angular-devkit/architect": "~0.1200.0",
    "@angular-devkit/core": "^12.0.0"
  }
}

Tên chính thức của trình xây dựng của chúng tôi bây giờ là @example/copy-file:copy. Phần đầu tiên của phần này là tên gói (được giải quyết bằng độ phân giải nút) và phần thứ hai là tên trình tạo (được giải quyết bằng tệp builders.json).

Sử dụng một trong số chúng tôi optionsrất đơn giản. Bạn đã làm điều này trong phần trước khi bạn truy cập options.sourcevà options.destination.

src/my-builder.ts (trạng thái báo cáo)
context.reportStatus(`Copying ${options.source} to ${options.destination}.`);
try {
  await fs.copyFile(options.source, options.destination);
} catch (err) {
  context.logger.error('Failed to copy file.');
  return {
    success: false,
    error: err.message,
  };
}

context.reportStatus('Done.');
return { success: true };

cấu hình mục tiêu

Trình tạo phải có một mục tiêu xác định liên kết nó với một cấu hình đầu vào và dự án cụ thể .

Các mục tiêu được xác định trong angular.json tệp cấu hình CLI . Mục tiêu chỉ định trình xây dựng sẽ sử dụng, cấu hình tùy chọn mặc định của nó và các cấu hình thay thế được đặt tên. Công cụ Kiến trúc sư sử dụng định nghĩa đích để giải quyết các tùy chọn đầu vào cho một lần chạy nhất định.

Tệp này angular.jsoncó một phần dành cho từng dự án và phần "kiến trúc sư" của từng dự án sẽ định cấu hình các mục tiêu cho trình tạo được sử dụng bởi các lệnh CLI, chẳng hạn như 'build', 'test' và 'lint'. Ví dụ: theo mặc định, buildlệnh chạy trình xây dựng để thực hiện tác vụ xây dựng và chuyển các giá trị tùy chọn mặc định như được chỉ định cho mục tiêu trong tệp .@angular-devkit/build-angular:browserbuildangular.json

{
  "myApp": {
    …
    "architect": {
      "build": {
        "builder": "@angular-devkit/build-angular:browser",
        "options": {
          "outputPath": "dist/myApp",
          "index": "src/index.html",
          …
        },
        "configurations": {
          "production": {
            "fileReplacements": [
              {
                "replace": "src/environments/environment.ts",
                "with": "src/environments/environment.prod.ts"
              }
            ],
            "optimization": true,
            "outputHashing": "all",
            …
          }
        }
      },
      …