{"id":14616,"date":"2014-07-06T01:10:32","date_gmt":"2014-07-05T19:40:32","guid":{"rendered":"http:\/\/www.tothenew.com\/blog\/?p=14616"},"modified":"2015-07-09T15:26:56","modified_gmt":"2015-07-09T09:56:56","slug":"easy-app-scaffolding-with-yeoman","status":"publish","type":"post","link":"https:\/\/www.tothenew.com\/blog\/easy-app-scaffolding-with-yeoman\/","title":{"rendered":"Easy app scaffolding with Yeoman"},"content":{"rendered":"<p><img decoding=\"async\" loading=\"lazy\" class=\"aligncenter size-full wp-image-14624\" src=\"\/blog\/wp-ttn-blog\/uploads\/2014\/12\/yeoman-logo.png\" alt=\"yeoman-logo\" width=\"374\" height=\"324\" \/><\/p>\n<p>Ever wondered that the most time consuming tasks are the one you have done numerous times on numerous projects, and why the hell am i doing it again?<\/p>\n<p>The most basic of examples of this is <strong>Scaffolding<\/strong> an app, you have to do a lot of things, repetitive things to get the app structure up to speed. This is an even bigger problem with NodeJS projects, and they do not have a sort of <em>&#8220;Pre-defined \/ Fixed structure&#8221;<\/em> if i may.<\/p>\n<p>But that may be the thing of the past, because there&#8217;s a new sheriff in town, to get the burden off of all your trivial and important task related stuff, and do so with the ease and panache that will make you a believer.<\/p>\n<p><code>Routing<\/code>, <code>Dependency management<\/code>, <code>packaging<\/code>, <code>deployment<\/code> all taken care of by this nifty tool, which should be in every developers tool kit.<\/p>\n<h2>What is Yeoman?<\/h2>\n<p><strong>Yeoman<\/strong> 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.<\/p>\n<p>Yeoman itself comprises of three main components:-<\/p>\n<p><img decoding=\"async\" class=\"aligncenter size-full wp-image-14623\" src=\"\/blog\/wp-ttn-blog\/uploads\/2014\/12\/yeoman.png\" alt=\"yeoman\" width=\"500\" \/><\/p>\n<ul>\n<li><strong><code>Grunt\/Gulp<\/code><\/strong> : The build system to build\/preview\/test your app<\/li>\n<li><strong><code>Bower<\/code><\/strong> : Frontend dependency management tool<\/li>\n<li><strong><code>Yeoman<\/code><\/strong> : for scaffolding out apps, writing grunt tasks and bower dependencies<\/li>\n<\/ul>\n<h2>Enough talk! Show me the code<\/h2>\n<p>In order to use <strong>Yeoman<\/strong> you need to have <code>NodeJS<\/code> installed, <code>NodeJS<\/code> comes with the super awesome <code>NPM (Node Package Manager)<\/code> which allows us to use many such tools as <strong>Yeoman<\/strong>, <strong>Grunt<\/strong> and <strong>Bower<\/strong>.<\/p>\n<p>Assuming you have <strong>NodeJS<\/strong> Installed, install <strong>Yeoman<\/strong> as follows:<\/p>\n<p>[js]<br \/>\nnpm install -g yo<br \/>\n[\/js]<\/p>\n<p>The <code>-g<\/code> denotes that this module will be installed globally and will be available from the command-line. Sweet.<\/p>\n<p>Now, <strong>Yeoman<\/strong> is a very versatile tool, i.e. its functionality can be extended by anyone, this is possible because of the integration of something called <code>Generators<\/code> which allow yeoman to scaffold apps quickly.<\/p>\n<p>There are a lot of generators available, for multiple languages and frameworks, Frontend, backend etc.<\/p>\n<p>Since <a title=\"node.js Development\" href=\"http:\/\/www.tothenew.com\/mean-node-js-development-consulting\">we already have node installed<\/a>, why not scaffold a <code>NodeJS<\/code> app complete with full <code>AngularJS<\/code> integration.<\/p>\n<p>Generators are the fuel of Yeoman, to build our app we&#8217;ll use a generator called <code>generator-angular-fullstack<\/code> complete with <code>MongoDB<\/code>, <code>Mongoose<\/code>, <code>SocketIO<\/code>, <code>Passport<\/code> integration out of the box \ud83d\ude09<\/p>\n<p>Let&#8217;s install it now:<\/p>\n<p>[js]<br \/>\nnpm install -g generator-angular-fullstack<br \/>\n[\/js]<\/p>\n<p>This will install your generator to be used by yeoman. Next we need to create a project directory in which <strong>Yeoman<\/strong> will scaffold our app.<\/p>\n<p>[js]<br \/>\nmkdir my-yeoman-project<br \/>\ncd my-yeoman-project<br \/>\n[\/js]<\/p>\n<p>Let&#8217;s generate our app by running the <code>angular-fullstack<\/code> with <code>yo<\/code>:<\/p>\n<p>[js]<br \/>\nyo angular-fullstack<br \/>\n[\/js]<\/p>\n<p>This will launch you into a interactive app configuration setup, where you can easily add\/remove options upon your own requirements.<\/p>\n<p>It will ask you certain configuration for both client and server:<\/p>\n<p><strong>Client<\/strong><\/p>\n<p># <code>Scripts<\/code> &#8211; Javascript \/ Coffeescript<br \/>\n# <code>Markup<\/code> &#8211; HTML \/ Jade<br \/>\n# <code>Stylesheets<\/code> &#8211; CSS \/ Sass \/ Less<br \/>\n# <code>Angular router<\/code> &#8211; ngRoute \/ uiRouter<\/p>\n<p><strong>Server<\/strong><\/p>\n<p># <code>Use MongoDB with Mongoose<\/code> &#8211; (Requires mongodb installed and running)<br \/>\n# <code>Basic Authentication<\/code> &#8211; Add basic Login \/ Register schemes<br \/>\n# <code>Additional OAuth Strategies using Passport<\/code> &#8211; Google \/ Facebook \/ Twitter<br \/>\n# <code>SocketIO<\/code><\/p>\n<p><a href=\"\/blog\/wp-ttn-blog\/uploads\/2014\/12\/step8-edit.jpg\"><img decoding=\"async\" loading=\"lazy\" width=\"992\" height=\"470\" class=\"aligncenter size-full wp-image-14626\" src=\"\/blog\/wp-ttn-blog\/uploads\/2014\/12\/step8-edit.jpg\" alt=\"Configuration Steps\" \/><\/a><\/p>\n<p>All this will give us a directory structure like following:<\/p>\n<p>[js]<br \/>\n_<br \/>\n\u251c\u2500 client<br \/>\n\u2502  \u251c\u2500 app              &#8211; App specific components<br \/>\n\u2502  \u251c\u2500 assets           &#8211; Custom assets: fonts, images, etc\u2026<br \/>\n\u2502  \u251c\u2500 components       &#8211; Our reusable components<br \/>\n\u2502<br \/>\n\u251c\u2500 e2e                 &#8211; Protractor end to end tests<br \/>\n\u2502<br \/>\n\u2514\u2500 server<br \/>\n   \u251c\u2500 api              &#8211; Our apps server api<br \/>\n   \u251c\u2500 auth             &#8211; For handling authentication<br \/>\n   \u251c\u2500 components       &#8211; Our reusable or app-wide components<br \/>\n   \u251c\u2500 config           &#8211; Where we do the bulk of our apps configuration<br \/>\n   \u2502   \u2514\u2500 local.env.js &#8211; Environment variables<br \/>\n   \u2502   \u2514\u2500 environment  &#8211; Configuration specific to the node environment<br \/>\n   \u2514\u2500 views            &#8211; Server rendered views<\/p>\n<p>[\/js]<\/p>\n<p>With all the required Grunt tasks to <code>combine<\/code>, <code>minify<\/code>, <code>building<\/code> etc. and cleanly written <code>angular components<\/code> and <code>services<\/code> to help us quickly get started.<\/p>\n<h2>Even more ..<\/h2>\n<p>The above app structure is really good because we only have a limited number of files within an <code>Entity<\/code>, there can be multiple entities with separate controllers, models etc.<\/p>\n<p>Now how do i add more entities, surely copying and pasting the files would be one way to do it, but folks at yeoman have this covered as well.<\/p>\n<p>The backend entities are called endpoints, which include the <code>controllers<\/code>, <code>models<\/code> (with full CRUD impemented), and <code>RESTful<\/code> routing. To add more endpoints we simply have to tell <code>yeoman<\/code> to generate it for us, like so:<\/p>\n<p>[js]<br \/>\nyo angular-fullstack:endpoint your-endpoint-name<br \/>\n[?] What will the url of your endpoint to be? (\/api\/your-endpoint-name)<br \/>\n   create server\/api\/your-endpoint-name\/index.js<br \/>\n   create server\/api\/your-endpoint-name\/your-endpoint-name.controller.js<br \/>\n   create server\/api\/your-endpoint-name\/your-endpoint-name.model.js<br \/>\n   create server\/api\/your-endpoint-name\/your-endpoint-name.socket.js<br \/>\n   create server\/api\/your-endpoint-name\/your-endpoint-name.spec.js<br \/>\n[\/js]<\/p>\n<p>This will create a number of files for us to use directly including <code>tests<\/code> and <code>SocketIO<\/code> file (if configured).<\/p>\n<p>In fact there are many commands for us to do a number of tasks, both for generating code templates for Backend as well as the frontend.<\/p>\n<p><strong>Angular Routes<\/strong><\/p>\n<p>[js]<br \/>\nyo angular-fullstack:route myroute<br \/>\n[?] Where would you like to create this route? client\/app\/<br \/>\n[?] What will the url of your route be? \/myroute<\/p>\n<p>   create client\/app\/myroute\/myroute.js<br \/>\n   create client\/app\/myroute\/myroute.controller.js<br \/>\n   create client\/app\/myroute\/myroute.controller.spec.js<br \/>\n   create client\/app\/myroute\/myroute.html<br \/>\n   create client\/app\/myroute\/myroute.scss<br \/>\n[\/js]<\/p>\n<p><strong>Angular Controller<\/strong><\/p>\n<p>[js]<br \/>\nyo angular-fullstack:controller user<br \/>\n[?] Where would you like to create this controller? client\/app\/<br \/>\n   create client\/app\/user\/user.controller.js<br \/>\n   create client\/app\/user\/user.controller.spec.js<br \/>\n[\/js]<\/p>\n<p><strong>Directives \/ filters<\/strong><\/p>\n<p>[js]<br \/>\nyo angular-fullstack:directive myDirective<br \/>\n[?] Where would you like to create this directive? client\/app\/<br \/>\n[?] Does this directive need an external html file? Yes<br \/>\n   create client\/app\/myDirective\/myDirective.directive.js<br \/>\n   create client\/app\/myDirective\/myDirective.directive.spec.js<br \/>\n   create client\/app\/myDirective\/myDirective.html<br \/>\n   create client\/app\/myDirective\/myDirective.scss<br \/>\n[\/js]<\/p>\n<p>[js]<br \/>\nyo angular-fullstack:filter myFilter<br \/>\n[?] Where would you like to create this filter? client\/app\/<br \/>\n   create client\/app\/myDirective\/myFilter.filter.js<br \/>\n   create client\/app\/myDirective\/myFilter.filter.spec.js<br \/>\n[\/js]<\/p>\n<p>Similar commands for <code>Services<\/code>, <code>decorators<\/code> etc.<\/p>\n<h2>Running \/ Testing<\/h2>\n<p>To run our app we dont need to do anything special, Grunt will figure this out ..<br \/>\nwe simply have to do:<\/p>\n<p>[js]<br \/>\n\/\/DEVELOPMENT<br \/>\ngrunt serve<\/p>\n<p>\/\/DISTRIBUTION\/PRODUCTION ENV<br \/>\ngrunt serve:dist<br \/>\n[\/js]<\/p>\n<p>This will run our app with desired environment and even open up a browser for us \ud83d\ude09 cool huh!<\/p>\n<p><strong>Running tests<\/strong><\/p>\n<p>To run all our tests run:<\/p>\n<p>[js]<br \/>\n\/\/RUN ALL THE TESTS<br \/>\n grunt test<\/p>\n<p>\/\/ONLY SERVER TESTS<br \/>\ngrunt test:server<\/p>\n<p>\/\/ONLY CLIENT TESTS<br \/>\ngrunt test:client<br \/>\n[\/js]<\/p>\n<p>Simple \ud83d\ude42<\/p>\n<h2>Deployment<\/h2>\n<p>All the code written means nothing if it&#8217;s not deployed. Yeoman also provides us extremely simple deployment options.<\/p>\n<p>Yeoman currently provides easy deployment for <code>OpenShift<\/code> and <code>Heroku<\/code>. To deploy to either of these services just do:<\/p>\n<p>[js]<br \/>\n\/\/HEROKU<br \/>\nyo angular-fullstack:heroku <\/p>\n<p>\/\/OPENSHIFT<br \/>\nyo angular-fullstack:openshift<br \/>\n[\/js]<\/p>\n<p>(Assuming all the configuration is already done once)<\/p>\n<p>All the power <code>Yeoman<\/code> provides us is extremely overwhelming at first, but once you get in the groove, it is a brilliant and nifty little tool in our development workflow which help us save time and energy and allows us to focus on important tasks and problems.<\/p>\n<p>Learn more about <a title=\"Yeoman\" href=\"http:\/\/yeoman.io\/\">Yeoman<\/a> and <a title=\"Generator-fullstack\" href=\"https:\/\/github.com\/DaftMonk\/generator-angular-fullstack\">angular-fullstack<\/a>.<\/p>\n<p>Till next time,<br \/>\nCiao<\/p>\n","protected":false},"excerpt":{"rendered":"<p>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.<\/p>\n","protected":false},"author":85,"featured_media":14624,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"iawp_total_views":3},"categories":[1185],"tags":[955,1467,1466,1177,1303,1468,1469],"aioseo_notices":[],"_links":{"self":[{"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/posts\/14616"}],"collection":[{"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/users\/85"}],"replies":[{"embeddable":true,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/comments?post=14616"}],"version-history":[{"count":0,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/posts\/14616\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/media\/14624"}],"wp:attachment":[{"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/media?parent=14616"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/categories?post=14616"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/tags?post=14616"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}