tech@iiit-gwalior
Published in

tech@iiit-gwalior

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.
iii) Deployment.

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

yo generator

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:-

The 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.

The initial index.js file would look something like this:-

The class we’re exporting extends the base Generator class, whose functions we can override.

The 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 this. The 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.

Replace the 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 name and mongodb properties, you would write this.props.name and 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

npm link

Once you do this, open your terminal, and run

yo express-mongodb

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.

In the app/templates folder, delete any existing files, and create a package.json, an 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.

The 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 opts object.

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!

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Guna Shekar Proddaturi

Guna Shekar Proddaturi

Blockchain Developer | MERN Stack | React Native