Build your own Boilerplate Generators using Yeoman
Three of the most important phases of developing a software include,
i) Bootstrapping and environment setup.
ii) Development and Testing.
While the second phase is fairly straightforward for developers, the first and third usually take up some time. A lot of research is involved in configuring basic features, especially if you’re a beginner. Deployment is another whole new ball game, and very few learners actually use docker and docker compose to make their apps fully deployable.
For fullstack applications, features like authentication, database, documentation, CORS on the backend, routers, state managers, axios on the frontend, seem to be pretty basic features which we would need almost all the time, but take up quite some time to setup from the scratch, which adds up to approximately 45 minutes as determined by a practical experiment.
If you find yourself spending time setting up your applications with the same configurations as always, it makes sense to develop a boilerplate generator for yourself which will bootstrap an app that is pre-configured with your needs.
This article will give you a brief understanding of how you can use Yeoman to build a simple boilerplate for Node.js + Express.js server that comes configured with MongoDB and Mongoose. If you’re looking to build a generator for some other tech stack, read on because the generator concepts remain the same, all you have to do is replace the templates with your own.
To start off, you’ll have to install 2 npm packages globally.
npm install -g yo generator-generator
Yo is the Yeoman package that helps you interact with all the generators you have installed and quite literally,
generator-generator helps you generate a generator. Every Yeoman generator begins with a
generator-, this helps their website index the Yeoman generators.
To start building your generator, run
This would open up an interactive CLI where you’ll have to answer a few basic questions like the name and description of your app. Make sure your app name begins with a
generator-. Here’re my answers:-
You should see a folder with the name of your app. The folder structure should look something like this:-
generators folder is the one where we’ll be writing most or all of our code. When you invoke your generator via your CLI using
yo express-mongodb, the
index.js file under the
generators/app folder gets executed. The files you’d want to generate should be kept under the
templates folder, which we’ll later use and copy into your generated application.
index.js file would look something like this:-
The class we’re exporting extends the base Generator class, whose functions we can override.
prompting function is where you’ll write out the prompts that you want your interactive CLI to ask the user. The answers can be saved in the context of the class using
writing function is where you’ll write the logic to copy files from the templates folder into the working directory of the user where they would want to generate the app. The
install function is where you’ll install the dependencies required for the generated app. Note that these 3 functions will be run in this same order when your CLI is invoked.
Starting off with the
prompting function, let’s ask the user what they’d like to name their app and whether or not they’d like Mongoose to be installed in their express app. Yeoman uses Inquirer.js under the hood for the interactive CLI.
prompts array with the one below:-
We have 2 prompts, one of type
input which accepts a string and second is of type
confirm which is a Yes/No question. The prompts are saved in
this.props as it can be seen on line 34. So if you want to access the
mongodb properties, you would write
this.props.mongodb. If you’d like to add more prompts of different types, checkout Inquirer.js for their documentation.
Also notice that I changed the
install function to use
this.npmInstall() instead of the default
this.installDependencies() function because the default one requires you to have
bower installed in your system.
Now in order to be able to invoke your interactive CLI so that you can start answering the questions you added as prompts, you’ll have to link your package. To do so, run
Once you do this, open your terminal, and run
and in a few seconds, you should see your prompts showing up and you can answer them. But nothing happens after that because we haven’t configured our templates folder to write the files that we want. Let’s configure the templates folder and copy those files into our working directory when we try to run the generator.
app/templates folder, delete any existing files, and create a
index.js and a
mongoose.js file. Copy the following contents into the files:-
If you’re familiar with ejs, you’d know what the
<% %> syntax is, in case you don’t, this is how you invoke variables and commands in an ejs file and Yeoman Generator uses this syntax to help you dynamically configure your template. On line 2 in
package.json, you can see we have the app name to be set equal to
"<%= name %>". Similarly on line 12, we’re installing mongoose only if the mongodb variable is true. And the same thing is followed in the
index.js file too. How do these files get access to these variables? Read on.
Paste the following code in your
app/index.js file, i.e., the one where you’re writing your generator:-
Let’s try to understand how the
writing() function works. The first line helps you fetch the path to your templates folder, i.e., the “source” directory where your template files reside. The
this.destinationPath function gives you access to the current working directory where you’ll be running the generator, and let’s you append anything to that path. I appended the app name to the destination, so if I run the generator in the Documents folder, my destination would be Documents/myapp if the name of my app is myapp.
ignore array in the copyOpts object helps you ignore any files dynamically. Since we wouldn’t want to copy the
mongoose.js file if the user opted not to use mongoose, we will push the file into the array if
this.props.mongodb is false.
this.fs.copy copies the files from a source directory to a destination directory keeping the copyOpts object in mind, i.e., it would ignore any files that you pushed into the
ignore array. The
this.fs.copy function directly copies the files, and doesn’t pass any parameters into the files for dynamic configuration as we did in our files. For that we’d have to use the
this.fs.copyTpl function as we did on line 63. We have an array of files which need dynamic properties, and we’re running
this.fs.copyTpl on each of them while passing the properties they need in the
Finally, coming to the
install() function, before installing the dependencies, we will have to change the directory to the current working directory which would be Documents/myapp if I executed the generator in the Documents folder with my app name as myapp. The code to do this is on lines 73 and 74. Once the directory is changed, we can go ahead and install the dependencies.
And that’s it! Now run
npm link and in your terminal, type out
yo express-mongodb. You’ll be asked for the prompts and once you fill your answers, your app will be configured and you can start your app by running
node index inside your app directory.
Now you don’t have to configure mongoose everytime you’re creating a new app, you could just use this generator and it would do it for you! While this example had just one configuration in one file, you can definitely do a lot more with this!
You can find the full code for the generator here.
If you’re looking for a full fledged MERN Stack or Django or Django React App generator, do checkout generator-front-to-back which lets you configure fullstack apps in a couple of minutes, saving approximately 45 minutes everytime you have to bootstrap your app!