Angular. Создание библиотеки компонентов

Angular CLI Library Example

Создание проекта lib-project без приложения (initial app)

ng new lib-project --createApplication=false
cd lib-project

Создание библиотеки some-api, где префиксом компонентов будет masha

ng g library some-api --prefix=masha

Разработка компонентов

Просто генерируем компонент + добавляем флаг project и имя библиотеки

ng g c button --project some-api

Сборка и публикация библиотеки

ng build --project some-api
Building Angular Package
Building entry point 'some-api'
Compiling TypeScript sources through ngc
Bundling to FESM2015
Bundling to FESM5
Bundling to UMD
Minifying UMD bundle
Copying declaration files
Writing package metadata
Removing scripts section in package.json as it's considered a potential security vulnerability.
Built some-api
Built Angular Package!
 - from: e:\home\angular\lib-project\projects\some-api
 - to:   e:\home\angular\lib-project\dist\some-api

cd dist/some-api
npm publish --registry http://...

Во время разработки библиотеки доступно слежение

ng build --project some-api --watch

Для приватного/локального npm репозитария удобно использовать verdaccio

npm i -g verdaccio

Создание тестового приложения внутри проекта

ng g application playground-app
ng serve --project playground-app

Так как тестовое приложение и библиотека находятся в одном проекте, то импортировать модули бибилотеки можно следующим образом:

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';

import { AppComponent } from './app.component';
import { SomeApiModule } from 'some-api';       <====

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

Он его подхватит из dist каталога. Angular CLI смотрит сначала в paths из файла tsconfig.json, а затем в node_modules.

Установка библиотеки.

Если используется npm репозиторий, то всё как обычно npm i <package_name>. Если нет, то алгоритм следующий:

  • перейти в dist каталог библиотки lib-project\dist\some-api
  • выполнить команду npm pack, которая создаст распространяемый tgz архив

В рассматриваемом примере это будет some-api-0.0.1.tgz

$ npm pack
npm notice
npm notice package: some-api@0.0.1
npm notice === Tarball Contents ===
npm notice 522B  package.json
npm notice 124B  public_api.d.ts
npm notice 155B  some-api.d.ts
npm notice 1.7kB some-api.metadata.json
npm notice 4.1kB bundles/some-api.umd.js
npm notice 1.9kB bundles/some-api.umd.js.map
npm notice 1.2kB bundles/some-api.umd.min.js
npm notice 1.9kB bundles/some-api.umd.min.js.map
npm notice 1.5kB esm2015/lib/button/button.component.js
npm notice 1.5kB esm2015/lib/some-api.component.js
npm notice 1.7kB esm2015/lib/some-api.module.js
npm notice 1.3kB esm2015/lib/some-api.service.js
npm notice 937B  esm2015/public_api.js
npm notice 898B  esm2015/some-api.js
npm notice 1.7kB esm5/lib/button/button.component.js
npm notice 1.7kB esm5/lib/some-api.component.js
npm notice 1.9kB esm5/lib/some-api.module.js
npm notice 1.5kB esm5/lib/some-api.service.js
npm notice 937B  esm5/public_api.js
npm notice 898B  esm5/some-api.js
npm notice 2.6kB fesm2015/some-api.js
npm notice 1.8kB fesm2015/some-api.js.map
npm notice 3.2kB fesm5/some-api.js
npm notice 1.9kB fesm5/some-api.js.map
npm notice 145B  lib/button/button.component.d.ts
npm notice 146B  lib/some-api.component.d.ts
npm notice 41B   lib/some-api.module.d.ts
npm notice 62B   lib/some-api.service.d.ts
npm notice === Tarball Details ===
npm notice name:          some-api
npm notice version:       0.0.1
npm notice filename:      some-api-0.0.1.tgz
npm notice package size:  7.1 kB
npm notice unpacked size: 37.9 kB
npm notice shasum:        f091e840592a30e534d45acd0e27436be4271df0
npm notice integrity:     sha512-1v/EPainHg1LO[...]DP8m/OoByBmjQ==
npm notice total files:   28
npm notice
some-api-0.0.1.tgz

В нужном приложении выполняется команда установки со ссылкой на tgz архив.

npm install ../../lib-project/dist/some_api/some-api-0.0.1.tgz

Пакет в секции зависимостей файла package.json:

  "dependencies": {
    "@angular/animations": "~7.1.0",
    "@angular/common": "~7.1.0",
    "@angular/compiler": "~7.1.0",
    "@angular/core": "~7.1.0",
    "@angular/forms": "~7.1.0",
    "@angular/platform-browser": "~7.1.0",
    "@angular/platform-browser-dynamic": "~7.1.0",
    "@angular/router": "~7.1.0",
    "core-js": "^2.5.4",
    "lodash": "^4.17.11",
    "rxjs": "~6.3.3",
    "some-api": "file:../../some-api-0.0.1.tgz",   <===
    "tslib": "^1.9.0",
    "zone.js": "~0.8.26"
  },

Похожие записи

#local variable внутри *ngIf

Представлены 2 варианта решения, как сослаться на локальную переменную шаблона (#myVar) за пределами шаблона:

  • @ViewChild
  • @ViewChildren
12 февраля 2019 г. в Angular

@Directive v/s @Component in Angular

Компоненты создают DOM элементы и добавляют к ним поведение, а директивы только добавляют поведение к существующим DOM элементам

13 августа 2018 г. в Angular

Angular attribute setter

Пример задания значения булева Input свойства как директивы, на примере:

09 октября 2018 г. в Angular

Об subscribe() vs async

О предпочтительности использования async pipe. При OnPush стратегии не требуется вызывать markForCheck() внутри подписки +решение с несколькими | async pipes развёрнутых в одну переменную (внутри шаблона).