4.8 KiB
Preferred Libraries
A lot of research has gone into determining what the best tool is for each common task that gets performed. These tasks can range from generating a CLI help menu to validating user inputs. You can browse through the dependencies in the package.json
file of our NPM package starting template to get a better idea of what we prefer.
Logger
If you browsed through the package.json
file mentioned above, you will see that we are including pino
and pino-pretty
as dependencies. Both should be used to handle all logging. There should be no console.log
commands in the project. Instead, all of the logging should be handled by a Logger class. You can see an example provided by the Buildr project here. When creating a Logger class, feel free to copy and paste from the linked Buildr Logger class file.
CLI / Help Menu
Commander.js is the leading solution for handling CLI commands and generating terminal help menus. The library is included in the aforementioned starting template and should be used in any project that includes CLI command capabilities or CLI help menus. Using this library is not a hard requirement but any deviations from it should be approved by the project's maintainer.
Interactive CLI Prompts
Inquirer.js is our preferred library for providing enhanced CLI prompts. You might choose to use this library if part of the app includes prompting the user for different values. Browsing through the capabilities of Inquirer.js using the link provided is highly encouraged. If you are not utilizing this dependency then it should be removed from the package.json
. The same goes for any package that is unused - if it is not being used then throw it out!
Data Model Validation
One feature we like to include in all of our projects that rely on any input parameters is data validation. For instance, if one of the parameters that is passed in is supposed to be a FQDN and the user passes in a string that does not match the RegEx of a FQDN, then the user should be notified with a simple, well-formatted error message (which is generated by pino
). We accomplish this by leveraging the class-validator
library. There are tons of examples provided on their page and we highly encourage you to get comfortable using the library by checking out the link.
In order to utilize class-validator
, you have to assign all input data to a model. The model is then set up to use class-validator
decorators on each attribute. With the data model populated, you can use the class-validator
library to validate the input. Take the following as an example:
import { validate, IsInt, IsFQDN, Min, Max } from 'class-validator';
export class Post {
@IsInt() // This is a decorator
@Min(0)
@Max(10)
rating: number;
@IsFQDN()
site: string;
}
let post = new Post();
post.rating = 11; // Should not pass validation
post.site = 'googlecom'; // Should not pass validation
validate(post).then(errors => {
// errors is an array of validation errors
if (errors.length > 0) {
console.log('validation failed. errors: ', errors);
} else {
console.log('validation succeed');
}
});
Using the library above can provide real value to our users. By validating the data before running any business logic, we can save the user time by taking out the guess work required for debugging. Please note that in practice, the Post
model/class would be seperated into a file stored in src/models/post.model.ts
.
All data inputs should utilize this form of validation. If the class-validator
project does not provide a decorator that can properly validate the input data then you can extend the library by creating a custom validation decorator. There is an example of how to create a custom validator in the Buildr project.
Update Notifier
As a feature meant to make our packages stand out from the crowd, we prefer that you incorporate update-notifier
in the project to notify users of any updates to the NPM package.
Environment Variables
In some cases, a package might rely on sensitive data that should not be included in git repositories. In this case, you may choose to utilize environment variables. If that is the case, then please include support for dotenv which allows users to load environment variables by defining a .env
file. The users can then add .env
to their .gitignore
file to keep the .env
file out of their project's repository.