With so many great tools available to front-end Mobile App developers these days it can sometimes be difficult to understand how they all fit together. Deciding on a workflow that you’re happy with is often a very personal endeavour, but getting started isn’t always easy. Yeoman aims to solve this problem by defining a workflow for creating modern mobile applications, while at the same time mixing in many of the best practices that have evolved within the industry. In this blog post you’re going to learn how to harness the power Yeoman Generator to create fantastic mobile applications.
The Components of Yeoman Generator
Yeoman is an app scaffolding tool that helps you kickstart new projects, prescribing best practices and tools to help you stay productive. Yeoman provides a workflow to improve productivity and ease of development.
Yeoman itself comprises of three main components:-
Yo
: Yo is a tool that’s used to scaffold a new application. It can create common project assets like stylesheets and JavaScript files. Basically, Yo provides an easy way to create all of the boilerplate code you need to get started on a project.Grunt/Gulp
: The Grunt task runner is a tool that can automate things like compiling Sass files or optimizing images. When used as part of the Yeoman package, Grunt handles building, testing, and reviewing your project.Bower
: Bower is a package manager for the web. It helps to manage the dependencies needed for your application so you don’t have to download them manually.
Each of these tools is developed independently but all have great communities pushing their continued advancement.
Install prerequisites
Before installing Yeoman, you will need the following:
- Node.js v4 or higher
- npm (which comes bundled with Node)
- git
You can check if you have Node and npm installed by typing:
node --version && npm --version
Steps of Yeoman Generator:
Step 1: Install Yeoman
Not every new computer comes with a Yeoman pre-installed. He lives in the npm package repository. You only have to ask for him once, then he packs up and moves into your hard drive. Make sure you clean up, he likes new and shiny things.
npm install -g yo
It is a good idea to check that everything is installed as expected by running commonly used Yeoman commands like yo with the –version flag as follows:
yo --version
Step 2: Install the Generator
Yeoman travels light. He didn’t pack any generators when he moved in. You can think of a generator like a plug-in. You get to choose what type of application you wish to create, such as a Backbone application or even a Chrome extension.
Install generator-android
:
npm install -g generator-android
Make a new directory and cd
into it:
mkdir my-shiny-project && cd $_
Finally, initiate the generator:
$ yo android
This will create a fully functioning Android app skeleton.
After it you will get the index.js file. You can change this file as per your requirement.
'use strict';
var yeoman = require('yeoman-generator');
var chalk = require('chalk');
var yosay = require('yosay');
var path = require('path');
/**
* Functionally the same as directory however applies templating if file name begins with an underscore (_).
*
* @param source
* @param destination
*/
function templateDirectory(source, destination) {
var root = this.isPathAbsolute(source) ? source : path.join(this.sourceRoot(), source);
var files = this.expandFiles('**', { dot: true, cwd: root });
for (var i = 0; i < files.length; i++) {
var f = files[i];
var src = path.join(root, f);
if(path.basename(f).indexOf('_') == 0){
var dest = path.join(destination, path.dirname(f), path.basename(f).replace(/^_/, ''));
this.template(src, dest);
}
else{
var dest = path.join(destination, f);
this.copy(src, dest);
}
}
}
module.exports = yeoman.generators.Base.extend({
initializing: function () {
this.pkg = require('../package.json');
this.templateDirectory = templateDirectory.bind(this);
},
prompting: function () {
var done = this.async();
// Have Yeoman greet the user.
this.log(yosay(
'Welcome to the rad ' + chalk.red('Android Starter') + ' generator!'
));
var prompts = [{
name: 'name',
message: 'What are you calling your app?',
store: true,
default : this.appname // Default to current folder name
},
{
name: 'package',
message: 'What package will you be publishing the app under?',
store: true
},
{
name: 'targetSdk',
message: 'What Android SDK will you be targeting?',
store: true,
default: 23 // Android 6.0 (Marshmallow)
},
{
name: 'minSdk',
message: 'What is the minimum Android SDK you wish to support?',
store: true,
default: 15 // Android 4.0 (Ice Cream Sandwich)
}];
this.prompt(prompts, function (props) {
this.appName = props.name;
this.appPackage = props.package;
this.androidTargetSdkVersion = props.targetSdk;
this.androidMinSdkVersion = props.minSdk;
done();
}.bind(this));
},
configuring: {
saveSettings: function() {
this.config.set('appPackage', this.appPackage);
}
},
writing: {
projectfiles: function () {
this.copy('gitignore', '.gitignore');
this.copy('_build.gradle', 'build.gradle');
this.copy('gradle.properties', 'gradle.properties');
this.copy('gradlew', 'gradlew');
this.copy('gradlew.bat', 'gradlew.bat');
this.copy('settings.gradle', 'settings.gradle');
this.template('_README.md', 'README.md');
this.directory('gradle', 'gradle');
},
app: function () {
var packageDir = this.appPackage.replace(/./g, '/');
this.mkdir('app');
this.copy('app/gitignore', 'app/.gitignore');
this.copy('app/proguard-rules.pro', 'app/proguard-rules.pro');
this.template('app/_build.gradle', 'app/build.gradle');
this.mkdir('app/src/androidTest/java/' + packageDir);
this.templateDirectory('app/src/androidTest/java', 'app/src/androidTest/java/' + packageDir);
this.templateDirectory('app/src/androidTest/res', 'app/src/androidTest/res');
this.mkdir('app/src/env_prod/java/' + packageDir);
this.templateDirectory('app/src/env_prod/java', 'app/src/env_prod/java/' + packageDir);
this.mkdir('app/src/env_test/java/' + packageDir);
this.templateDirectory('app/src/env_test/java', 'app/src/env_test/java/' + packageDir);
this.templateDirectory('app/src/env_test/res', 'app/src/env_test/res');
this.mkdir('app/src/main/assets');
this.mkdir('app/src/main/java/' + packageDir);
this.directory('app/src/main/assets', 'app/src/main/assets');
this.template('app/src/main/_AndroidManifest.xml', 'app/src/main/AndroidManifest.xml');
this.templateDirectory('app/src/main/java', 'app/src/main/java/' + packageDir);
this.templateDirectory('app/src/main/res', 'app/src/main/res');
this.mkdir('app/src/debug');
this.template('app/src/debug/_AndroidManifest.xml', 'app/src/debug/AndroidManifest.xml');
}
}
});
Step 3: Run it
Once you’ve generated the skeleton app simply import into Android Studio/IntelliJ as a Gradle project, perform a Gradle sync and then run!
Conclusion
The pace at which new tools and frameworks are being made available is staggering. This inherently means that our development workflows are always evolving so that we can take advantage of the best tools on offer. The thing I like most about Yeoman is its ability to adapt. By creating an ecosystem of generators it’s easy to start using new frameworks and libraries whilst keeping a relatively consistent workflow.
References
- Yeoman: Set up your dev environment for Yeoman Generator
- Yeoman Generators: Yeoman Generator for any platform