Cara mengembangkan library Angular secara lokal

Nov 25 2022
Hai ! Dalam cerita ini saya ingin menunjukkan kepada Anda cara bekerja dengan perpustakaan Angular secara lokal, dan mengembangkannya tanpa perlu terus mendorongnya ke repositori jarak jauh :) KERING - cara menghindari pengulangan kode Jika Anda mengerjakan proyek Angular yang besar dan kompleks , saya yakin Anda akan menghadapi masalah duplikasi kode. Sebagai contoh, mari fokus pada "tampilan" aplikasi Anda - semua halaman mungkin harus memiliki gaya yang konsisten (Anda tidak ingin membingungkan pengguna dan memiliki tombol yang terlihat berbeda di setiap halaman).
Foto oleh Ryunosuke Kikuno di Unsplash

Hai ! Dalam cerita ini saya ingin menunjukkan kepada Anda bagaimana bekerja dengan perpustakaan Angular secara lokal, dan mengembangkannya tanpa perlu terus mendorongnya ke repositori jarak jauh :)

KERING - cara menghindari pengulangan kode

Jika Anda mengerjakan proyek Angular yang besar dan kompleks, saya yakin Anda akan menghadapi masalah duplikasi kode. Sebagai contoh, mari fokus pada "tampilan" aplikasi Anda - semua halaman mungkin harus memiliki gaya yang konsisten (Anda tidak ingin membingungkan pengguna dan memiliki tombol yang terlihat berbeda di setiap halaman). Oke, itu mudah - Anda bisa memindahkan gaya umum tersebut ke styles.scssfile, atau menggunakan pola 7–1 untuk mendesainnya dengan cara yang elegan.

Tetapi bagaimana jika Anda memiliki beberapa komponen umum yang seharusnya tidak hanya terlihat, tetapi juga berperilaku sama? Itu… masih mudah! Cukup buat modul bersama di aplikasi Anda, tentukan komponen Anda di sana, dan ekspor dalam definisi modul. Besar !

Sekarang, mari kita fokus pada masalah yang lebih kompleks. Bagaimana jika perusahaan Anda memiliki lebih dari satu aplikasi Angular? Dan setiap aplikasi harus terlihat serupa, misalnya:

  • memiliki header dan footer yang sama
  • memiliki gaya CSS perusahaan yang sama
  • memiliki cara yang sama dalam menampilkan formulir, kesalahan validasi, dan pesan lainnya

pembuatan perpustakaan

Di sini Anda dapat menemukan halaman dokumentasi resmi tentang membuat perpustakaan. Mari ikuti langkah-langkah yang dijelaskan di sana dan buat perpustakaan kita:

ng new my-shared-workspace --no-create-application
cd my-shared-workspace
ng generate library my-buttons

  • my-shared-workspace adalah ruang kerja umum untuk perpustakaan Anda
  • tombol-saya adalah pustaka contoh yang dapat Anda gunakan kembali di proyek lain

{
  "name": "@my-company/my-buttons",
  "version": "0.0.1",
  "peerDependencies": {
    "@angular/common": "^14.2.0",
    "@angular/core": "^14.2.0"
  },
  "dependencies": {
    "tslib": "^2.3.0"
  }
}

my-shared-workspace/projects/my-buttons/src/lib> ng g c fancy-button

Komponen dibuat, sehingga kita dapat mengupdate templatenya untuk menampilkan sebuah tombol

<button>fancy-button works!</button>

@NgModule({
  declarations: [
    MyButtonsComponent,
    FancyButtonComponent
  ],
  imports: [
  ],
  exports: [
    MyButtonsComponent,
    FancyButtonComponent // <-- here
  ]
})
export class MyButtonsModule { }

/*
 * Public API Surface of my-buttons
 */

export * from './lib/my-buttons.service';
export * from './lib/my-buttons.component';
export * from './lib/my-buttons.module';
export * from './lib/fancy-button/fancy-button.component'; // <-- here

Kami sudah membuat perpustakaan kami, jadi sekarang saatnya untuk aplikasi klien. Saya akan menggunakan Angular CLI untuk membuatnya: ng new my-application, dan saya akan menambahkan @my-company/my-buttonssebagai ketergantungan pada aplikasi package.json(ketergantungan terakhir, setelah zone.js)

{
  "name": "my-application",
  "version": "0.0.0",
  "scripts": {
    "ng": "ng",
    "start": "ng serve",
    "build": "ng build",
    "watch": "ng build --watch --configuration development",
    "test": "ng test"
  },
  "private": true,
  "dependencies": {
    "@angular/animations": "^14.2.0",
    "@angular/common": "^14.2.0",
    "@angular/compiler": "^14.2.0",
    "@angular/core": "^14.2.0",
    "@angular/forms": "^14.2.0",
    "@angular/platform-browser": "^14.2.0",
    "@angular/platform-browser-dynamic": "^14.2.0",
    "@angular/router": "^14.2.0",
    "rxjs": "~7.5.0",
    "tslib": "^2.3.0",
    "zone.js": "~0.11.4",
    "@my-company/my-buttons": "0.0.1"
  },
  "devDependencies": {
    "@angular-devkit/build-angular": "^14.2.6",
    "@angular/cli": "~14.2.6",
    "@angular/compiler-cli": "^14.2.0",
    "@types/jasmine": "~4.0.0",
    "jasmine-core": "~4.3.0",
    "karma": "~6.4.0",
    "karma-chrome-launcher": "~3.1.0",
    "karma-coverage": "~2.2.0",
    "karma-jasmine": "~5.1.0",
    "karma-jasmine-html-reporter": "~2.0.0",
    "typescript": "~4.7.2"
  }
}

import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { MyButtonsModule } from '@my-company/my-buttons';

import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';

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

<lib-fancy-button></lib-fancy-button>

Error: src/app/app.component.html:1:1 - error NG8001: 'lib-fancy-button' is not a known element:
1. If 'lib-fancy-button' is an Angular component, then verify that it is part of this module.
2. If 'lib-fancy-button' is a Web Component then add 'CUSTOM_ELEMENTS_SCHEMA' to the '@NgModule.schemas' of this component to suppress this message.

1 <lib-fancy-button></lib-fancy-button>
  ~~~~~~~~~~~~~~~~~~

  src/app/app.component.ts:5:16
    5   templateUrl: './app.component.html',
                     ~~~~~~~~~~~~~~~~~~~~~~
    Error occurs in the template of component AppComponent.




** Angular Live Development Server is listening on localhost:4200, open your browser on http://localhost:4200/ **

Anda juga akan melihat beberapa kesalahan lainnya seperti:

Error: src/app/app.module.ts:3:33 - error TS2307: Cannot find module '@my-company/my-buttons' or its corresponding type declarations.

3 import { MyButtonsModule } from '@my-company/my-buttons';

npm ERR! code E404
npm ERR! 404 Not Found - GET https://registry.npmjs.org/@my-company%2fmy-buttons - Not found
npm ERR! 404
npm ERR! 404  '@my-company/[email protected]' is not in this registry.
npm ERR! 404
npm ERR! 404 Note that you can also install from a
npm ERR! 404 tarball, folder, http url, or git url.
Npm link to the rescue

Di sini Anda dapat menemukan dokumentasi perintah tautan npm lengkap. Saya akan menunjukkan cara menggunakan perintah ini untuk mengembangkan shared library secara lokal, dengan live reload.

Mari kembali ke my-shared-workspacedirektori, build my-buttonslibrary (flag --watchbertanggung jawab untuk live reload), dan buka direktori build

my-shared-workspace> ng build my-buttons --configuration development --watch
Building Angular Package

------------------------------------------------------------------------------
Building entry point '@my-company/my-buttons'
------------------------------------------------------------------------------
✔ Compiling with Angular sources in Ivy full compilation mode.
✔ Writing FESM bundles
✔ Copying assets
✔ Writing package manifest
✔ Built @my-company/my-buttons

------------------------------------------------------------------------------
Built Angular Package
 - from: /Users/<user>/<path>/my-shared-workspace/projects/my-buttons
 - to:   /Users/<user>/<path>/my-shared-workspace/dist/my-buttons
------------------------------------------------------------------------------

my-shared-workspace> cd dist/my-buttons
my-shared-workspace/dist/my-buttons> npm link

added 1 package, and audited 3 packages in 1s

found 0 vulnerabilities

Di my-applicationdirektori, angular.jsontambahkan satu opsi lagi - pertahankanSymlinks, yang memungkinkan kita menggunakan pustaka tertaut ini.

{
  "$schema": "./node_modules/@angular/cli/lib/config/schema.json",
  "version": 1,
  "newProjectRoot": "projects",
  "projects": {
    "my-application": {
      "projectType": "application",
      "schematics": {
        "@schematics/angular:component": {
          "style": "scss"
        }
      },
      "root": "",
      "sourceRoot": "src",
      "prefix": "app",
      "architect": {
        "build": {
          "builder": "@angular-devkit/build-angular:browser",
          "options": {
            "outputPath": "dist/my-application",
            "index": "src/index.html",
            "main": "src/main.ts",
            "polyfills": "src/polyfills.ts",
            "tsConfig": "tsconfig.app.json",
            "inlineStyleLanguage": "scss",
            "preserveSymlinks": true,
            "assets": [
              "src/favicon.ico",
              "src/assets"
            ],
            "styles": [
              "src/styles.scss"
            ],
            "scripts": []
          },
          "configurations": {
            "production": {
              "budgets": [
                {
                  "type": "initial",
                  "maximumWarning": "500kb",
                  "maximumError": "1mb"
                },
                {
                  "type": "anyComponentStyle",
                  "maximumWarning": "2kb",
                  "maximumError": "4kb"
                }
              ],
              "fileReplacements": [
                {
                  "replace": "src/environments/environment.ts",
                  "with": "src/environments/environment.prod.ts"
                }
              ],
              "outputHashing": "all"
            },
            "development": {
              "buildOptimizer": false,
              "optimization": false,
              "vendorChunk": true,
              "extractLicenses": false,
              "sourceMap": true,
              "namedChunks": true
            }
          },
          "defaultConfiguration": "production"
        },
        "serve": {
          "builder": "@angular-devkit/build-angular:dev-server",
          "configurations": {
            "production": {
              "browserTarget": "my-application:build:production"
            },
            "development": {
              "browserTarget": "my-application:build:development"
            }
          },
          "defaultConfiguration": "development"
        },
        "extract-i18n": {
          "builder": "@angular-devkit/build-angular:extract-i18n",
          "options": {
            "browserTarget": "my-application:build"
          }
        },
        "test": {
          "builder": "@angular-devkit/build-angular:karma",
          "options": {
            "main": "src/test.ts",
            "polyfills": "src/polyfills.ts",
            "tsConfig": "tsconfig.spec.json",
            "karmaConfig": "karma.conf.js",
            "inlineStyleLanguage": "scss",
            "assets": [
              "src/favicon.ico",
              "src/assets"
            ],
            "styles": [
              "src/styles.scss"
            ],
            "scripts": []
          }
        }
      }
    }
  }
}

my-application> npm link @my-company/my-buttons

added 1 package, removed 1 package, and audited 918 packages in 2s

121 packages are looking for funding
  run `npm fund` for details

found 0 vulnerabilities

Setelah itu jalankan ng servelagi:

my-application> ng serve
✔ Browser application bundle generation complete.

Initial Chunk Files   | Names         |  Raw Size
vendor.js             | vendor        |   3.30 MB |
polyfills.js          | polyfills     | 318.02 kB |
styles.css, styles.js | styles        | 210.56 kB |
main.js               | main          |  12.32 kB |
runtime.js            | runtime       |   6.53 kB |

                      | Initial Total |   3.84 MB

Build at: 2022-11-24T18:27:00.803Z - Hash: 7669daf65ca2f665 - Time: 4598ms

** Angular Live Development Server is listening on localhost:4200, open your browser on http://localhost:4200/ **


✔ Compiled successfully.

Mari kita lihat hasilnya:

Besar ! Sekarang coba ubah sesuatu di fancy-button-component.html

<button>fancy-button works - live reload!</button>

Sekarang Anda dapat mengerjakan pustaka dan aplikasi tanpa kesulitan :)

Verifikasi

Untuk memverifikasi versi perpustakaan mana yang Anda gunakan, Anda dapat menjalankan perintah di bawah ini:

npm list -g
/usr/local/lib
├── @angular/[email protected]
├── @my-company/[email protected]+1669314745555 -> ./../../../Users/<user>/<path>/my-shared-workspace/dist/my-buttons

Setelah selesai mengerjakan perubahan secara lokal, Anda dapat berhenti menggunakan pustaka tertaut di aplikasi klien dengan cara berikut

my-application> npm unlink @my-company/my-buttons --no-save

my-shared-workspace/dist/my-buttons> npm rm -g @my-company/my-buttons

Bahan