Top Banner
Scaffolding in JavaScript March 2015 Tomi Vanek
53

JavaScript code generator with Yeoman

Jul 16, 2015

Download

Software

tomi vanek
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: JavaScript code generator with Yeoman

Scaffolding in JavaScriptMarch 2015

Tomi Vanek

Page 2: JavaScript code generator with Yeoman

Copyright © 2015 Accenture All rights reserved. 2

Tomi VanekSenior technology architect by Accenture

25+ years of experience

Current focus on modern web applications

Page 3: JavaScript code generator with Yeoman

Copyright © 2015 Accenture All rights reserved. 3Credit: Flickr, photo by Cedward Bricehttps://www.youtube.com/watch?v=2nMD6sjAe8I#t=134

Page 4: JavaScript code generator with Yeoman

Copyright © 2015 Accenture All rights reserved. 4

Page 5: JavaScript code generator with Yeoman

Copyright © 2015 Accenture All rights reserved. 5

- name must be prefixed by generator-.

- folder tree reflects available generators

generator-angular

|

|__ package.json

|

|__ generators

| |__ app

| | |__ index.js

| |

| |__ controller

| | |__ index.js

| |

| |__ directive

| |__ index.js

|

|__ templates

Initialization

Interaction

Configuration

Generation

Installation

End

Page 6: JavaScript code generator with Yeoman

Copyright © 2015 Accenture All rights reserved. 6

- name must be prefixed by generator-.

- folder tree reflects available generators

generator-angular

|

|__ package.json

|

|__ generators

| |__ app

| | |__ index.js

| |

| |__ controller

| | |__ index.js

| |

| |__ directive

| |__ index.js

|

|__ templates

Initialization

Interaction

Configuration

Generation

Installation

End

Page 7: JavaScript code generator with Yeoman

Copyright © 2015 Accenture All rights reserved. 7

• Start with extending from

• generators.Base for default generator

• generators.NamedBase for sub-generator

• Methods/functions are executed in the order

they are defined

• Private methods – use underscore or instance

method

• Execution phases:

• Initializing

• Prompting

• Configuring

• Default

• Writing

• Conflicts

• Install

• End

Initialization

Interaction

Configuration

Generation

Installation

End

Page 8: JavaScript code generator with Yeoman

Copyright © 2015 Accenture All rights reserved. 8

• Start with extending from

• generators.Base for default generator

• generators.NamedBase for sub-generator

• Methods/functions are executed in the order

they are defined

• Private methods – use underscore or instance

method

• Execution phases:

• Initializing

• Prompting

• Configuring

• Default

• Writing

• Conflicts

• Install

• End

Initialization

Interaction

Configuration

Generation

Installation

End

Page 9: JavaScript code generator with Yeoman

Copyright © 2015 Accenture All rights reserved. 9

• Start with extending from

• generators.Base for default generator

• generators.NamedBase for sub-generator

• Methods/functions are executed in the order

they are defined

• Private methods – use underscore or instance

method

• Execution phases:

• Initializing

• Prompting

• Configuring

• Default

• Writing

• Conflicts

• Install

• End

Initialization

Interaction

Configuration

Generation

Installation

End

Page 10: JavaScript code generator with Yeoman

Copyright © 2015 Accenture All rights reserved. 10

• Start with extending from

• generators.Base for default generator

• generators.NamedBase for sub-generator

• Methods/functions are executed in the order

they are defined

• Private methods – use underscore or instance

method

• Execution phases:

• Initializing

• Prompting

• Configuring

• Default

• Writing

• Conflicts

• Install

• End

Initialization

Interaction

Configuration

Generation

Installation

End

Page 11: JavaScript code generator with Yeoman

Copyright © 2015 Accenture All rights reserved. 11

var yg = require('yeoman-generator');

module.exports = yg.generators.Base.extend({

constructor: function(args, options) {

yg.generators.Base.apply(this, arguments);

},

greetDeveloper: function() {

this.log('Hello!');

},

createFiles: function() {

},

end: function() {

},

_helper: function() {

}

});

Initialization

Interaction

Configuration

Generation

Installation

End

Page 12: JavaScript code generator with Yeoman

Copyright © 2015 Accenture All rights reserved. 12

var yg = require('yeoman-generator');

module.exports = yg.generators.Base.extend({

constructor: function(args, options) {

yg.generators.Base.apply(this, arguments);

},

greetDeveloper: function() {

this.log('Hello!');

},

createFiles: function() {

},

end: function() {

},

_helper: function() {

}

});

Initialization

Interaction

Configuration

Generation

Installation

End

Page 13: JavaScript code generator with Yeoman

Copyright © 2015 Accenture All rights reserved. 13

var yg = require('yeoman-generator');

module.exports = yg.generators.Base.extend({

constructor: function(args, options) {

yg.generators.Base.apply(this, arguments);

},

greetDeveloper: function() {

this.log('Hello!');

},

createFiles: function() {

},

end: function() {

},

_helper: function() {

}

});

Initialization

Interaction

Configuration

Generation

Installation

End

Page 14: JavaScript code generator with Yeoman

Copyright © 2015 Accenture All rights reserved. 14

var yg = require('yeoman-generator');

module.exports = yg.generators.Base.extend({

constructor: function(args, options) {

yg.generators.Base.apply(this, arguments);

},

greetDeveloper: function() {

this.log('Hello!');

},

createFiles: function() {

},

end: function() {

},

_helper: function() {

}

});

Initialization

Interaction

Configuration

Generation

Installation

End

Page 15: JavaScript code generator with Yeoman

Copyright © 2015 Accenture All rights reserved. 15

var yg = require('yeoman-generator');

module.exports = yg.generators.Base.extend({

constructor: function(args, options) {

yg.generators.Base.apply(this, arguments);

},

greetDeveloper: function() {

this.log('Hello!');

},

createFiles: function() {

},

end: function() {

},

_helper: function() {

}

});

Initialization

Interaction

Configuration

Generation

Installation

End

Page 16: JavaScript code generator with Yeoman

Copyright © 2015 Accenture All rights reserved. 16

• Arguments

• yo angular:controller admin

var yg = require('yeoman-generator');

module.exports = yg.generators.NamedBase.extend({

constructor: function(args, options) {

yg.generators.NamedBase.apply(this, arguments);

},

displayName: function() {

this.log(‘Creating ' + this.name + 'Ctrl.');

}

});

Interaction

Initialization

Configuration

Generation

Installation

End

Page 17: JavaScript code generator with Yeoman

Copyright © 2015 Accenture All rights reserved. 17

• Arguments

• yo angular:controller admin

var yg = require('yeoman-generator');

module.exports = yg.generators.NamedBase.extend({

constructor: function(args, options) {

yg.generators.NamedBase.apply(this, arguments);

},

displayName: function() {

this.log(‘Creating ' + this.name + 'Ctrl.');

}

});

Interaction

Initialization

Configuration

Generation

Installation

End

Page 18: JavaScript code generator with Yeoman

Copyright © 2015 Accenture All rights reserved. 18

• Options

• yo angular --coffee --skip-install

var yg = require('yeoman-generator');

module.exports = yg.generators.Base.extend({

constructor: function(args, options) {

yg.generators.Base.apply(this, arguments);

},

createFiles: function() {

if (this.options['coffee']){

// use CoffeeScript templates

} else {

// use JavaScript templates

}

},

install: function() {

if (this.options['skip-install']) {

// don’t run installation

}

}

});

Interaction

Initialization

Configuration

Generation

Installation

End

Page 19: JavaScript code generator with Yeoman

Copyright © 2015 Accenture All rights reserved. 19

• Options

• yo angular --coffee --skip-install

var yg = require('yeoman-generator');

module.exports = yg.generators.Base.extend({

constructor: function(args, options) {

yg.generators.Base.apply(this, arguments);

},

createFiles: function() {

if (this.options['coffee']){

// use CoffeeScript templates

} else {

// use JavaScript templates

}

},

install: function() {

if (this.options['skip-install']) {

// don’t run installation

}

}

});

Interaction

Initialization

Configuration

Generation

Installation

End

Page 20: JavaScript code generator with Yeoman

Copyright © 2015 Accenture All rights reserved. 20

• Options

• yo angular --coffee --skip-install

var yg = require('yeoman-generator');

module.exports = yg.generators.Base.extend({

constructor: function(args, options) {

yg.generators.Base.apply(this, arguments);

},

createFiles: function() {

if (this.options['coffee']){

// use CoffeeScript templates

} else {

// use JavaScript templates

}

},

install: function() {

if (this.options['skip-install']) {

// don’t run installation

}

}

});

Interaction

Initialization

Configuration

Generation

Installation

End

Page 21: JavaScript code generator with Yeoman

Copyright © 2015 Accenture All rights reserved. 21

// list? What would you like to write scripts with?:

> JavaScript

CoffeeScript

// checkbox? Which modules would you like to include?:

> (•) angular-animate.js

( ) angular-cookies.js

(•) angular-route.js

( ) angular-touch.js

// confirm? Would you like to include Bootstrap?: (Y/n)

// expand? Overwrite bower.json?: (Ynaxdh) a

>> overwrite this and all others

Interaction

Initialization

Configuration

Generation

Installation

End

Page 22: JavaScript code generator with Yeoman

Copyright © 2015 Accenture All rights reserved. 22

• Prompts – via Inquirer.js• Asking questions

• Parsing

• Validation

• Hierarchical prompts

• Error handling

• Available prompt types• List

• Raw list

• Checkbox

• Confirm (y/n)

• Expand

• Input

• Password

Interaction

Initialization

Configuration

Generation

Installation

End

Page 23: JavaScript code generator with Yeoman

Copyright © 2015 Accenture All rights reserved. 23

askAboutAngularModules: function() {

var ngModules = [{

value: 'ngAnimate',

checked: true

},{

value: 'ngResource',

checked: false

},{

value: 'ngCookies',

checked: false }];

var cb = this.async();

this.prompt([

{

type: 'checkbox’,

name: ‘angularModules’,

message: ‘Which modules would you like to

include?’,

choices: ngModules

}

], function(answers) {

this.angularModules = nswers.angularModules;

cb()

}.bind(this));

}

Interaction

Initialization

Configuration

Generation

Installation

End

Page 24: JavaScript code generator with Yeoman

Copyright © 2015 Accenture All rights reserved. 24

askAboutAngularModules: function() {

var ngModules = [{

value: 'ngAnimate',

checked: true

},{

value: 'ngResource',

checked: false

},{

value: 'ngCookies',

checked: false }];

var cb = this.async();

this.prompt([

{

type: 'checkbox’,

name: ‘angularModules’,

message: ‘Which modules would you like to

include?’,

choices: ngModules

}

], function(result) {

this.angularModules = result.angularModules;

cb();

}.bind(this));

}

Interaction

Initialization

Configuration

Generation

Installation

End

Page 25: JavaScript code generator with Yeoman

Copyright © 2015 Accenture All rights reserved. 25

askAboutAngularModules: function() {

var ngModules = [{

value: 'ngAnimate',

checked: true

},{

value: 'ngResource',

checked: false

},{

value: 'ngCookies',

checked: false }];

var cb = this.async();

this.prompt([

{

type: 'checkbox’,

name: ‘angularModules’,

message: ‘Which modules would you like to

include?’,

choices: ngModules

}

], function(answers) {

this.angularModules = nswers.angularModules;

cb()

}.bind(this));

}

Interaction

Initialization

Configuration

Generation

Installation

End

Page 26: JavaScript code generator with Yeoman

Copyright © 2015 Accenture All rights reserved. 26

• Storing user configuration and sharing it

between sub-generators:• Source directory

• Bootstrap

• Routing option

• SASS/LESS

• HTML/Jade

• Path to custom templates

• etc.

• Configuration Persistence - API

• generator.config.save()

• generator.config.set()

• generator.config.get()

• generator.config.getAll()

• generator.config.delete()

• generator.config.defaults()

Interaction

Configuration

Initialization

Generation

Installation

End

Page 27: JavaScript code generator with Yeoman

Copyright © 2015 Accenture All rights reserved. 27

.yo-rc.json – yeoman configuration file

{

"generator-angular": {

"srcDir": "src/client",

"routing": "uiRouter",

"bootstrap": true,

"ngModules": [

"ngAnimate",

"ngSanitize",

"ngTouch"

],

"extensions": ["js", "html"]

},

"generator-node": {

"srcDir": "src/server",

"socketio": false,

"oauth": true

}

}

Interaction

Configuration

Initialization

Generation

Installation

End

Page 28: JavaScript code generator with Yeoman

Copyright © 2015 Accenture All rights reserved. 28

• Two location contexts:

• sourceRoot

• destinationRoot

• File path is relative to location contexts

• File utilities:

• template(source, dest [, data])

• copy(source, dest)

• dir(source, dest [, data])

• Template data – optional JS object

• If not provided – properties of `this` are used

• File conflict handling out of box

? Overwrite bower.json?: (Ynaxdh) a

>> overwrite this and all others

Interaction

Configuration

Generation

Initialization

Installation

End

Page 29: JavaScript code generator with Yeoman

Copyright © 2015 Accenture All rights reserved. 29

(function() {

'use strict';

angular

.module('<%= moduleName %>')

.directive('<%= name %>', [<%= name %>]);

/* @ngInject */

function <%= name %> () {

var directive = {

restrict: 'EA',

link: link,<% if (separateTemplate) { %>

templateUrl: '<%= templateUrl %>‘

<% } else { %>

template: '<div><%= name %></div>‘<% } %>

};

return directive;

function link(scope, element, attrs) {

element.text('<%= name %>');

}

}

})();

Interaction

Configuration

Generation

Initialization

Installation

End

Page 30: JavaScript code generator with Yeoman

Copyright © 2015 Accenture All rights reserved. 30

(function() {

'use strict';

angular

.module('<%= moduleName %>')

.directive('<%= name %>', [<%= name %>]);

/* @ngInject */

function <%= name %> () {

var directive = {

restrict: 'EA',

link: link,<% if (separateTemplate) { %>

templateUrl: '<%= templateUrl %>‘

<% } else { %>

template: '<div><%= name %></div>‘<% } %>

};

return directive;

function link(scope, element, attrs) {

element.text('<%= name %>');

}

}

})();

Interaction

Configuration

Generation

Initialization

Installation

End

Page 31: JavaScript code generator with Yeoman

Copyright © 2015 Accenture All rights reserved. 31

var yg = require('yeoman-generator');

module.exports = yg.generators.Base.extend({

constructor: function(args, options) {

yg.generators.Base.apply(this, arguments);

this.sourceRoot('../templates');

this.destinationRoot('.');

this.appName = 'myApp';

},

configFiles: function() {

this.copy('_editorconfig', '.editorconfig');

this.dir('code-analysis', '.');

this.dir('pkg-conf', '.', {name: 'demo'});

},

appModule: function() {

this.template('module/module.js_',

'src/client/app/app.module.js');

this.template('controller/ctrl.js_',

'src/client/app.controller.js',

{name: 'MyAppCtrl', appName: 'myApp')};

}

});

Interaction

Configuration

Generation

Initialization

Installation

End

Page 32: JavaScript code generator with Yeoman

Copyright © 2015 Accenture All rights reserved. 32

var yg = require('yeoman-generator');

module.exports = yg.generators.Base.extend({

constructor: function(args, options) {

yg.generators.Base.apply(this, arguments);

this.sourceRoot('../templates');

this.destinationRoot('.');

this.appName = 'myApp';

},

configFiles: function() {

this.copy('_editorconfig', '.editorconfig');

this.dir('code-analysis', '.');

this.dir('pkg-conf', '.', {name: 'demo'});

},

appModule: function() {

this.template('module/module.js_',

'src/client/app/app.module.js');

this.template('controller/ctrl.js_',

'src/client/app.controller.js',

{name: 'MyAppCtrl', appName: 'myApp')};

}

});

Interaction

Configuration

Generation

Initialization

Installation

End

Page 33: JavaScript code generator with Yeoman

Copyright © 2015 Accenture All rights reserved. 33

var yg = require('yeoman-generator');

module.exports = yg.generators.Base.extend({

constructor: function(args, options) {

yg.generators.Base.apply(this, arguments);

this.sourceRoot('../templates');

this.destinationRoot('.');

this.appName = 'myApp';

},

configFiles: function() {

this.copy('_editorconfig', '.editorconfig');

this.dir('code-analysis', '.');

this.dir('pkg-conf', '.', {name: 'demo'});

},

appModule: function() {

this.template('module/module.js_',

'src/client/app/app.module.js');

this.template('controller/ctrl.js_',

'src/client/app.controller.js',

{name: 'MyAppCtrl', appName: 'myApp')};

}

});

Interaction

Configuration

Generation

Initialization

Installation

End

Page 34: JavaScript code generator with Yeoman

Copyright © 2015 Accenture All rights reserved. 34

var yg = require('yeoman-generator');

module.exports = yg.generators.Base.extend({

constructor: function(args, options) {

yg.generators.Base.apply(this, arguments);

this.sourceRoot('../templates');

this.destinationRoot('.');

this.appName = 'myApp';

},

configFiles: function() {

this.copy('_editorconfig', '.editorconfig');

this.dir('code-analysis', '.');

this.dir('pkg-conf', '.', {name: 'demo'});

},

appModule: function() {

this.template('module/module.js_',

'src/client/app/app.module.js');

this.template('controller/ctrl.js_',

'src/client/app.controller.js',

{name: 'MyAppCtrl', appName: 'myApp')};

}

});

Interaction

Configuration

Generation

Initialization

Installation

End

Page 35: JavaScript code generator with Yeoman

Copyright © 2015 Accenture All rights reserved. 35

• Yeoman runs npm & bower install for you

• Spawn CLI commands

• Execute in 'install' or 'end' running context

_skippedInstl: function() {

if (this.options['skip-install']) {

this.log('Run npm install & bower install');

} else {

this.spawnCommand('grunt', ['wiredep']);

}

},

end: function() {

this.installDependencies({

skipInstall: this.options['skip-install'],

skipMessage: this.options['skip-message'],

callback: this._skippedInstl.bind(this)

});

}

Interaction

Configuration

Generation

Initialization

Installation

End

Page 36: JavaScript code generator with Yeoman

Copyright © 2015 Accenture All rights reserved. 36

• Yeoman runs npm & bower install for you

• Spawn CLI commands

• Execute in 'install' or 'end' running context

_skippedInstl: function() {

if (this.options['skip-install']) {

this.log('Run npm install & bower install');

} else {

this.spawnCommand('grunt', ['wiredep']);

}

},

end: function() {

this.installDependencies({

skipInstall: this.options['skip-install'],

skipMessage: this.options['skip-message'],

callback: this._skippedInstl.bind(this)

});

}

Interaction

Configuration

Generation

Initialization

Installation

End

Page 37: JavaScript code generator with Yeoman

Copyright © 2015 Accenture All rights reserved. 37

• Yeoman runs npm & bower install for you

• Spawn CLI commands

• Execute in 'install' or 'end' running context

_skippedInstl: function() {

if (this.options['skip-install']) {

this.log('Run npm install & bower install');

} else {

this.spawnCommand('grunt', ['wiredep']);

}

},

end: function() {

this.installDependencies({

skipInstall: this.options['skip-install'],

skipMessage: this.options['skip-message'],

callback: this._skippedInstl.bind(this)

});

}

Interaction

Configuration

Generation

Initialization

End

Installation

Page 38: JavaScript code generator with Yeoman

Copyright © 2015 Accenture All rights reserved. 38

Short summary of the result

Next manual steps

(i.e. on –skip-installation)

After running `npm install` & `bower install`, inject

your front end dependencies into your source code

by running: grunt wiredep

Interaction

Configuration

Generation

Initialization

Installation

End

Page 39: JavaScript code generator with Yeoman

Copyright © 2015 Accenture All rights reserved. 39

Short summary of the result

Next manual steps

(i.e. on –skip-installation)

After running `npm install` & `bower install`, inject

your front end dependencies into your source code

by running: grunt wiredep

Interaction

Configuration

Generation

Initialization

Installation

End

Page 40: JavaScript code generator with Yeoman

Copyright © 2015 Accenture All rights reserved. 40

Unit Tests

• Put each tested type of generator into separate describe block

• Mock user interaction and run generator in before block

• Test assertions in the it block

describe('angular generator', function() {

before(function(done) {

// run tested generator

done();

});

describe('should generate following files', function() {

it('bower.json', function() {

// assert the file exits

// assert correct file content

});

it('package.json', function() {

});

});

});

Page 41: JavaScript code generator with Yeoman

Copyright © 2015 Accenture All rights reserved. 41

Unit Tests

• Put each tested type of generator into separate describe block

• Mock user interaction and run generator in before block

• Test assertions in the it block

describe('angular generator', function() {

before(function(done) {

// run tested generator

done();

});

describe('should generate following files', function() {

it('bower.json', function() {

// assert the file exits

// assert correct file content

});

it('package.json', function() {

});

});

});

Page 42: JavaScript code generator with Yeoman

Copyright © 2015 Accenture All rights reserved. 42

Unit Tests

• Put each tested type of generator into separate describe block

• Mock user interaction and run generator in before block

• Test assertions in the it block

describe('angular generator', function() {

before(function(done) {

// run tested generator

done();

});

describe('should generate following files', function() {

it('bower.json', function() {

// assert the file exits

// assert correct file content

});

it('package.json', function() {

});

});

});

Page 43: JavaScript code generator with Yeoman

Copyright © 2015 Accenture All rights reserved. 43

Unit Tests

describe('angular generator', function() {

before(function(done) {

helpers.run(path.join(__dirname, '../generators/app')

.inDir(path.join(__dirname, './temp'), function(dir) {

})

.withArguments([]),

.withOptions({'coffee': false}),

.withPrompts({'bootstrap': true, 'routing': 'uiRouter'})

.on('ready', function(generator) {

generator.on('start', yoOutput.mute);

})

.on('end', function() {

yoOutput.unmute();

done();

});

});

describe('should generate following files', function() {

// test the assertions

});

});

Page 44: JavaScript code generator with Yeoman

Copyright © 2015 Accenture All rights reserved. 44

Unit Tests

describe('angular generator', function() {

before(function(done) {

helpers.run(path.join(__dirname, '../generators/app')

.inDir(path.join(__dirname, './temp'), function(dir) {

})

.withArguments([]),

.withOptions({'coffee': false}),

.withPrompts({'bootstrap': true, 'routing': 'uiRouter'})

.on('ready', function(generator) {

generator.on('start', yoOutput.mute);

})

.on('end', function() {

yoOutput.unmute();

done();

});

});

describe('should generate following files', function() {

// test the assertions

});

});

Page 45: JavaScript code generator with Yeoman

Copyright © 2015 Accenture All rights reserved. 45

Unit Tests

describe('angular generator', function() {

before(function(done) {

helpers.run(path.join(__dirname, '../generators/app')

.inDir(path.join(__dirname, './temp'), function(dir) {

})

.withArguments([]),

.withOptions({'coffee': false}),

.withPrompts({'bootstrap': true, 'routing': 'uiRouter'})

.on('ready', function(generator) {

generator.on('start', yoOutput.mute);

})

.on('end', function() {

yoOutput.unmute();

done();

});

});

describe('should generate following files', function() {

// test the assertions

});

});

Page 46: JavaScript code generator with Yeoman

Copyright © 2015 Accenture All rights reserved. 46

Unit Tests

describe('angular generator', function() {

before(function(done) {

// run tested generator

done();

});

describe('should generate following files', function() {

it('bower.json', function() {

// assert the file exits

assert.file('bower.json');

// assert correct file content

assert.fileContent('bower.json', /bootstrap/);

assert.noFileContent('bower.json', /angular-route/);

});

it('package.json', function() {

});

});

});

Page 47: JavaScript code generator with Yeoman

Copyright © 2015 Accenture All rights reserved. 47

Unit Tests

describe('angular generator', function() {

before(function(done) {

// run tested generator

done();

});

describe('should generate following files', function() {

it('bower.json', function() {

// assert the file exits

assert.file('bower.json');

// assert correct file content

assert.fileContent('bower.json', /bootstrap/);

assert.noFileContent('bower.json', /angular-route/);

});

it('package.json', function() {

});

});

});

Page 48: JavaScript code generator with Yeoman

Copyright © 2015 Accenture All rights reserved. 48

Modularization

• Subgenerators

this.composeWith('angular:controller', {

arguments: ['admin'],

options: {'matchingView': false}

}

};

• External generators

this.composeWith('karma', {}, {

local: require.resolve('generator-karma')

}

};

• Shared templates and utilities

Page 49: JavaScript code generator with Yeoman

Copyright © 2015 Accenture All rights reserved. 49

Modularization

• Subgenerators

this.composeWith('angular:controller', {

arguments: ['admin'],

options: {'matchingView': false}

}

};

• External generators

this.composeWith('karma', {}, {

local: require.resolve('generator-karma')

}

};

• Shared templates and utilities

Page 50: JavaScript code generator with Yeoman

Copyright © 2015 Accenture All rights reserved. 50

Modularization

• Subgenerators

this.composeWith('angular:controller', {

arguments: ['admin'],

options: {'matchingView': false}

}

};

• External generators

this.composeWith('karma', {}, {

local: require.resolve('generator-karma')

}

};

• Shared templates and utilities

Page 51: JavaScript code generator with Yeoman

Copyright © 2015 Accenture All rights reserved. 51

• Enterprise IT, BPM, B2B

• DevOps

• API, WS

• Language, DSL

• Model-Driven Development

• Runtime Code Generation

• Scaffold

• Project Seed

• Framework, Platform, SDK

• Runtime Module, Component, Library

• Copy-Paste

• Hand-Written Code

Scaffolding in Model-Driven Architecture

Page 52: JavaScript code generator with Yeoman

Copyright © 2015 Accenture All rights reserved. 52

• Asynchronous callbacks in conditional execution

• Post-write to files

• OS-specific path

• Naming

• Simplicity vs rich configurability

Pitfalls

Page 53: JavaScript code generator with Yeoman

Copyright © 2015 Accenture All rights reserved. 53

Questions

Scaffolding in JavaScript

Yeoman code generator

tomi vanek

software architect