Pull to refresh

Строгие правила для нового приложения на Angular

Reading time8 min
Views9.8K

Как создать и настроить Angular проект с нуля


Статья была обновлена 29 Февраля 2020 чтобы следовать лучшим практикам.


Короткое вступление


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


Подготовка окружения для разработки


Git


Первое что должно быть установлено на любом окружении для разработки это Git. Скачайте и установите Git на свою операционную систему.


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


// Для глобальной настройки (для всех проектов) используйте команды
$ git config --global user.name "John Doe"
$ git config --global user.email johndoe@example.com

// Для настройки конкретного проект перейдите в папку с проектом и выполните
$ git config user.name "John Doe"
$ git config user.email johndoe@example.com

NodeJs и NVM


Следующее что нужно настроить для работы с Angular это NodeJs. Лучший подход на данный момент это установить NodeJs с помощью Node Version Manager. Это даст возможность легко переключаться на любую версию и даже делать это автоматически для каждого проекта.


  1. На MacOs перед установкой необходимо создать файл .zshrc в домашней директории.

$ touch ~/.zshrc

  1. Выполните инструкции для установки или обновления NVM.


  2. Установите последнюю LTS версию NodeJs.



$ nvm install 'lts/*'

  1. Установите ее как default.

$ nvm use 'lts/*'
$ nvm alias default 'lts/*'

  1. Для автоматического переключения версии nodejs при переходе в проект на версиюуказанную в файле .nvmrc выполните эти инструкции.

Установка CLI и создание проекта


  1. Установите CLI используя менеджер пакетов npm.

$ npm install -g @angular/cli

  1. Перейдите в папку со своим проектом и создайте пустой Angular проект

$ cd ~/Projects
$ ng new --create-application false --new-project-root apps project-name

Мы создали пустой проект с настроенной директорией apps для новых приложений. Другими словами мы подготовили основу для монорепозитория.


  1. Создайте и сделайте коммит первого приложения в монорепозитории.

$ cd project-name
$ ng generate application --routing true --style scss website
$ git add .
$ git commit -m 'website application created'

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


Создание библиотек


Я обычно советую создавать библиотеки в папке libs. Для этого нам необходимо изменить одну строку в angular.json файле:


"newProjectRoot": "apps",

На следующую строку:


"newProjectRoot": "libs",

И выполнить команду:


$ ng generate library @group-name/lib-name

Мы добавили group-name для более наглядной группировки библиотек по домену или какому то другому принципу. Также если вы захотите опубликовать библиотеку например в npm, сначала необходимо создать организацию тут с названием соответствующим group-name. Это как namespace для группы связанных библиотек, например:


"@angular/common"
"@angular/compiler"
"@angular/core"
"@angular/forms"

Я более подробно опишу процесс публикации библиотек в npm в будущих статьях. А пока просто следуйте этому правилу.


И не забудьте вернуть angular.json к прежнему состоянию: "newProjectRoot": "apps"


Также я обычно советую не использовать defaultProject из angular.json, дальше в статье я покажу как настроить скрипты на конкретный проект, поэтому давайте пока установим эту настройку в пустое значение:


"defaultProject": ""

Дополнительная конфигурация


NodeJs version


Добавьте .nvmrc файл с текстом lts/* в нем. Так же можно указать конкретную версию node, например 12.16.1. Эта версия будет автоматически установлена если вы следовали моим предыдущим инструкциям. Также можно активировать эту версию вручную с помощью команды $ nvm use.


$ touch .nvmrc
$ echo "lts/*" > .nvmrc

Строгие проверки на null и undefined


Добавьте следующее правило в tsconfig.json чтоб включить строгую проверку на null и undefined. Это защитит вас от распространённой ошибки чтения свойства у undefined или null переменной.


"compilerOptions": {
    "strictNullChecks": true,
}

Или лучше, если вы хотите больше строгих проверок включите все правила в компиляторе:


/* Strict Type-Checking Options */
    "strict": true,                           /* Enable all strict type-checking options. */
    // "noImplicitAny": true,                 /* Raise error on expressions and declarations with an implied 'any' type. */
    // "strictNullChecks": true,              /* Enable strict null checks. */
    // "strictFunctionTypes": true,           /* Enable strict checking of function types. */
    // "strictBindCallApply": true,           /* Enable strict 'bind', 'call', and 'apply' methods on functions. */
    "strictPropertyInitialization": false,    /* Enable strict checking of property initialization in classes. */
    // "noImplicitThis": true,                /* Raise error on 'this' expressions with an implied 'any' type. */
    // "alwaysStrict": true,                  /* Parse in strict mode and emit "use strict" for each source file. */

    /* Additional Checks */
    "noUnusedLocals": true,                   /* Report errors on unused locals. */
    "noUnusedParameters": true,               /* Report errors on unused parameters. */
    "noImplicitReturns": true,                /* Report error when not all code paths in function return a value. */
    "noFallthroughCasesInSwitch": true,       /* Report errors for fallthrough cases in switch statement. */

Строгие правила TsLint


Включите все tslint правила на самые строгие настройки, для этого просто замените в tslint.json


"extends": "tslint:recommended",

На


"extends": "tslint:all",

И добавьте следующие правила чтобы отключить некоторые лишние правила


"no-use-before-declare": false,
"file-name-casing": [
  true,
  "kebab-case"
],
"no-implicit-dependencies": false,
"comment-format": [
  true,
  "check-space"
],
"newline-per-chained-call": false,
"no-object-literal-type-assertion": [
  true,
  {
    "allow-arguments": true
  }
],
"no-floating-promises": false,
"promise-function-async": false,
"completed-docs": false,
"prefer-function-over-method": false,
"no-submodule-imports": false,
"no-unsafe-any": false,
"no-inferrable-types": false,
"typedef": [
  true,
  "call-signature",
  "arrow-call-signature",
  "parameter",
  "arrow-parameter",
  "property-declaration",
  "variable-declaration",
  "variable-declaration-ignore-function",
  "member-variable-declaration",
  "object-destructuring",
  "array-destructuring"
],
"no-null-keyword": false,
"no-parameter-properties": false,
"variable-name": {
  "options": [
    "ban-keywords",
    "check-format",
    "allow-leading-underscore",
    "require-const-for-all-caps"
  ]
},
"max-line-length": false,
"increment-decrement": [true, "allow-post"],
"object-literal-key-quotes": false,
"align": [
  true,
  "parameters",
  "statements",
  "members"
],

В процессе разработки отключайте или настраивайте те правила которые вам не нравятся. И не забудьте включить поддержку tslint в своей IDE.


Lint SCSS с помощью stylelint


Добавьте stylelint для проверки качества вашего sсss кода


$ npm install -D stylelint stylelint-config-sass-guidelines
$ touch .stylelintrc.json

И настройте правила в .stylelintrc.json


{
  "extends": "stylelint-config-sass-guidelines",
  "ignoreFiles": [
    "dist/**/*"
  ],
  "rules": {
    "no-empty-source": true
  }
}

В процессе разработки отключите или настройте те правила которые вас не устраивают. И не забудьте включить поддержку stylelint в своей IDE


Prettier


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


$ npm install --save-dev --save-exact prettier
$ touch .prettierrc
$ touch .prettierignore

Добавьте настройки в файл .prettierrc


{
  "printWidth": 120,
  "tabWidth": 2,
  "arrowParens": "always",
  "bracketSpacing": true,
  "endOfLine": "lf",
  "semi": true,
  "singleQuote": true,
  "quoteProps": "consistent",
  "trailingComma": "all"
}

И в файл .prettierignore с игнорируемыми файлами и папками


test.ts

E2E


Для запуска тестов в headless режиме нудно выполнить следующее:


  1. В конфиге Karma (apps/website/karma.conf.js) добавить кастомный лаунчер ChromeHeadlessCI под браузерами

browsers: ['Chrome'],
customLaunchers: {
  ChromeHeadlessCI: {
    base: 'ChromeHeadless',
    flags: ['--no-sandbox']
  }
},

  1. В корневой папке вашего e2e проекта создайте файл apps/website/e2e/protractor-ci.conf.js этот файл будет наследовать оригинальный apps/website/e2e/protractor.conf.js.

const config = require('./protractor.conf').config;

config.capabilities = {
  browserName: 'chrome',
  chromeOptions: {
    args: ['--headless', '--no-sandbox']
  }
};

exports.config = config;

HOOKS


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


  • husky — устанавливает хуки
  • lint-staged — запускает команды только для подготовленных (staged) файлов

$ npm i -D husky lint-staged

Для настройки lint-staged просто добавьте следующие строки в package.json


"lint-staged": {
  "{apps,libs}/**/*.{ts,scss,html}": [
    "prettier --write"
  ],
  "{apps,libs}/**/*.scss": [
    "stylelint --fix"
  ]
},

Следующий шаг написать скрипты для наших хуков. Я предпочитаю создать папку tools для shell скриптов. Мы настроим 3 хука:


  1. pre-commit — Хук который выполняется перед коммитом. В этом хуке будем выполнять prettier на измененных файлах и линтеры.
  2. commit-msg — Хук в котором можно изменить текст коммита, мы используем его для того чтоб добавить имя ветки к тексту коммита.
  3. pre-push — Хук который выполняется перед git push. Используем его для запуска тестов и e2e.

Конфигурация Husky в package.json:


"husky": {
  "hooks": {
    "pre-commit": "npm run pre-commit",
    "commit-msg": "node ./tools/commit-msg.js",
    "pre-push": "npm run pre-push"
  }
},

Script ./tools/pre-commit.sh


#!/bin/sh

npx lint-staged || exit
npm run lint:website || exit

Скрипт ./tools/commit-msg.js


#!/usr/bin/env node

const fs = require('fs');
const { execSync } = require('child_process');

const message = fs.readFileSync(process.env.HUSKY_GIT_PARAMS, 'utf8').trim();
const currentBranch = getCurrentBranch();

fs.writeFileSync(process.env.HUSKY_GIT_PARAMS, `${currentBranch}: ${message}`);
process.exit(0);

function getCurrentBranch() {
  const branches = execSync('git branch', { encoding: 'utf8' });
  return branches
    .split('\n')
    .find((b) => b.charAt(0) === '*')
    .trim()
    .substring(2);
}

Скрипт ./tools/pre-push.sh


#!/bin/sh

npm run test-ci:website || exit
npm run e2e-ci:website || exit

Нужно задать правильные права на файлы


$ chmod 755 ./tools/pre-commit.sh
$ chmod 755 ./tools/commit-msg.js
$ chmod 755 ./tools/pre-push.sh

И в завершение замените scripts в package.json для удобного запуска комманд


"scripts": {
  "------------------ website ------------------": "",
  "start:website": "ng serve website --port 4200",
  "build:website": "ng build website --configuration production",
  "lint:website": "ng lint website --fix",
  "lint-scss:website": "stylelint --formatter verbose --fix \"apps/website/**/*.scss\"",
  "test:website": "ng test website --code-coverage --no-watch",
  "test-watch:website": "ng test website",
  "test-ci:website": "ng test website --no-watch --no-progress --browsers=ChromeHeadlessCI",
  "e2e:website": "ng e2e website --port 6200",
  "e2e-ci:website": "ng e2e website --port 6200 --protractor-config=apps/website/e2e/protractor-ci.conf.js",
  "------------------ common ------------------": "",
  "prettier": "prettier --write \"{apps,libs}/**/*.{ts,scss,html}\"",
  "lint-scss": "stylelint --formatter verbose --fix \"{apps,libs}/**/*.scss\"",
  "pre-commit": "./tools/pre-commit.sh",
  "pre-push": "./tools/pre-push.sh"
},

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




Присоединяйтесь к нашему сообществу на Medium, Telegram или Twitter.

Tags:
Hubs:
Total votes 8: ↑6 and ↓2+4
Comments6

Articles