TL;DR В этом руководстве мы изучим основы инструмента Nrwl Nx, а также узнаем, как создать настраиваемую схему командной строки рабочей области. Вы можете увидеть готовый код в этом репозитории.

Примечание. В этом руководстве требуются базовые знания Angular и интерфейса командной строки Angular. Если вы никогда раньше не работали с Angular, ознакомьтесь с нашей серией Real World Angular.

Проблемы корпоративных команд

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

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

  • Согласованность. Как убедиться, что все в организации (а это могут быть тысячи человек) следуют одним и тем же передовым методам структурирования и написания кода?
  • Безопасность — как мы гарантируем, что наш код не будет подвергаться атакам или подвержен ошибкам?
  • Увеличение размера и сложности — как мы можем структурировать наш код, чтобы он мог расти, не жертвуя ясностью или производительностью?
  • Изменение требований — как мы можем идти в ногу с потребностями бизнеса, чтобы постоянно обновлять приложение, не позволяя техническому долгу выйти из-под контроля?

Хотя небольшие команды и небольшие организации в некоторой степени разделяют эти же проблемы, риски могут быть катастрофическими в масштабах предприятия. Чтобы узнать больше о проблемах, с которыми сталкиваются большие команды, ознакомьтесь с отличным выступлением Виктора Савкина на ng-conf 2018 Angular в больших организациях.

Посетите блог Auth0 🔐 и найдите все, что вам нужно знать об инфраструктуре идентификации, JavaScript, технологиях внешнего интерфейса, аутентификации JWT и последних новостях в Angular. 👉 AUTH0 БЛОГ👈

Nx: корпоративный набор инструментов для Angular

"Источник"

Nx — это набор инструментов для Angular CLI, созданный консалтинговой фирмой Nrwl, чтобы помочь решить именно эти вопросы согласованности, безопасности и ремонтопригодности. В дополнение к включенной схеме для реализации разработки приложений и библиотек в стиле монорепозитория, Nx включает набор библиотек, линтеров и генераторов кода, которые помогают большим командам создавать и внедрять лучшие практики в своих организациях.

«Nx от @nrwl — это набор инструментов, помогающих корпоративным разработчикам @angular обеспечить согласованность, безопасность и удобство сопровождения.»

ОТПРАВИТЬ ЭТО В Твиттер

По умолчанию Nx содержит инструменты, помогающие:

  • Управление состоянием и NgRx
  • Сохранение данных
  • Линтинг и форматирование кода
  • Переход с AngularJS на Angular
  • Визуальный анализ зависимостей
  • Создание и запуск более качественных тестов
  • Создание схем для конкретных рабочих мест

Хотя мы не можем углубляться во все функции Nx, мы собираемся немного взглянуть на последнюю: схемы для конкретных рабочих мест. Прежде чем мы это сделаем, давайте узнаем, как начать работу с Nx.

Основы Nx

Давайте изучим основы подготовки и работы с Nx. Нам нужно знать, как установить Nx, как создать рабочее пространство и как создавать приложения и библиотеки.

Установить Nx

Мы начнем с установки Nx, который на самом деле представляет собой просто набор схем Angular CLI. Для этого вам понадобится Node 8.9 или выше и NPM 5.5.1 или выше, которые вы можете установить с веб-сайта Node.

Во-первых, убедитесь, что у вас глобально установлена ​​последняя версия Angular CLI:

npm i -g @angular/cli

(Обратите внимание, что npm i -g — это просто сокращение от npm install --global.)

Затем установите Nx глобально:

npm i -g @nrwl/schematics

Глобальная установка Nx на самом деле требуется только для создания рабочих областей с нуля из командной строки. Если вы не можете установить что-то глобально на работе, не волнуйтесь. Вы можете добавить возможности Nx в существующий проект CLI, выполнив эту команду:

ng add @nrwl/schematics

Примечание. В этом руководстве вы также можете использовать Angular Console вместо CLI, если предпочитаете работать с графическим интерфейсом, а не с командной строкой.

Создать рабочее пространство

Теперь, когда у нас установлен Nx, мы готовы создать наше первое рабочее пространство. Что же такое рабочее пространство? Рабочая область — это пример monorepo (сокращение от monorepo) — репозитория, который содержит несколько связанных приложений и библиотек.

Давайте представим, что нам поручили создать систему усыновления домашних животных. Давайте подумаем о некоторых различных частях, которые могут нам понадобиться для этого:

  • Интерфейсное приложение для потенциальных усыновителей для просмотра домашних животных.
  • Интерфейсное приложение для администраторов, позволяющее обновлять информацию о доступных питомцах и получать запросы.
  • Общие компоненты пользовательского интерфейса между внешними интерфейсами
  • Общие библиотеки доступа к данным между внешними интерфейсами
  • Сервер Node для обслуживания данных запросов о домашних животных и усыновлениях.

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

В Nx рабочее пространство представляет собой монорепозиторий для Angular CLI, чтобы ваши приложения и библиотеки были организованы.

После глобальной установки Nx мы можем запустить эту команду:

create-nx-workspace pet-adoption-system

Когда мы запустим эту команду с версией 7 или более поздней версии CLI и Nx, мы получим два вопроса с подсказками. Во-первых, хотим ли мы использовать отдельное имя для области npm, что позволяет нам импортировать внутри с помощью сокращения. Например, мы могли бы установить область действия «adoption-suite», что означало бы, что наш импорт будет начинаться с @adoption-suite. Мы не будем делать это в этом уроке, поэтому мы можем просто нажать Enter, чтобы оставить значение по умолчанию, то есть pet-adoption-system.

Вторая подсказка — хотим ли мы использовать npm или Yarn для управления пакетами. В этом уроке я буду использовать npm, но вместо этого вы можете использовать Yarn.

Это создаст новое рабочее пространство CLI, которое будет немного отличаться от того, к чему вы привыкли. Вместо обычной папки src вы увидите папки с именами apps, libs и tools в корне проекта. Вы также увидите некоторые дополнительные файлы, такие как nx.json для настройки Nx, .prettierrc для настройки расширения форматирования Prettier и .editorconfig для установки некоторых пресетов редактора. Nx выполняет множество настроек за вас, поэтому вы можете сосредоточиться на написании кода, а не на инструментах.

Создать приложение

Давайте создадим приложение в нашей новой рабочей области и добавим в него маршрутизацию.

ng generate app adoption-ui --routing

В версии 7 Nx добавлены подсказки относительно размещения каталогов, расширения стиля и выбора исполнителей модульных и сквозных тестов. Это здорово, потому что теперь мы можем легко настроить приложение, используя SCSS, Jest для модульного тестирования и Cypress для сквозного тестирования без дополнительной работы. В этом руководстве не стесняйтесь оставлять все подсказки по умолчанию. Мы не будем использовать их здесь.

Схема Nx app почти идентична встроенной версии CLI, но имеет пару отличий. Например, добавленная нами опция routing настраивает корневой каталог NgModule с маршрутизацией вместо создания отдельного модуля. Это все чаще становится передовой практикой в ​​сообществе Angular, чтобы избежать «загрязнения модулей», поэтому очень приятно, что Nx делает это для нас по умолчанию.

После того, как мы запустим команду, у нас появится папка apps/adoption-ui со знакомой структурой CLI внутри. Обратите внимание, что AppModule настроен с маршрутизацией и что для Protractor есть отдельная папка apps/adoption-ui-e2e. Это немного отличается от обычной настройки CLI, где папка e2e находится внутри папки приложения.

Создать библиотеку

Библиотеки — идеальные места для размещения таких вещей, как компоненты пользовательского интерфейса или службы доступа к данным для использования в нескольких приложениях.

Мы можем добавить новые библиотеки в рабочее пространство Nx с помощью команды AngularCLI generate, точно так же, как добавление нового приложения. У Nx есть схема с именем lib, которую можно использовать для добавления новой библиотеки модулей Angular в нашу рабочую область:

ng generate lib shared-components

Мы получим несколько подсказок в командной строке относительно инструментов, тестирования, настройки и маршрутизации. Поскольку на самом деле мы не собираемся использовать эту библиотеку, ответы на эти вопросы не имеют значения — продолжайте и просто примите все значения по умолчанию. Тем не менее, полезно знать, насколько легко настраиваются библиотеки из командной строки, от маршрутизации и отложенной загрузки до инструментов и настройки.

Выполнение этой команды создаст libs/shared-components со своей собственной папкой src и файлами конфигурации.

Мы можем легко добавить компоненты в эту библиотеку, передав параметр project в CLI. Давайте воспользуемся ярлыком g для generate и ярлыком c component и выполним следующую команду:

ng g c pet-list --export=true --project=shared-components

Поскольку это общая библиотека, я добавил export=true для экспорта компонента из файла NgModule.

Теперь, когда мы знаем основы Nx, давайте рассмотрим одну из его менее известных, но невероятно мощных функций: возможность создавать собственные схемы рабочего пространства.

Создание пользовательской схемы аутентификации

На самом деле вы уже знакомы со схемами — это то, что Angular CLI использует для создания новых компонентов, сервисов и многого другого, когда вы запускаете команду ng generate. Вы также можете написать свои собственные схемы с нуля, независимо от того, используете ли вы Nx или нет. Однако прелесть Nx в том, что он выполняет всю тяжелую работу по подключению ваших пользовательских схем, чтобы их было легко запускать в вашем рабочем пространстве.

Пользовательские схемы часто используются для двух основных целей:

  1. Для обеспечения соблюдения стилей или стандартов в вашей организации.
  2. Для создания пользовательского кода, характерного для вашей организации.

«Пользовательские схемы интерфейса командной строки @angular используются для обеспечения соблюдения стилей или стандартов и для создания пользовательского кода.»

ОТПРАВИТЬ ЭТО В Твиттер

В этом руководстве мы сосредоточимся на первом, поскольку для создания пользовательского кода с помощью API схем требуется некоторое знание абстрактного синтаксического дерева TypeScript, и это немного выходит за рамки нашего руководства в этом руководстве.

Некоторые примеры хороших идей для пользовательских схем, которые обеспечивают соблюдение стилей или стандартов:

  • Применение структуры каталогов или архитектуры приложений.
  • Применение шаблонов для доступа к данным, таких как NgRx.

Поскольку аутентификация является предметом нашего сердца здесь, в Auth0, давайте создадим схему, которую разработчики будут использовать при добавлении модуля аутентификации в свои приложения. Мы хотели бы, чтобы он делал четыре вещи:

  1. Придерживайтесь соглашения об именовании файлов с префиксом «auth-».
  2. Создайте модуль аутентификации и импортируйте его в файл проекта AppModule.
  3. Создайте пустой сервис, который будет содержать наш код аутентификации.
  4. Создайте пустую защиту CanActivate, которая будет содержать защиту маршрута аутентификации.

Мы можем выполнить все это в одной схеме, которая примет имя модуля и проект, в который мы его добавляем, в качестве аргументов. Это позволит нашим разработчикам, работающим над системой усыновления домашних животных, быстро добавить правильную основу для любого приложения, которое они создают в рамках проекта.

Давайте начнем!

Создайте пользовательскую схему

Первым шагом к созданию пользовательской схемы является использование Nx для генерации исходного кода. Мы можем сделать это, выполнив эту команду:

ng g workspace-schematic auth-module

(Обратите внимание, что я снова использовал ярлык g для generate.)

Схема workspace-schematic (я знаю, она такая мета) создает папку auth-module внутри tools/schematics. Эта новая папка содержит два файла: schema.json и index.ts.

Обновите схему

Schema.json содержит метаданные для нашей пользовательской схемы, такие как используемые с ней параметры. Если мы откроем его, мы увидим этот код по умолчанию:

// tools/schematics/auth-module/schema.json { "$schema": "http://json-schema.org/schema", "id": "auth-module", "type": "object", "properties": { "name": { "type": "string", "description": "Library name", "$default": { "$source": "argv", "index": 0 } } }, "required": ["name"] }

По умолчанию мы можем передать свойство name, которое является string, нашей схеме. Параметр $default говорит нам, что предполагается, что первый аргумент, переданный этой команде, является значением свойства name. Не стесняйтесь изменить описание свойства name на что-то более конкретное, например, «Имя модуля аутентификации».

Давайте также добавим в этот файл еще одно свойство, чтобы указать проект, в который мы добавим наш новый модуль аутентификации. Под свойством name добавьте следующее:

// tools/schematics/auth-module/schema.json // ...above code remains the same // add under the name property: "project": { "type": "string", "description": "Project to add the auth module to" } // ...below code remains the same

Давайте также сделаем его обязательным, добавив его в массив required. Готовый файл будет выглядеть так:

// tools/schematics/auth-module/schema.json { "$schema": "http://json-schema.org/schema", "id": "auth-module", "type": "object", "properties": { "name": { "type": "string", "description": "Auth module name", "$default": { "$source": "argv", "index": 0 } }, "project": { "type": "string", "description": "Project to add the auth module to" } }, "required": ["name", "project"] }

Мы могли бы добавить сюда любые другие опции с их типами, если бы они нам были нужны. Например, если вы посмотрите на schema.json официальную схему компонентов, вы увидите знакомые параметры boolean, такие как spec и inlineTemplate.

Напишите пользовательскую схему

Теперь мы готовы написать пользовательскую реализацию схемы. Он живет в сгенерированном файле index.ts. Давайте откроем его и начнем создавать нашу схему auth-module. Мы увидим следующий код, сгенерированный Nx:

// tools/schematics/auth-module/index.ts import { chain, externalSchematic, Rule } from '@angular-devkit/schematics'; export default function(schema: any): Rule { return chain([ externalSchematic('@nrwl/schematics', 'lib', { name: schema.name }) ]); }

Давайте разберем, что здесь происходит, чтобы мы могли отталкиваться от этого.

Во-первых, мы импортируем функции chain и externalSchematic, а также тип Rule из @angular-devkit/schematics. Затем мы используем весь этот импорт в экспортируемой функции. Но что это за вещи?

Мы часто говорим, что схемы подобны чертежам, когда вы строите дом. В этой аналогии Rule — это страница или раздел чертежа. Правила — это отдельные части схемы, которые сообщают интерфейсу командной строки, как модифицировать файловую систему, представленную как Tree на схемах. Деревья позволяют нам изменять файловую систему путем создания, обновления и удаления файлов. Как правило, все, что мы можем сделать с файловой системой, мы можем сделать и с деревом. Однако, в отличие от файловой системы, деревья используют транзакционную структуру. Никакие изменения в фактическую файловую систему не вносятся до тех пор, пока вся схема не запустится. Если часть схемы дает сбой, любые изменения в файловой системе откатываются.

Таким образом, правила — это функции, которые принимают текущее дерево и возвращают либо модифицированное дерево, либо другое правило. Это означает, что правила также могут быть составными. Мы можем комбинировать правила с помощью функции chain, как в этом примере. Есть и другие операторы, например branchAndMerge и mergeWith. Вы увидите эти функции в официальном коде схем CLI.

Мы также можем использовать здесь функцию externalSchematic, чтобы обратиться к внешней схеме и составить ее правила на нашей пользовательской схеме. В шаблоне, сгенерированном Nx, мы начинаем с правила, которое просто запускает схему lib, встроенную в Nx, которая находится в коллекции @nrwl/schematics.

Сердцем схемы является экспортируемая функция:

// tools/schematics/auth-module/index.ts export default function(schema: any): Rule { return chain([ externalSchematic('@nrwl/schematics', 'lib', { name: schema.name }) ]); }

Эта функция принимает schema и возвращает Rule. schema должен соответствовать структуре schema.json. По сути, все схемы — это просто функции, которые возвращают правила, изменяющие файловую систему. Вы часто будете видеть множество правил, определенных в схеме, а также вспомогательные функции, но в итоге экспортируется только одна функция. Эта функция будет иметь все необходимые правила, связанные в цепочку, разветвленные или объединенные вместе.

Самая простая из возможных пользовательских схем — это та, которая использует преимущества объединения существующих правил. Это особенно полезно в крупных организациях для внедрения передового опыта и шаблонов архитектуры. Например, вы можете захотеть, чтобы каждый в команде всегда создавал компоненты со встроенными стилями и с сопутствующей моделью в качестве интерфейса TypeScript. Вы можете легко соединить схему component со схемой interface, чтобы всем в организации было легко это сделать.

Мы собираемся следовать аналогичной схеме здесь. Мы хотим, чтобы каждый, кто добавляет аутентификацию в проект, всегда добавлял отдельный модуль, сервис и CanActivate гвардию. Для этого мы воспользуемся нашими новыми инструментами — функциями chain и externalSchematic.

Давайте сначала заменим Nx lib вызовом схемы module, сохранив ее внутри массива, передаваемого в функцию chain:

// tools/schematics/auth-module/index.ts // ...above code remains the same // replace nx lib with this: externalSchematic('@schematics/angular', 'module', { project: schema.project, name: schema.name, routing: true, module: 'app.module.ts' })

Обратите внимание, что мы сначала передаем коллекцию (@schematics/angular), затем имя схемы (module), а затем объект опций. Объект параметров содержит значения для любых параметров внешней схемы. Мы передаем проект, имя и имя корневого модуля app.module.ts. Мы также устанавливаем флаг routing на true, чтобы добавить маршрутизацию в модуль аутентификации. Это упрощает добавление маршрутов в модуль аутентификации, таких как маршрут callback или маршруты для входа и выхода.

Для вызовов схем service и guard нам нужно импортировать path вверху нашего файла:

// tools/schematics/auth-module/index.ts // ...previous imports import * as path from 'path';

Это позволит нам указывать пути к файлам независимо от того, использует ли пользователь операционную систему на базе Windows или Linux. Добавьте следующее в массив после схемы module (не забудьте запятую!):

// tools/schematics/auth-module/index.ts // ...above code remains the same externalSchematic('@schematics/angular', 'service', { project: schema.project, name: schema.name, path: path.join( 'apps', schema.project, 'src', 'app', schema.name, 'services' ) }) // ...end of the array and chain function

Когда мы запустим эту схему, она сгенерирует наш сервис внутри apps/{project}/src/app/{schema}/services. Вы можете легко изменить это на другую структуру, если хотите. Вы заметили, как легко эти схемы упрощают стандартизацию и организацию кода?

Наш последний вызов — схема guard, и она почти идентична. Добавьте это после схемы service (и снова не забудьте запятую!):

// tools/schematics/auth-module/index.ts // ...above code remains the same externalSchematic('@schematics/angular', 'guard', { project: schema.project, name: schema.name, path: path.join( 'apps', schema.project, 'src', 'app', schema.name, 'services' ) }) // ...end of the array and chain function

Это создаст защиту в том же месте, что и служба аутентификации.

Наша схема почти готова. Он создаст модуль, сервис и защиту с именем, которое мы ему дадим, и для проекта, который мы укажем. Давайте добавим последний штрих: давайте выдадим ошибку, если пользователь не поставит перед своим новым модулем аутентификации префикс auth-.

Для этого мы можем добавить следующий оператор if внутрь нашей функции в строке 5 непосредственно перед тем, как мы вернем нашу цепочку правил:

// tools/schematics/auth-module/index.ts // ...above code remains the same // add above the returned chain function: if (!schema.name.startsWith('auth-')) { throw new Error(`Auth modules must be prefixed with 'auth-'`); } // ...below code remains the same

Теперь мы увидим ошибку, если не будем придерживаться рекомендаций по именованию. Аккуратный!

Готовый код для нашей пользовательской схемы выглядит так:

import { chain, externalSchematic, Rule } from '@angular-devkit/schematics'; import * as path from 'path'; export default function(schema: any): Rule { if (!schema.name.startsWith('auth-')) { throw new Error(`Auth modules must be prefixed with 'auth-'`); } return chain([ externalSchematic('@schematics/angular', 'module', { project: schema.project, name: schema.name, routing: true, module: 'app.module.ts' }), externalSchematic('@schematics/angular', 'service', { project: schema.project, name: schema.name, path: path.join( 'apps', schema.project, 'src', 'app', schema.name, 'services' ) }), externalSchematic('@schematics/angular', 'guard', { project: schema.project, name: schema.name, path: path.join( 'apps', schema.project, 'src', 'app', schema.name, 'services' ) }) ]); }

Помните, что с помощью этой схемы мы только создаем основу для нашей настройки аутентификации. Чтобы узнать, как правильно реализовать аутентификацию в вашем сервисе и защите, ознакомьтесь с нашим Руководством по аутентификации Angular. У нас также есть Руководство по аутентификации NgRx для вас, если вы используете преимущества NgRx в своем проекте. Чтобы использовать любое из этих руководств для настройки Auth0 в вашем приложении, сначала зарегистрируйте бесплатную учетную запись Auth0 здесь.

Запустите пользовательскую схему

Теперь, когда мы написали схему, давайте проверим ее. Nx уже выполнил работу по подключению его для использования в нашем рабочем пространстве, поэтому нам не нужно об этом беспокоиться. Чтобы запустить нашу новую схему auth-module, выполните следующую команду:

npm run workspace-schematic -- auth-module auth-adoption --project=adoption-ui

Эта команда запускает скрипт workspace-schematic, который является частью Nx. Мы используем оператор -- для передачи параметров в этот сценарий, таких как имена модуля и проекта. (Если вы используете Yarn, вы можете отказаться от оператора -- и запустить yarn workspace-schematic auth-module с остальными параметрами.)

После запуска схемы мы увидим результирующие файлы в папке src приложения adoption-ui. Там будет наш модуль auth-adoption и его модуль роутинга, а также папка services, содержащая сервис auth-adoption и защиту маршрута.

Не забудьте также проверить наше требование к именованию. Попробуйте запустить команду еще раз, но без префикса auth-. Вы должны увидеть Auth modules must be prefixed with 'auth-' как ошибку в своей консоли. Вы также увидите ошибку, если не укажете имя проекта.

Весь готовый код можно найти в этом репозитории.

Вывод

Наша настраиваемая схема аутентификации позволяет добиться многого с помощью менее чем 50 строк кода:

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

Поскольку написание пользовательских схем в первый раз может быть сложной задачей, Nx помогает выполнять большую часть тяжелой работы. Это действительно то, что Nx делает лучше всего: автоматизация и упрощение разработки на Angular в любом масштабе.

Чтобы узнать больше о пользовательских схемах, ознакомьтесь с Введением в блоге Angular, этим замечательным руководством по Генерированию пользовательского кода от Manfred Steyer и этой презентацией о пользовательских схемах от Brian Love. И, конечно же, лучшее место, где можно увидеть примеры пользовательских схем, — это исходный код схем Angular.

На самом деле мы только коснулись того, что может сделать Nx. Чтобы узнать больше о Nx, включая такие функции, как визуальный график зависимостей, ограничения зависимостей и возможность запускать только затронутые тесты, ознакомьтесь с официальной документацией по Nx, репозиторием nx-examples и этим бесплатным видеокурсом по Nx Джастина Шварценбергера.

Особая благодарность Jason Jean из Nrwl за то, что он вместе со мной попарно запрограммировал и ответил на мои вопросы о Nx и пользовательских схемах. Спасибо, Джейсон!

Первоначально опубликовано на auth0.com.