Все классные кошки теперь используют рабочие места, а ВЫ?

Github.com: https://github.com/buildmotion/workspace-demo

Самая последняя версия Angular - это значительный выпуск - версия 6.0.3 на момент публикации. Мы получаем много новых инструментов и функций, которые обеспечивают более эффективную среду разработки.

Когда мы используем новый интерфейс командной строки Angular 6, среда по умолчанию теперь является рабочей областью (ну, может быть, нет - подробнее позже), которая позволяет разрабатывать несколько приложений и библиотек в одной рабочей области. Когда вы добавляете новые приложения и / или библиотеки, вы создаете project элементов. Элемент проекта имеет определенный тип, чтобы указать, является ли он application или library.

application: is a single-page web application.
    library: is a module that is shared by multiple applications

Инструменты рабочего пространства для разработки на Angular были представлены некоторое время назад расширениями Nx от NRWL.io. Набор схем, позволяющих создать workspace, используя настраиваемую конфигурацию, предоставленную NRWL. Если вы используете Nx, вы создаете apps, которые являются либо lib, либо app (одностраничное веб-приложение Angular). Похоже, я только начал использовать Nx Workspace 1.0 от NRWL - 22 мая 2018 года NRWL объявила о выпуске версии 6.0, построенной на основе Angular CLI 6.0. Инструменты для создания и использования библиотек в наши дни развиваются довольно быстро.

Возможность повторно использовать библиотеки в нескольких приложениях - отличная функция. Раньше это определенно было возможно. Однако рабочий процесс был намного более интенсивным и требовал большой настройки библиотек. Теперь это намного проще с версией 6 Angular CLI.

Использование для рабочего пространства Angular

Я предполагаю, что по умолчанию новая рабочая область Angular используется для поддержки возможности совместного использования библиотек Angular между несколькими веб-приложениями. Предыдущий Angular CLI позволяет нам создавать @NgModule в веб-приложении с помощью следующей команды.

ng generate module MyNewModule

Новый интерфейс командной строки Angular 6 позволит вам создать библиотеку Angular, которая на самом деле является @NgModule, вне указанного веб-приложения. Поскольку у нас есть эта новая возможность, у нас есть больше возможностей. Теперь нам нужно решить, какие модули являются кандидатами для повторного использования и обмена стихами, какие из них должны содержаться в указанном приложении. Я считаю, что модули - отличный способ упорядочить код и приложения. Они обеспечивают инкапсуляцию и поддерживают множество хороших принципов программирования. Объединение связанных вещей в один модуль дает много преимуществ. Теперь, если этот модуль является кандидатом для повторного использования другими приложениями, теперь мы можем создать его как библиотеку в новой рабочей области. Думайте об этом как о дополнительной стратегии организации кода. Используйте следующее, чтобы создать новую библиотеку.

ng generate library MyNewLibrary

Итак, в чем разница между module и library? Если модуль может использоваться более чем одним потребителем (например, веб-приложениями Angular или другими модулями), его можно рассматривать как библиотеку. Модуль описывает способность или механизм группировать связанные вещи. А библиотека указывает на то, что она содержит вещи, которые полезны для потребителей библиотеки - подумайте о реальной физической библиотеке, где вы можете посещать и оформлять покупки для вашего удовольствия. Теперь ваша библиотека может использоваться многими пользователями - как книга в библиотеке.

Итак, в чем разница между library и package? Я предполагаю, что если модуль публикуется в репозитории для использования через диспетчер пакетов (подумайте о NPM), что это пакет. Однако во многих недавних сообщениях в блогах и выступлениях сообщества они называются библиотеками. В оставшейся части этой статьи опубликованные или неопубликованные элементы будут называться библиотеками.

Неопубликованные библиотеки

Текущая реализация Angular Workspace предназначена для разработки нескольких общих библиотек веб-приложений в единой среде разработки. Текущая реализация Angular Workspace НЕ является средой разработки (по умолчанию) для создания библиотек для публикации в NPM. Хотя среда может использовать ng-packagr для создания и вывода проекта библиотеки в dist папку, полностью готовую к публикации, это не стандартное использование среды рабочей области. Фактически, когда вы запускаете сценарий сборки по умолчанию, только приложение по умолчанию выводится в папку dist. Стратегия сборки ориентирована на приложение. Он будет создавать приложения и включать любые другие модули, на которые ссылается указанное приложение.

Публикация пакетов - это совсем другой рабочий процесс. Если вы хотите скомпилировать и опубликовать одну из библиотек в новом рабочем пространстве, вы можете использовать команду Angular CLI ng build --project=lib-one. Новая конфигурация проекта в angular.json знает, что этот тип проекта library, теперь он может использовать разные стратегии сборки для разных типов проектов - проекты библиотек будут использовать ng-packagr для сборки и создания распространяемых выходных данных, готовых к публикации. NPM требует дополнительного управления peerDependencies в файле package.json библиотеки. По умолчанию это не делается в процессе сборки библиотек или приложений в новой рабочей области. Вам нужно будет вручную установить эти одноранговые зависимости. Кроме того, NPM требует семантического управления версиями опубликованных библиотек. Перед публикацией пакетов в NPM вам необходимо обновить семантическую версию библиотеки. Веб-приложения в рабочей области не связаны с package понятием библиотеки - они не упоминаются в package.json по имени / версии; и они не установлены в node_modules папку рабочей области. Приложения в справочных библиотеках Worksapce по пути к файлу, как мы увидим.

При сборке проекта приложения нет сборки или вывода проектов библиотеки в папке dist. Чтобы выполнить сборку дистрибутива библиотек, вам необходимо добавить новый сценарий сборки в файл package.json. Вы также захотите обновить версию своего пакета перед созданием сборки дистрибутива для публикации. Следующий сценарий ниже показывает, как создавать (2) библиотеки - этот конкретный процесс сборки будет использовать ng-packagr для создания дистрибутивной версии библиотеки для: UMD, esm5, esm2015, fesm5 и fesm2015. Этот специальный процесс сборки соответствует формату пакета Angular. Отлично!

"package": "ng build --project=libOne && ng build --project=libTwo",

Запустите сценарий, чтобы собрать библиотеки с выводом в папку dist.

npm run package

Сборка и вывод библиотек в папку dist действительно только для публикации пакетов (библиотек) в NPM. Ни одно из приложений не использует и не импортирует эти пакеты из локальной dist папки.

рабочая область-демонстрация

Я создаю workspace-demo рабочее пространство, доступное на Github, чтобы показать базовое использование рабочего процесса разработки для нескольких библиотек и приложений. Рабочая область по умолчанию содержит веб-приложение по умолчанию. Поэтому, чтобы продемонстрировать несколько библиотек, я добавлю (2) новых библиотечных проекта в рабочую область с помощью интерфейса командной строки.

ng generate library libOne
ng generate library libTwo

Использование библиотеки

Когда я добавляю службу в конструктор AppComponent, редактор добавит оператор импорта в LibOneService. Обратите внимание, что в правой части импорта используется ссылка на путь к файлу public_api указанной библиотеки - здесь имя пакета не используется.

Упрощенный рабочий процесс разработчика здесь не требует от нас добавления записи в раздел dependencies файла package.json. Библиотека не публикуется и не содержится в папке node_modules, как большинство пакетов. Помните, что это общие библиотеки в рабочей среде.

У сервиса будет простой SayHello метод - мы просто хотим посмотреть, как здесь все работает.

Я обновлю launch.json, чтобы добавить конфигурацию для использования локального хоста и порта 4200.

Теперь мы можем запустить ng serve, а затем нажать F5, чтобы запустить приложение.

Это было просто. А теперь давайте попробуем что-нибудь более реальное.

Заявка на услугуОдна на услугуДва

В реальном мире библиотека нередко использует другие библиотеки. Все дело в повторном использовании. Наши пакеты, которые мы устанавливаем из NPM, зависят от других пакетов. Мы также можем сделать то же самое с нашими общими библиотеками.

Мы просто расширим реализацию служб так, чтобы LibOneService зависел от LibTwoService, который содержится в lib-two библиотеке. Мы внедрим службу в конструктор LibOneService и обновим метод SayHello для использования экземпляра LibTwoService. Обратите внимание, что инструкция import - это ссылка на путь к файлу public_api из LibTwoService.

Создайте и реализуйте SayHello метод в LibTwoService.

Обслуживайте и запускайте приложение, чтобы просмотреть использование нескольких служб одним приложением.

ng serve

Как видите, рабочий процесс разработки сильно отличается и действительно эффективен. Нет необходимости публиковать библиотеки, а затем устанавливать / обновлять их для использования в приложении.

  • более эффективный рабочий процесс разработки
  • возможность делиться библиотеками от потребителей приложений
  • возможность для библиотек использовать другие библиотеки в рабочей области

Рабочее пространство Angular 6 для публикаций библиотек

Теперь мы понимаем, как использовать среду рабочего пространства по умолчанию для совместного использования библиотек с приложениями. Следующий сценарий, который мы хотим изучить, - это то, как мы можем использовать новое рабочее пространство Angular для публикации библиотек в NPM.

Я хочу протестировать новое рабочее пространство проекта Angular и немного поработать. А также сравните его с рабочим пространством Nx NRWL.io. Вот мои ожидания:

  1. Используйте @scope для библиотек - чтобы помочь управлять библиотеками и организовывать их. Например, @buildmotion/security, где моя область действия - @buildmotion.
  2. Используйте имя области, если есть какие-либо библиотеки-кандидаты для публикации в NPM.
  3. Потребители (т. Е. Компоненты приложения или другие модули) библиотеки должны иметь возможность import использовать библиотеку, используя ее объем и имя: @buildmotion/security.
  4. Простая настройка проектов библиотек и приложений.

Angular 6 имеет новую конфигурацию angular.json, которая заменяет старый файл .angular-cli.json. Эта новая конфигурация содержит список projects, позволяющий индивидуально настраивать несколько проектов.

Чтобы использовать эти новые функции, вам необходимо:

  1. Обновите среду разработки global, чтобы использовать Angular 6.
npm install -g @angular/cli@latest
  1. Создайте новый workspace для разработки.
ng new buildmotion

Если вы создали новое рабочее пространство, вы заметите, что в корне рабочего пространства есть папка src с веб-приложением по умолчанию. То же самое и с предыдущей версией Angular CLI.

Конфигурация веб-приложения по умолчанию содержится в разделе angular.json проектов. Если вы используете интерфейс командной строки для создания дополнительных проектов (библиотеки или приложения), он будет создавать новую папку в папке projects для каждого нового проекта.

Я бы предпочел, чтобы все мои проекты, включая приложение по умолчанию, находились в папке проектов. Является ли приложение по умолчанию в src корневой папке другим или более особенным? Наличие приложений в (2) разных местах немного сбивает с толку - я предпочитаю согласованность. Похоже, что новая среда поддерживает рабочее пространство, но при настройке проекта по умолчанию все еще используется предыдущая структура папок для одного веб-приложения. И, кстати, если вы хотите добавить больше проектов в workspace, который тоже поддерживается.

Новые конфигурации с использованием angular.json

Вы можете просмотреть схему, чтобы увидеть все доступные параметры конфигурации. Вы можете просмотреть более подробное описание на странице https://github.com/angular/angular-cli/wiki/angular-workspace.

"$schema": "./node_modules/@angular/cli/lib/config/schema.json",
  • $ schema: ссылается на указанный schema.json файл, используемый cli.
  • версия (целое число): версия формата файла. В настоящее время это «1».
  • newProjectRoot (строка): Путь, по которому будут созданы новые проекты.
  • проекты: список из project элементов.
  • defaultProject (строка): имя проекта по умолчанию, используемое в командах.
  • cli: параметры конфигурации рабочего пространства для Angular CLI.
  • schematics (объект): параметры конфигурации рабочего пространства для схем.
  • проекты: параметры конфигурации для каждого проекта в рабочей области.

Проект приложения

Когда создается новый проект типа application, в разделе projects в angular.json добавляется конфигурация для следующих элементов.

  • root: корень файлов проекта.
  • sourceRoot: корень исходных файлов, ресурсов и файловой структуры index.html.
  • projectType: перечисление для указания типа проекта: application, library
  • префикс: префикс, применяемый к сгенерированным селекторам.
  • schematics: параметры конфигурации проекта для схем. Имеет тот же формат, что и конфигурация схемы верхнего уровня).
  • архитектор: конфигурация проекта для целей Architect.
  • строить
  • обслуживать
  • экстракт-i18n
  • тестовое задание
  • ворсинок

Существует (2) типа проектов, которые разрешены схемой angular.json. Свойства projectType и root необходимы для элемента проектов. Значения enum показаны ниже.

Библиотечный проект

Когда создается новый проект типа library, в разделе projects в angular.json добавляется конфигурация для следующих элементов. Библиотеки используются и не обслуживаются, поэтому serve конфигурация архитектора отсутствует.

  • root: корень файлов проекта.
  • sourceRoot: корень исходных файлов, ресурсов и файловой структуры index.html.
  • projectType: перечисление для указания типа проекта: application, library
  • prefix: префикс, применяемый к сгенерированным селекторам.
  • архитектор: конфигурация проекта для целей Architect.
  • строить
  • тестовое задание
  • ворсинок

Создание элементов рабочего пространства

Я буду использовать интерфейс командной строки для создания дополнительных веб-приложений и новых библиотек в рабочей области. Мы будем использовать это приложение для использования наших библиотек.

Веб приложение

Создайте новое приложение (веб) под названием webOne. Для приложения будет создана новая папка проекта.

ng generate application webOne

Соберите приложение с помощью команды CLI:

ng build --project=webOne

Запустите приложение с помощью команды CLI:

ng serve webOne

Библиотека

Хорошей практикой является определение объема ваших библиотек, за которые вы несете ответственность. В этом примере я хотел бы, чтобы все библиотеки были ограничены с помощью @buildmotion. Это удобный способ организовать ваши библиотеки. Области видимости - это способ группировки связанных пакетов вместе. Я не уверен, насколько это практично для рабочего процесса разработки, когда библиотеки совместно используются приложениями, но не публикуются и не распространяются в NPM (для использования другими приложениями, не содержащимися в рабочей области).

Создайте новый проект библиотеки с именем @scope вместе с именем библиотеки. Это фактически создаст папку с именем buildmotion в projects с новой папкой библиотеки lib-one.

Пример: ng generate library @ SCOPE-NAME-HERE / LIBRARY-NAME-HERE

ng generate library @buildmotion/libOne

Имя пакета @buildmotion/lib-one - обратите внимание, что он также содержит имя области @buildmotion. namevalue в корне проекта package.json библиотеки содержит правильное значение, если вы хотите опубликовать пакет в NPM.

{
  "name": "@buildmotion/lib-one",
  "version": "0.0.1",
  "peerDependencies": {
    "@angular/common": "^6.0.0-rc.0 || ^6.0.0",
    "@angular/core": "^6.0.0-rc.0 || ^6.0.0"
  }
}

Вам нужно будет изменить имя проекта в файле angular.json, чтобы удалить область @buildmotion/. Значение имени @buildmotion/libOne содержит недопустимые символы, как определено схемой для angular.json.

"libOne": {
      "root": "projects/buildmotion/lib-one",
      "sourceRoot": "projects/buildmotion/lib-one/src",
      "projectType": "library",
      "prefix": "lib",
      ...
    }

Добавить услугу в библиотеку

Используйте интерфейс командной строки для создания службы в новой библиотеке. Мы хотим иметь возможность ссылаться на библиотеку и сервис, используя @buildmotion/libOne.

ng generate service hello  --project=libOne

Интересно, что схема, генерирующая новую библиотеку, также создает службу по умолчанию для каждой библиотеки. Предполагаете ли, что всем библиотекам требуется служба для работы в качестве API для модуля?

import { Injectable } from '@angular/core';
@Injectable({
  providedIn: 'root'
})
export class LibOneService {
  constructor() { }
}

Кроме того, схема также генерирует компонент по умолчанию для библиотеки. Я бы предпочел добавлять в свои библиотеки службы и компоненты по мере необходимости для желаемой реализации и цели библиотеки. Не все библиотеки будут нуждаться в / использовать службы и компоненты. Но это хорошее начало.

import { Component, OnInit } from '@angular/core';
@Component({
  selector: 'lib-libOne',
  template: `
    <p>
      lib-one works!
    </p>
  `,
  styles: []
})
export class LibOneComponent implements OnInit {
  constructor() { }
  ngOnInit() {
  }
}

Используйте библиотеку в приложении

Теперь, когда у нас есть некоторые компоненты и сервисы в нашей библиотеке, мы готовы использовать их в приложении. Я могу внедрить сервис в конструктор. Visual Studio Code создаст оператор импорта для компонента. Однако обратите внимание, что мы не используем @buildmotion/lib-one область видимости и имя библиотеки. Это неутешительно. Рабочее пространство NRWL.io Nx делает это по умолчанию. Не рекомендуется публиковать библиотеки со ссылками на пути к файлам / импортом - зависимость должна быть установлена ​​из NPM и не будет находиться в указанном пути к файлу.

import { LibOneService } from 'dist/@buildmotion/lib-one/public_api';

Я бы предпочел увидеть то, что ниже. Потому что контекст этого упражнения - публикация библиотек, которые могут использоваться другими приложениями. Потребителями вашей библиотеки могут не быть приложения в одной и той же рабочей области проекта. Если библиотеки публичные, это может быть другая команда или компания. Имейте в виду, что мы расширяем стандартное использование среды рабочего пространства Angular 6, чтобы позволить публиковать библиотеки для общего пользования. Возможно, вам это не понадобится.

import { LibOneService } from '@buildmotion/lib-one';

Однако мы получаем path ссылку на LibOneService. Обновите значение пути, чтобы использовать значение имени области: @buildmotion/lib-one. Мы предложим обходной путь, чтобы это произошло.

import { Component, OnInit } from '@angular/core';
import { LibOneService } from '@buildmotion/lib-one';
@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
  title = 'app';
  constructor(
    private oneService: LibOneService
  ) {
  }
  ngOnInit(): void {
    this.title = this.oneService.SayHello("Angular 6 Workspace");
  }
}

Импортировать справочное исправление

Обновите корневой tsconfig.json файл рабочей области, чтобы включить (2) новых элемента для каждой из наших библиотек. По сути, мы сообщаем компиляторам, где искать module, когда он импортирует @buildmotion/lib-one или @buildmotion/lib-two.

"paths": {
      "@buildmotion/lib-two":["dist/@buildmotion/lib-two"],
      "@buildmotion/lib-one":["dist/@buildmotion/lib-one"]
    }

Обратите внимание, что это папка dist. Это означает, что если вы хотите, чтобы приложения-потребители получали последние изменения в каком-либо библиотечном проекте, вам нужно будет собрать библиотеки. Для этого я создал новый элемент script в файле package.json рабочей области.

"package": "ng build --project=libTwo && ng build --project=libOne",

Выполните сценарий для сборки и вывода библиотек в папку dist - готовые к использованию. Хотя это дополнительный шаг, он намного эффективнее, чем процесс публикации, когда это отдельные проекты. Установите приоритет порядка на основе зависимостей библиотек. В нашем примере libOne зависит от libTwo. Следовательно, libTwo компилируется до libOne. Понятно?

npm run package

Однако, если вы публикуете одну или несколько своих пользовательских библиотек в NPM, и одна из них имеет зависимость от существующей библиотеки в той же области (например, @buildmotion), ей потребуется зависимость, определенная с помощью операторов импорта, которые используют правильную область видимости. и название пакета. Это будет иметь место, когда вы публикуете группы пакетов с одним и тем же именем области.

ng generate library @buildmotion/libTwo

Теперь вы можете создать новую библиотеку в рабочей области, указав имя библиотеки с помощью переключателя --project.

ng build --project=libTwo

Мы изменим метод SayHello в LibOneService, чтобы использовать и вызвать метод LibTwoService.

SayHello(message: string): string {
if(message) {
    this.libTwoService.SayHello(message);
}
return 'Next time send in a message.';
}

Реализуйте метод SayHello в службе. Эта служба используется другой библиотекой / модулем. Это нужно поддерживать, правда?

import { Injectable } from '@angular/core';
@Injectable({
  providedIn: 'root'
})
export class LibTwoService {

  constructor() { }
  SayHello(message: any): any {
   return `Hello ${message}.`;
  }
}

Создайте новые библиотеки. Вы должны увидеть результат в папке dist в папке @buildmotion.

npm run package

Библиотечные одноранговые зависимости

Если вы собираетесь публиковать свои библиотеки, созданные в рабочем пространстве Angular 6, вам нужно будет обновить peerDependencies в package.json файле библиотеки. Это то, что публикуется в NPM. Когда потребители вашей библиотеки устанавливают пакет, peerDependencies указывается разработчику для ручной установки.

Мы должны иметь возможность использовать библиотеку, которая потребляет другую библиотеку из webOne приложения.

ng serve --project=webOne

Заключение

Новое рабочее пространство Angular 6 действительно задумано как усовершенствованный рабочий процесс разработчика, позволяющий более эффективно разрабатывать несколько приложений и библиотек вместе. Он не предназначен для публикации библиотек для общего пользования.

  • Среда рабочей области поддерживает совместное использование нескольких библиотек несколькими приложениями-потребителями.
  • Он ориентирован на приложение в процессе сборки. По умолчанию сборка и вывод библиотек не производится.
  • Похоже, что среда рабочей области не поддерживает имена и ссылки @scope от потребителей библиотек.
  • Возможно, это не лучший выбор для разработки библиотек, основным назначением которых является репозиторий диспетчера пакетов (подумайте о NPM).
  • По умолчанию application создается в корневой src папке при создании нового рабочего пространства.

Если вы хотите воспользоваться преимуществами среды рабочего пространства, которая обеспечивает расширенную конфигурацию проектов и зависимостей, а также полную поддержку для публикаций библиотек; Я бы посоветовал использовать расширения NRWL.io Nx версий 1.0 или 6.0. Если вы не публикуете свои библиотеки для общего пользования, вам следует использовать среду рабочего пространства Angular или NRWL. Обе среды предоставляют отличные возможности для организации вашего кода с помощью модулей, и это хорошо!

Я публикую новую книгу по угловой архитектуре. Узнайте, как использовать преимущества библиотечных проектов для создания лучших архитектур путем организации и повторного использования вашего кода. Доступно на Leanpub.com.