Как правильно настроить TypeScript в Node.js проекте?
#typescript #best_practice
Как
1. Сделан фреймворком. В моем тех стэке, это
2. Результат команды
3. Копирование из другого проекта.
Каждый из этих вариантов, не учитывает под какой версией #nodejs вы будете запускать ваш проект. В результате этого, вы не можете использовать новые JavaScript конструкции.
TypeScript Wiki рекомендует такие настройки под Node.js v14:
Для сравнения стандартная настройка Nest.js:
После изменения конфигурации у меня заработал
#typescript #best_practice
Как
tsconfig.json появился в вашем проекте? Наиболее распространенные варианты:1. Сделан фреймворком. В моем тех стэке, это
npx @nestjs/cli new project-name2. Результат команды
./node_modules/.bin/tsc --init3. Копирование из другого проекта.
Каждый из этих вариантов, не учитывает под какой версией #nodejs вы будете запускать ваш проект. В результате этого, вы не можете использовать новые JavaScript конструкции.
TypeScript Wiki рекомендует такие настройки под Node.js v14:
{ "compilerOptions": { "lib": ["ES2020"], "module": "commonjs", "target": "ES2020" }}Для сравнения стандартная настройка Nest.js:
{ "compilerOptions": { "module": "commonjs", "target": "ES2017" }}После изменения конфигурации у меня заработал
Array.flat, ради которого я изучал этот вопрос. Полный список новых поддерживаемых фич ECMAScript можно посмотреть в исходниках typescript@src/lib.Как конфигурировать Node.js приложение?
#best_practice #package #devops
TL;DR Конфигурация хранится в переменных окружения без значений по умолчанию. Если какой-либо переменной нет или формат не верный, то приложение не должно запускаться. Требуемые переменные описываются в env.example. Реализация dotenv-safe
Теория
Каждому #nodejs разработчику следует знать 12 факторный манифест . Следование его принципам позволит создавать масштабируемые веб-приложения и комфортно сотрудничать с DevOps инженерами. Третий фактор говорит, что конфигурация должна храниться в настройках окружения (env vars). Рекомендую с этим фактором ознакомиться, там подробно описано почему стоит использовать именной такой подход.
Применение
Значения всех переменных окружения доступны:
- в терминале с помощью команды
- на уровне Node.js кода с помощью объекта
Значения конкретной переменной
- в терминале с помощью
- на уровне Node.js кода с помощью
Установить переменные окружения можно:
– посредством команды export. Например:
– посредством команды source
– В момент запуска процесса как ИМЯ=ЗНАЧЕНИЕ перед самой командой. Пример:
– Изменением значений в
.env
.env.example
Советы по уменьшению количества переменных
– Используйте connection string. Пример:
– Используйте JSON в значениях переменных. Пример:
– Используйте значения через запятую. Пример:
Распространенные ошибки
– Отсутствие приведение типа. Все ключи объекта
– Использование значений по умолчанию. Пример,
– Ошибка в путях к
– Ошибка характерная для FE разработчиков: не понимание разницы между переменными окружения в build-а и run time.
– Ошибка характерная для microservice разработчиков в проектах с Service discovery: различие локального и прод окружений. Необходимо запускать Consul или его аналоги через Docker.
#best_practice #package #devops
TL;DR Конфигурация хранится в переменных окружения без значений по умолчанию. Если какой-либо переменной нет или формат не верный, то приложение не должно запускаться. Требуемые переменные описываются в env.example. Реализация dotenv-safe
Теория
Каждому #nodejs разработчику следует знать 12 факторный манифест . Следование его принципам позволит создавать масштабируемые веб-приложения и комфортно сотрудничать с DevOps инженерами. Третий фактор говорит, что конфигурация должна храниться в настройках окружения (env vars). Рекомендую с этим фактором ознакомиться, там подробно описано почему стоит использовать именной такой подход.
Применение
Значения всех переменных окружения доступны:
- в терминале с помощью команды
env- на уровне Node.js кода с помощью объекта
process.env. Значения конкретной переменной
<NAME> доступно:- в терминале с помощью
$<NAME>- на уровне Node.js кода с помощью
process.env.<NAME>Установить переменные окружения можно:
– посредством команды export. Например:
export NODE_ENV=production . Результат команды не сохраняется между сессиями консоли. Для внесения долгосрочный изменений в окружение команду необходимо прописать в .bashrc или его аналог.– посредством команды source
– В момент запуска процесса как ИМЯ=ЗНАЧЕНИЕ перед самой командой. Пример:
NODE_ENV=production DEBUG=0 node src/index.js Работает как в терминале, так и в npm scripts.– Изменением значений в
process.env уже во время работы приложения. .env
.env файл с переменными окружения используется для упрощения локальной разработки. На всех других окружениях его использование является плохой практиков. .env никогда не должен храниться в git репозитории. Поддержка есть во всех IDEA. Для консоли есть расширения, например autoenv. На уровне кода общепринятым пакетом является dotenv. Он вычитывает в process.env значения из .env, но не заменяет уже существующие значения..env.example
.env.example описывает все требуемые переменные окружения для работы приложения. Там можно и нужно делать комментарии. Это single source of truth для вашего DevOps инженера. Его необходимо хранить в git. Если приложение, не имеет какого-либо из ожидаемых переменных, то оно не должно стартовать. Fail fast! Этот функционал обеспечивает пакет dotenv-safe, который является оберткой над dotenv.Советы по уменьшению количества переменных
– Используйте connection string. Пример:
DB_URL=postgresql://postgres:password@localhost:5432/database– Используйте JSON в значениях переменных. Пример:
const stripeConfig = JSON.parse(process.env.STRIPE_CONFIG)– Используйте значения через запятую. Пример:
const adminList = process.env.ADMINS.split(',')Распространенные ошибки
– Отсутствие приведение типа. Все ключи объекта
process.env имеют значения типа string. Пример, вопреки ожиданиям при запуск с SOME_FEATURE=false код if process.env.SOME_FEATURE ... будет исполнен.– Использование значений по умолчанию. Пример,
const logLevel = process.env.LOG_LEVEL || 'info'. Это приводит к неявной конфигурации и дорогостоящим ошибкам.– Ошибка в путях к
.env из-за использования относительных, а не абсолютных путей.– Ошибка характерная для FE разработчиков: не понимание разницы между переменными окружения в build-а и run time.
– Ошибка характерная для microservice разработчиков в проектах с Service discovery: различие локального и прод окружений. Необходимо запускать Consul или его аналоги через Docker.
Какую версию npm использовать?
#best_practice #npm #tech_stack
Node package manager – npm регулярно показывает
Пример текущей LTS комбинации: Node.js v14.16.1, npm v6.14.12. Этому следуют все:
- установочные бинарники,
- nvm (node version manager) и его аналоги,
- Docker image
Использование различных версий npm ведет к различному поведению приложения, трудноуловимым багам и git конфликтам.
Если вы используете yarn, то такой таблицы нет. Лучшей практикой будет использование версию прошитой в Docker image. Например, для Node.js v14.16.1 это будет yarn v1.22.5
#best_practice #npm #tech_stack
Node package manager – npm регулярно показывает
Update available. Следовать этому оповещению и обновлять npm не стоит. Вместе с версией #nodejs идет конкретная версия npm и именно ее следует использовать. Версии указаны в таблице.Пример текущей LTS комбинации: Node.js v14.16.1, npm v6.14.12. Этому следуют все:
- установочные бинарники,
- nvm (node version manager) и его аналоги,
- Docker image
Использование различных версий npm ведет к различному поведению приложения, трудноуловимым багам и git конфликтам.
Если вы используете yarn, то такой таблицы нет. Лучшей практикой будет использование версию прошитой в Docker image. Например, для Node.js v14.16.1 это будет yarn v1.22.5
Как узнать источник соединение в БД?
#best_practice #database
TL;DR Всегда ставьте
Сегодня обсудим малодокументированную фишку баз данных. При создание соединения можно указать
Без ORM:
TypeORM
Sequelize
Теперь вы сможете увидеть
Аналогичные параметр есть у всех клиентов баз данных.
Например, MongoDB использует appName, а Redis – CLIENT SETNAME.
#best_practice #database
TL;DR Всегда ставьте
application_name в конфигурации подключения к БД.Сегодня обсудим малодокументированную фишку баз данных. При создание соединения можно указать
application_name. Это аналог http заголовка User-Agent в мире баз данных. Он виден в списке соединений и slow query log. Приведу примеры кода для PostgreSQL.Без ORM:
import { Client } from 'pg';const client = new Client({ connectionString: process.env.DB_URL, application_name: 'my-app@0.1.0'});TypeORM
import { PostgresConnectionOptions } from 'typeorm/driver/postgres/PostgresConnectionOptions';const dbConfig: PostgresConnectionOptions = { type: 'postgres', url: process.env.DB_URL!, extra: { application_name: 'my-app@0.1.0' }, entities: ...};Sequelize
import { Sequelize } from 'sequelize';const sequelize = new Sequelize(process.env.DB_URL!, { dialect: 'postgres', dialectOptions: { appName: 'my-app@0.1.0' }});Теперь вы сможете увидеть
application_name в pg_stat_activity с помощью запросаSELECT * FROM pg_stat_activity WHERE datname = '<db_name>';Аналогичные параметр есть у всех клиентов баз данных.
Например, MongoDB использует appName, а Redis – CLIENT SETNAME.
Что не стоит делать в PostgreSQL?
#best_practice #database
Сегодня у нас в рекомендациях ссылка Don't Do This из википедии PostgreSQL. Каждый из пунктов выдержан в стиле что не стоит делать, почему и в каких случаях все же стоит нарушить эту рекомендацию. Отлично подходит, чтобы отправить коллеге который таки решил сделать что-нибудь плохое.
#best_practice #database
Сегодня у нас в рекомендациях ссылка Don't Do This из википедии PostgreSQL. Каждый из пунктов выдержан в стиле что не стоит делать, почему и в каких случаях все же стоит нарушить эту рекомендацию. Отлично подходит, чтобы отправить коллеге который таки решил сделать что-нибудь плохое.