Запуск NestJS невероятно медленно развивается
Мое приложение в среде разработки очень медленно на этапе запуска. Я установил несколько журналов отладки в разных местах, чтобы посмотреть, что занимает так много времени, и обнаружил, что мой main.ts
на самом деле использует почти 9 минут, чтобы получить мой app.module
импортирован!
Источник
import { performance } from 'perf_hooks';
const startTime = performance.now();
import { Log } from 'api/common/util/logger/log';
Log.log.info(`┌────────────────────────────────────────────────────────────┐`);
Log.log.info(`│ Starting: ${new Date().toISOString()} │`);
Log.log.info(`└────────────────────────────────────────────────────────────┘`);
// From here -------------------->
import { NestFactory } from '@nestjs/core';
import { ValidationPipe } from '@nestjs/common';
import 'reflect-metadata';
import { existsSync, mkdirSync, writeFile } from 'fs';
import * as express from 'express';
import * as bodyParser from 'body-parser';
import * as helmet from 'helmet';
import * as morgan from 'morgan';
import * as morganBody from 'morgan-body';
// <------ to here, imports fly in as expected.
// Theese take a bit longer, but not enormously
import { Config } from './api/common/config';
import { HttpExceptionFilter } from './api/common/filters/http-exception.filter';
import { LogService } from 'api/common/util/logger/log.service';
// This one takes up the most time on startup (several minutes)
import { AppModule } from './api/app.module';
Log.log.debug(` * imports done in ${(performance.now() - startTime).toFixed(3)}ms`);
Log.log.debug(` * Memory: ${readMem()}`);
function readMem() {
const mem = process.memoryUsage();
const convert = { Kb: n => (n / 1024), Mb: n => convert.Kb(n) / 1024 };
const toHuman = (n, t) => `${convert[t](n).toFixed(2)}${t}`;
return `Used ${toHuman(mem.heapUsed, 'Mb')} of ${toHuman(mem.heapTotal, 'Mb')} - RSS: ${toHuman(mem.rss, 'Mb')}`;
}
Выход
Запуск производства:
$ node dist/main.js
info: ┌──────────────────────────────────────────────────────────────────────────┐
info: │ Starting: 2019-01-29T13:06:13.751Z │
info: │ Memory: Used 6.54Mb of 11.70Mb - RSS: 25.33Mb │
info: │ Runtime: js │
info: └──────────────────────────────────────────────────────────────────────────┘
debug: * imports done in 6862.350ms
debug: * Memory: Used 87.99Mb of 113.76Mb - RSS: 133.58Mb
info: Nest application successfully started
info: ┌──────────────────────────────────────────────────────────────────────────┐
info: │ Memory: Used 93.71Mb of 122.52Mb - RSS: 144.20Mb │
info: │ Launch: 2019-01-29T13:06:25.377Z │
info: │ Time to start: 11991.049ms │
info: │ Bootstrap time: 5124.189ms │
info: └──────────────────────────────────────────────────────────────────────────┘
Разработка стартапа:
$ ts-node -r tsconfig-paths/register src/main.ts
info: ┌──────────────────────────────────────────────────────────────────────────┐
info: │ Starting: 2019-01-29T13:08:06.914Z │
info: │ Memory: Used 157.76Mb of 193.62Mb - RSS: 209.77Mb │
info: │ Runtime: ts │
info: └──────────────────────────────────────────────────────────────────────────┘
debug: * imports done in 471159.063ms
debug: * Memory: Used 297.45Mb of 385.35Mb - RSS: 408.90Mb
info: Nest application successfully started
info: ┌──────────────────────────────────────────────────────────────────────────┐
info: │ Memory: Used 216.64Mb of 383.35Mb - RSS: 409.11Mb │
info: │ Launch: 2019-01-29T13:16:05.521Z │
info: │ Time to start: 483228.325ms │
info: │ Bootstrap time: 12042.239ms │
info: └──────────────────────────────────────────────────────────────────────────┘
Да я начинаю это использовать ts-node
, но это то, что NestJS рекомендует для разработки и отладки.
Вопрос
Как я могу оптимизировать запуск, чтобы каждое незначительное изменение в серверной части здесь не требовало 10-минутного промедления? У меня достаточно проблем с концентрацией, как это, это не помогает.
У меня слишком много модулей? Поможет ли мне это объединить? У меня есть около 15 моделей сущностей БД, каждая из которых включена в свой собственный модуль на основе graphql для удобства чтения, но многие из них имеют циклические зависимости, разрешаемые с помощью forwardRef()
впрыск в мой модуль импорта. Возможно, это проблема?
Я стараюсь включать как можно меньше сторонних библиотек, чтобы избежать адских узловых модулей. То, что я импортирую в свои модули, это либо мой собственный код, либо материал фреймворка NestJS. Конечно, я не знаю, сколько загруженных неявных зависимостей, но может ли количество библиотек, которые я перетаскиваю со мной, повлиять на производительность запуска? И если да, то как я могу отслеживать, что попадает в стек и сколько памяти / процессора потребляет каждый скрипт при оценке? И могу ли я как-то предварительно скомпилировать это для увеличения запуска?
У меня нет этой проблемы при запуске как скомпилированный JavaScript в производстве.
8 ответов
Попробуй установить env TS_NODE_TRANSPILE_ONLY=true
,
например TS_NODE_TRANSPILE_ONLY=true ts-node -r tsconfig-paths/register src/main.ts
документы: https://github.com/TypeStrong/ts-node
Это ускорит запуск моего приложения
Один из вариантов - использовать tsc-watch вместо ts-node и nodemon. Вы можете настроить команду запуска в своем запуске:dev следующим образом:
{
//this is assuming you're building to the dist folder
...
"start:dev": "tsc-watch --onSuccess \"node dist/main.js\" --onFailure \"echo
There was a problem with the build!\" -p tscfonig.json"
...
}
По моему опыту я столкнулся с слишком многими проблемами с ts-node
и регистрация маршрутов, плюс время загрузки убивали меня. С tsc-watch
Я получаю свежую сборку проекта, перестраивая только те файлы, которые были изменены. Таким образом, вы также проверяете, что tsc
работает во время разработки.
Я также использую команду tsconfig-bootstrap для импорта моих пользовательских маршрутов (определенных в моем tsconfig) и добавляю их в мою команду запуска с помощью node -r path/to/my/script.js dist/main.js
,
Надеюсь, это поможет вам немного!
Если у кого-то возникла эта проблема, у нас есть Nest API с примерно 40 модулями, с узлом v12 время запуска составляло около 2-3 минут, а с узлом v14+ время запуска составляет от 5 до 10 секунд. Для локальной разработки я рекомендую использовать NVM и попробовать использовать более высокую версию узла (если пакеты совместимы).
У меня возникла эта проблема после обновления до [email protected] и я начал использовать узел v16. Проблема исчезла после того, как я понизил версию nodejs.
Изменить: проблема была связана с
pg
модуль. Оно бесшумно падало. После обновления до
pg@latest
NestJ запустился нормально.
- Пожалуйста, проверьте, подключается ли ваш сервер к удаленной базе данных, в этом случае это может привести к замедлению работы вашего сервера.
- Если вы используете mongoDB, проверьте версию mongoose, которую вы используете.
- для MYSQL используйте «рабочую среду MySQL» вместо xampp (я лично исправил проблему, сделав это)
PS: В большинстве случаев удаленное соединение будет влиять на работу вашего сервера, замедляя его работу.
Просто добавив это на случай, если у кого-то может быть такая же причина, моя проблема была связана с импортом клиентов grpc, которые не были достаточно конкретными с тем, какие протоколы включать, а также в слишком многих разных местах.
Наша структура protos довольно велика, поэтому загрузчик grpc загружался очень медленно, из-за чего nest требовал нескольких минут для запуска.
Поэтому убедитесь, что вы используете только те сервисы, которые вам напрямую нужны в настроенном protoPath. Я не думаю, что параметры includeDirs имеют значение, поэтому просто protoPath.
Логичное решение проблемы - это раскомментировать модули, которые вы не используете в настоящее время, из модуля приложения.
@Module({
imports: [
TypeOrmModule.forRoot(defaultOptions),
// Commented for faster reloads
// NotUsingModule1
// NotUsingModule2
UsingModule1
],
controllers: [AppController],
providers: [AppService],
})
export class AppModule { }
Также в случае работы с СУБД убедитесь, что для входа в систему не задано значение true, а dropSchema также не установлено в значение true.
- В некоторых случаях вы столкнетесь с проблемой, когда сущности не формируют отношения правильно, сделайте dropSchema истинным, она ОЧИСТИТ ВСЕ СРЕДСТВА ИЗ БАЗЫ ДАННЫХ. НЕ ДЕЛАЙТЕ ЭТОГО В ПРОИЗВОДСТВЕ. ВЫ БЫЛИ ПРЕДУПРЕЖДЕНЫ
export const defaultOptions = {
type: "postgres",
port: 5432,
username: "postgres",
password: "postgres",
database: "awesome db",
synchronize: true,
// logging: true,
// dropSchema: true,
entities: ['dist/**/*.entity.js'],
Установить последнюю версию @nestjs/cli
, как глобально, так и локально:
$ npm install -g @nestjs/cli
$ cd /some/project/root/folder
$ npm install -D @nestjs/cli
замените / убедитесь, что у вас есть следующие скрипты, определенные в package.json
"build": "nest build",
"start": "nest start",
"start:dev": "nest start --watch",
"start:debug": "nest start --debug --watch",
убедитесь, что у вас есть автоматическое прикрепление кода vs
пробег
npm run start:dev