Angular kitaplıkları yerel olarak nasıl geliştirilir

Nov 25 2022
Merhaba ! Bu hikayede size Angular kitaplıklarıyla yerel olarak nasıl çalışacağınızı ve bunları sürekli uzak depoya göndermeye gerek kalmadan nasıl geliştireceğinizi göstermek istiyorum :) DRY - büyük ve karmaşık bir Angular projesinde çalışıyorsanız kod tekrarından nasıl kaçınılır , Bir kod çoğaltma sorunuyla karşılaşacağınızdan eminim. Örnek olarak, uygulamanızın "görünüşüne" odaklanalım - muhtemelen tüm sayfaların stili tutarlı olmalıdır (kullanıcılarınızın kafasını karıştırmak ve her sayfada farklı görünen düğmeler olmasını istemezsiniz).
Unsplash'ta Ryunosuke Kikuno'nun fotoğrafı

Merhaba ! Bu hikayede size Angular kitaplıklarıyla yerel olarak nasıl çalışılacağını ve bunları sürekli olarak uzak depoya göndermeye gerek kalmadan nasıl geliştireceğinizi göstermek istiyorum :)

DRY - kod tekrarından nasıl kaçınılır

Büyük ve karmaşık bir Angular projesi üzerinde çalışıyorsanız, kod çoğaltma sorunuyla karşılaşacağınızdan eminim. Örnek olarak, uygulamanızın "görünüşüne" odaklanalım - muhtemelen tüm sayfaların stili tutarlı olmalıdır (kullanıcılarınızın kafasını karıştırmak ve her sayfada farklı görünen düğmeler olmasını istemezsiniz). Tamam, bu kolay - bu ortak stilleri styles.scssdosyaya taşıyabilir veya 7–1 desenini kullanarak zarif bir şekilde tasarlayabilirsiniz.

Ancak , yalnızca görünmekle kalmayıp aynı şekilde davranması gereken bazı ortak bileşenleriniz varsa ne olur ? Bu… hala kolay! Uygulamanızda paylaşılan bir modül oluşturun , bileşenlerinizi orada tanımlayın ve bunları modül tanımında dışa aktarın. Harika !

Şimdi daha karmaşık soruna odaklanalım. Ya şirketinizin birden fazla Angular uygulaması varsa? Ve her uygulama benzer görünmelidir, örneğin:

  • aynı üst bilgiye ve alt bilgiye sahip olmak
  • aynı kurumsal CSS stiline sahip
  • formları, doğrulama hatalarını ve diğer mesajları aynı şekilde görüntüleme

kütüphane oluşturma

Burada kitaplık oluşturmaya ilişkin resmi dokümantasyon sayfasını bulabilirsiniz. Orada anlatılan adımları takip edelim ve kütüphanemizi oluşturalım:

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

  • paylaşımlı çalışma alanım , kitaplıklarınız için ortak bir çalışma alanıdır
  • my-buttons , diğer projelerde yeniden kullanabileceğiniz örnek bir kitaplıktır.

{
  "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

Bileşen oluşturuldu, böylece bir düğme görüntülemek için şablonunu güncelleyebiliriz

<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

Kütüphanemizi zaten oluşturduk, şimdi client uygulaması zamanı. Bunu oluşturmak için Angular CLI kullanacağım: ve uygulamanın (son bağımlılıktan sonra ) bir bağımlılık olarak ng new my-applicationekleyeceğim@my-company/my-buttonspackage.jsonzone.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/ **

Ayrıca aşağıdakiler gibi başka hatalar da görürsünüz:

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

Burada tam npm link komut belgelerini bulabilirsiniz. Canlı yeniden yükleme ile yerel olarak paylaşılan kitaplık geliştirmek için bu komutu nasıl kullanacağınızı göstereceğim.

Dizine geri dönelim my-shared-workspace, derleme my-buttonskitaplığı ( --watchcanlı yeniden yüklemeden bayrak sorumludur) ve derlemenin dizinine gidelim

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

Dizinde my-application, angular.jsonbir seçenek daha ekleyin - bu bağlantılı kitaplığı kullanmamıza izin verecek olan korumaSymlinks .

{
  "$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

Bundan sonra ng servetekrar çalıştırın:

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.

Sonucu görelim:

Harika ! Şimdi fancy-button-component.html'de bir şeyi değiştirmeyi deneyin.

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

Artık hem kütüphane hem de uygulama üzerinde herhangi bir zorluk yaşamadan çalışabilirsiniz :)

Doğrulama

Kitaplığın hangi sürümünü kullandığınızı doğrulamak için aşağıdaki komutu çalıştırabilirsiniz:

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

Değişiklikleriniz üzerinde yerel olarak çalışmayı bitirdikten sonra, istemci uygulamasında bağlantılı kitaplığı kullanmayı aşağıdaki şekilde durdurabilirsiniz.

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

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

Malzemeler