Building a Slush Generator

Tweet about this on TwitterShare on LinkedIn8Share on Google+0Share on Reddit0Buffer this pageFlattr the authorEmail this to someonePrint this page

Building a Slush Generator

Generators are powerful tools that help in quickly scaffolding project structures. You can use them to start off a new project or add new components to an existing project. Generally these projects are collections of best practices that a developer can consume directly. In this post, we will see how to build a simple generator that will create a boilerplate for a building static pages with auto reloading feature.

You can find the completed code here.

So, let us get started.

What is Slush?

Slush is a tool to be able to use Gulp for project scaffolding.

Slush does not contain anything “out of the box”, except the ability to locate installed slush generators and to run them with liftoff.

Getting started

First we will install gulp, slush and slush-generator. slush-generator is a generator for generating slush generators. Yup! this generator will scaffold a project that can be used to scaffold other slush projects.

As mentioned earlier, we are going to build a project that will create a boilerplate for a building static pages with auto reloading feature. Create a new folder named slush-reloader. Open a new terminal/prompt here and run

Windows Mac/*nix

npm i -g gulp slush slush-generator 

  sudo npm i -g gulp slush slush-generator

Once the installation is completed, we will scaffold a new slush project. Run

slush generator

And answer the questions as below

Screen Shot 2014-07-31 at 8.55.47 amPS : Enter the project name as only reloader and not slush-reloader.

Slush will take care of installing the dependencies. The final project structure would be

The project structure is pretty simple. We will be working mostly with slushfile.js and templates folder. Once the development is completed, we will push the changes to NPM repository by updating our package.json. Sounds simple?

Now, open slushfile.js in your favorite editor. You will notice that there are a few includes and and some helper functions. Then you will notice a gulp task.

When building slush generators, you need to be aware that a generator is nothing but a gulp task. And the name of the task is how we would be invoking it. Technically a gulp task also acts a sub-generators. Sub-generators are very much like generators, except they are used once the project is already generated and a few minor monotonous functionalities need to be added.

For example, if you are building a client-side MVC app, a generator will be responsible for scaffolding the app itself, where as a sub-generator will be responsible for scaffolding MVC related files for a new feature/route as the development progresses.

Back to the gulp task, you will notice an array named prompts inside the callback function, this array holds the list of question that you would be asking to user to scaffold a project. Like the once we have answered to generate the current project.

And then these options are fed into a node module named inquirerinquirer is responsible for firing these questions and gathering the answers. Once we receive the answers, we can scaffold a project according to the user’s inputs. Simple?

For our generator, we will only ask the user what is the name of the project. We will use this input to personalize the project for the user.

You can update the prompts array like

If you want to test this locally, you can link this project to a node module. Run

[sudo] npm link

Now, you can locally test the generator as you make changes.

Create another folder named test_reloader elsewhere on the same machine and open terminal/prompt and run

slush reloader

And you should see the question we have configured. You can enter anything or simply hit return and you should see Screen Shot 2014-07-31 at 9.21.30 amNothing happens because we have no files to placed into the destination folder. Back to the slushfile.js, the inquirer part

On line 3, we check if a certain condition is met to start the scaffolding process, else we terminate the execution. On line 6, we clean up the user’s input. On Line 7, using a globbing pattern, we fetch all the files from the templates folder. We pass in the answers to the files we fetched in the templates folder, personalize the content and then save the processed files to the user’s current folder. Once all the files/folders are saved, we run the install()  on the scaffolded project to install dependencies.

For our generator, this is precisely what we need.

The final slushfile.js would be

Now, let us build the project we would like to scaffold. Generally, I build a few projects of a type, prune the best practice and then build a boilerplate/template that can be reused.

Inside the templates folder, create 2 new folders named css and js. And create app.css and app.js in css and js folders respectively. Open app.js and updated it as

And app.css like

Next, create a new file at the root of templates folder and name it index.html. And update it like

Do notice <%= appName %>. This will be updated when we scaffold the template with the answers.

Next, create a new file at the same level as index.html and name it as package.json. Update the file as below

We are going to add gulp-connect module that will be used to host the files locally. And finally the gulpFile. Create a new file named gulpFile.js and update it as

Save all the files and Bam!! we are done with our generator. Now back to the test folder we have created – reloader and run

slush reloader

Answer the question and slush will scaffold the app for us. Once done, run

gulp

This will start the connect server and you can navigate to  http://localhost:8080  and see the scaffolded app.

Simple right? If you want to see more advanced examples you can checkout

Repo

Description

slush-mongo

 A slush generator for MongoDB

slush-meanjs

 A slush generator to scaffold MEAN Apps

slush-bootstrap

 A Slush generator for Bootstrap SASS/LESS/CSS projects

slush-express

 A slush generator to scaffold Express apps

slush-webstarterkit

One command scaffold-er for Google's Web Starter Kit. No questions asked!

slush-h5bp

 A HTML5 Boilerplate generator for Slush

slush-angularfire

 A slush generator to scaffold an Angular-Firebase App

slush-reveal

 A Slush Generator for creating Revealjs presentation

Pushing to NPM

Once you are satisfied with your generator you can push the code to GitHub and publish it to NPM. For this, create a new Github repo named slush-reloader.

Next, push the code to the repo run

git init

git add -A

git commit -am "initial commit"

git remote add origin https://github.com/arvindr21/slush-reloader.git

git push origin master

Next, we will push this repo to NPM. Run

npm publish

You may be asked to enter your NPM credentials. If you do not have one, you can create so here.

Once the command executes, you can checkout  https://www.npmjs.org/package/slush-reloader  to see the package module registered with NPM.

Hope you got a decent idea on how to build your own slush generator.


Thanks for reading! Do comment.
@arvindr21

Tweet about this on TwitterShare on LinkedIn8Share on Google+0Share on Reddit0Buffer this pageFlattr the authorEmail this to someonePrint this page
  • http://www.fernandofas.com/ Fernando Fas

    Hi there, it’s me again.

    On you instructions you wrote:

    “We are going to add gulp-connect module that will be used to host the files locally. And finally the gulpFile. Create a new file named gulpFile.js and update it as”

    So, where the gulFile.js will be placed, inside the templates folder or at the root of all files?

    Also, when I’m on the folder created separately, I tried to run gulp, but on the command line asked me to install gulp that is already installed as global.

    Any ideas?

    Kind regards,

    Fernando Fas

  • http://www.fernandofas.com/ Fernando Fas

    Hi there,

    I installed everything according to the instructions and after create a new folder and type slush reloader, the following messages appear:
    [slush] No generator by name: “reloader” was found!
    [slush] Try installing it with npm install -g slush-reloader” first.

    Any idea why that happens?

    Kind regards,

    Fernando Fas

  • http://irinasokolovskaja.com Irina Sokolovskaja

    Hello Arvind, could you please help me with Slush generator problem?
    I use gulp-notify with lodash template in generated gulpfile. So I need the pipe in generated gulpfile look like this:

    .pipe(sass().on(‘error’, notify.onError({
    title: ‘SCSS error (in line )’,
    message: ”
    })))

    I get an error when scaffolding my project, because Slush tries to replace the gulp-notify template code with the prompts. Thanks in advance for any ideas how to fix this!

  • Shoaib UD-Din

    Getting error: var workingDirName = path.basename(process.cwd()),
    ReferenceError: path is not defined

    • http://thejackalofjavascript.com/ Arvind Ravulavaru

      Hello Shoaid. Not sure if the generator has changed. But you can check if

      is present in the js file.

      Thanks.

      • http://visualdecree.co.uk/ Mat Doidge

        I think they’ve updated slush. I’m now getting lots of errors including the one above. Fixing the above then gets me: ‘error is not defined’

        • http://thejackalofjavascript.com/ Arvind Ravulavaru

          Looks like there are quite a few changes. Can you tell me what error are you facing & when? I can try and propose a fix.

  • http://visualdecree.co.uk/ Mat Doidge

    Hi Arvind, brilliant tutorial. One question I have is; If I make update to my slush template and push to Git, does the npm publish command need to be re-ran or will npm pickup the changes?

    • http://thejackalofjavascript.com/ Arvind Ravulavaru

      Thanks Mat!

      Reg. your question, you need to manually run

      after updating the version in package.json.

  • YdnasErriep

    Hi

    i issu some crash in the generating process !! the error is there var username = string.toLowerCase(); the toLowerCase function seems to crash beceause username seems to be undefined(working on elementary luna) so if i comment the call for that function in default tash //userName: format(user.name) || osUserName, no crash everithing works great??have you ever get that error ?

    i like your writing style , great material again clear and precise

    peace

    • http://thejackalofjavascript.com/ Arvind Ravulavaru

      Hi @YdnasErriep:disqus – Thanks!

      Yes, this bug has creeped into the slush-generator in the last push. For now, you can do something like

      https://github.com/arvindr21/slush-ng/blob/master/slushfile.js#L20

      Thanks,
      Arvind.

      • YdnasErriep

        Thanks Arvind!

        • http://thejackalofjavascript.com/ Arvind Ravulavaru

          Thanks!

  • http://www.davidebarranca.com Davide Barranca

    Hi Arvind, thanks for this tutorial!!
    May I ask you to show a sub-generator example, please?
    I’m trying to find a way to automatically run a gulpfile (belonging to the scaffolded template – or gulp code from the very slushfile) after the files have been deployed.
    Thank you in advance!

    • http://thejackalofjavascript.com/ Arvind Ravulavaru

      Thanks David.

      In slush, a sub-generator is another gulp task. The way we invoke it will give you a “sense/feel” of a sub-generator.

      For example : slush-meanjs
      Here, the main generator scaffolds the core app and when the user wants to add a new MVC route, s/he can use a sub generator to scaffold/append the required files to existing project.

      To quickly guide you through it,
      1. My Slush file ( https://github.com/arvindr21/slush-meanjs/blob/master/slushfile.js#L23 ) consists of the defintion to the generator

      2. In the crud module generator, I have defined a gulp task ( https://github.com/arvindr21/slush-meanjs/blob/master/generators/crudModule.js#L2 ). Slush will take care of wrapping this task as a sub-generator.

      3. And finally when I want to invoke it, I will call the sub-generator as a “child” task like

      ( https://github.com/arvindr21/slush-meanjs#crud-module-sub-generator )

      In other words, any task named as default is the generator and other tasks as sub-generator.

      Hope this gave you an understanding as how to start off.

      Thanks!