My 2012 computer, fully loaded with i7 processor and RAM *at the time*, is still quite powerful and very reliable, so I don’t want to change it (ecologically speaking: I don’t want to use more rare resources from the Earth which also come with misery and violence in producing countries; get informed!).
Yet, working with NestJS has first appeared very tedious and extremely long to run, up to 2 minutes.
Avoiding launching the web-server everytime
The first thing I wanted to avoid was to launch the application webserver every time I changed something within the application logic (which is, 99.999% of the time, right?). So I created a script for the case I wanted to develop-and-try :
console.log("[" + (new Date()).toISOString() + "] Script launched.");
import { NestFactory } from '@nestjs/core';
import * as moment from 'moment';
import 'moment/locale/pt-br';
import { AlarmController } from '@ceneau-wa/controller/alarm/alarm.controller';
import { AlarmModule } from '@ceneau-wa/controller/alarm/alarm.module';
import { SymptomOccurrenceDto } from '@ceneau-dto/activity/symptom-occurrence.dto';
console.log("[" + (new Date()).toISOString() + "] Imports done.");
async function run() {
moment.locale('utc');
// Prepare controllers and services
const app = await NestFactory.create(AlarmModule);
const controller = app.get(AlarmController) as AlarmController;
// Prepare data to process
const dto = new SymptomOccurrenceDto();
dto.entityType = 10;
dto.entityId = 81;
dto.positive = true;
dto.startingDate = 1554214235000;
dto.endingDate = 1554214237000;
dto.elementCount = 1;
// Launch actual logic
console.log("[" + (new Date()).toISOString() + "] Application starts.");
await controller.launch(dto);
console.log("[" + (new Date()).toISOString() + "] Application ends.");
}
run();
This works fine. I create the application context via NestFactory.create, giving it the module I need, and retrieve the component I want to use (here, the AlarmController). Works well!
Minimizing execution time
By using following command to launch above script :
node --nolazy -r ts-node/register -r tsconfig-paths/register src/sendOccurrence.ts
(don't use this command ! see below)
execution times were terrible, between 90 to 120 seconds.
Surely, it’s the dealing with NestFactory and internal process which causes an horrible overhead, so I tried to not use NestFactory and instead created all services myself with all dependant services, but I was gaining only 2 seconds. I added some profiling time prints, as indicated in above code, and could see most of the time was spent during imports !
Finally, it’s the use of ts-node (install it globally) which saved me, being way faster :
ts-node -T -r tsconfig-paths/register src/sendOccurrence.ts
(-T: "does not check for type errors", saves another 2 seconds in execution)
Execution dropped to 17-20 seconds. Hooray !
Take note that some people totally struggle while using ts-node too, like this guy and his 9-minute start time…
Debugging the process
Unfortunaly, I couldn’t find a way to minimize launching time while debugging the script indicated above. I’m still using a VSCode launch.json with such configuration :
{
"type": "node",
"request": "launch",
"name": "Slooooow - Debug SendOccurrence",
"args": ["${workspaceFolder}/src/sendOccurrence.ts"],
"runtimeArgs": ["--nolazy", "-r", "ts-node/register", "-r", "tsconfig-paths/register"],
"sourceMaps": true,
"cwd": "${workspaceRoot}",
"protocol": "inspector",
"stopOnEntry": false
}
And launching time is still 2 minutes…
Note: from VS Code versions after 1.46.0, the internal javascript debugger has an auto-attach mode which seems sweet, and maybe solves this. Turn option “Debug: Toggle Auto Attach” on, and run a npm/yarn command: your breakpoints should be hit. More details here:
https://github.com/microsoft/vscode-js-debug#debug-nodejs-processes-in-the-terminal.
