nest
nest copied to clipboard
feat(core): free port listening
PR Checklist
Please check if your PR fulfills the following requirements:
- [ ] The commit message follows our guidelines: https://github.com/nestjs/nest/blob/master/CONTRIBUTING.md
- [x] Tests for the changes have been added (for bug fixes / features)
- [x] Docs have been added / updated (for bug fixes / features)
PR Type
What kind of change does this PR introduce?
- [ ] Bugfix
- [x] Feature
- [ ] Code style update (formatting, local variables)
- [ ] Refactoring (no functional changes, no api changes)
- [ ] Build related changes
- [ ] CI related changes
- [ ] Other... Please describe:
What is the current behavior?
Default Nest.js application startup.
const app = await NestFactory.create(AppModule);
await app.listen(3000);
It will potentially throw EADDRINUSE error (if you launching different servers at the same time with same ports).
What is the new behavior?
We can run application anyway, even port is busy. Nest.js application will automatically find free port.
const app = await NestFactory.create<INestFreePortListener>(AppModule);
await app.listenFreePort({
port: 3000,
});
It can be helpful in debugging, when we want just to start a server.
const app = await NestFactory.create<INestFreePortListener>(AppModule);
if (process.env.NODE_ENV === 'development') {
await app.listenFreePort({
port: 3000,
});
} else {
await app.listen(3000);
}
All parameters of .listenFreePort(options)
. All parameters are nullable. Default port is 3000.
const app = await NestFactory.create<INestFreePortListener>(AppModule);
await app.listenFreePort({
port: 3000,
hostname: '0.0.0.0',
onSkip: (port) => {
console.log(`Port ${port} is busy. Try another one...`);
return port < 4000; // Set some restriction for port. Return true if we want to continue port skipping.
},
onStart: (port) => console.log(`Server listening at http://localhost:${port}`),
});
Does this PR introduce a breaking change?
- [ ] Yes
- [x] No
Other information
Fastify support not available yet :(
Pull Request Test Coverage Report for Build bdc9e6c6-dd01-4424-9c19-d7be885abfb5
- 2 of 2 (100.0%) changed or added relevant lines in 1 file are covered.
- No unchanged relevant lines lost coverage.
- Overall coverage increased (+0.002%) to 93.788%
Totals | |
---|---|
Change from base Build 6b637f64-9c7a-4d7b-8537-b6a8d098f58e: | 0.002% |
Covered Lines: | 6115 |
Relevant Lines: | 6520 |
💛 - Coveralls
actually, we can't say that "the default is 3000". That's just the value we got when generating the app with the CLI.
What we could do instead is making that port
parameter optional. When not supplied, a random available port will be taken, like they do in Express already.
We would have to do a minimal change on FastifyAdapter#listen
. And just a type def changing on ExpressAdapter#listen
. What do you think?
const app = await NestFactory.create(AppModule);
await app.listen();
console.log( await app.getUrl() ) // to see the port
I just tested the above with both HTTP adapters without making any change on their source code and it works
By the way, using 0
as the port means that the OS will find a free port for you. I do this in just about every e2e test that I write now so I don't worry about port collision. You could do the same thing here and use the getUrl()
like @micalevisk suggested
So we could use 0
as the default value for port
.
Or just document that you could use 0 if you want to pick a random port in our docs site.
Also, what would be the reason for keeping a port within a certain range, like under 4000? So long as it's above port 1023 is should generally be okay as you don't need super user permissions to run, and the OS will find one that's open anyways. Do some tools/utilities have issues with 5 digit ports, or ports over a certain value?
This is redundant changes as I understand it. PR should be closed?
yep
It would be better to write another one if you want to make the port
parameter optional