Showing posts with label nodejs. Show all posts
Showing posts with label nodejs. Show all posts

2014-09-18

Pyramid starter seed template powered by Yeoman (part 2)

In the previous blog post we have seen what are the benefits of using the Yeoman workflow fully integrated with a web development framework like Pyramid. See:

Now we'll add more technical details about:
  • how to install pyramid_starter_seed and its prerequisites

How to install pyramid_starter_seed

    Prerequisites

    As you can imagine, nodejs tools are required.

    I strongly suggest to:
    • avoid system packages because they are too old
    • install nodejs with nvm (Node Version Manager)
    I won't cover the nodejs installation but it is quite simple if you follow these instructions provided by this useful link:
    The nvm achronym stands for NodeJS Version Manager. Once installed nvm, installing nodejs it is as simple as typing nvm install VERSION (at this time of writing 0.10.32).

    Nodejs is shipped with the command line utility named npm (Nodejs Package Manager) and we will use npm for installing what we need.

    We need to install our global (-g option) dev dependencies, so just type:
    $ npm install -g bower
    $ npm install -g grunt-cli
    $ npm install -g karma

    Starter seed project installation

    Create an isolated Python environment as explained in the official Pyramid documentation and instal Pyramid.

    Once installed you can clone pyramid_starter_seed from github:
    $ git clone git@github.com:davidemoro/pyramid_starter_seed.git
    $ cd pyramid_starter_seed
    $ YOUR_VIRTUALENV_PYTHON_PATH/bin/python setup.py develop
    Not finished yet, continue.

    Yeoman initialization

    Go to the folder where it lives our Yeoman project and initialize it.

    These are the standard commands (but, wait a moment, see the "Notes and known issues" subsection):
    $ cd pyramid_starter_seed/webapp
    $ bower install
    $ npm install --loglevel verbose
    Known issues:
    • if you are behind a proxy you'll have to configure properly npm
    • if you have a slow internet connection you might experience timeout problems.

    Build phase

    Just type:
    $ grunt
    and... probably it will fail because of a couple of known issues shipped with the latest version of generator-webapp or its dependencies.

    Probably these issues will be fixed in newer generator-webapp releases. However here it is how to solve these problems, so don't worry:
    1. grunt-contrib-imagemin fix
      Problem with grunt:
      Warning: Running "imagemin:dist" (imagemin) task
      Warning: Bad argument Use --force to continue.
      Solution:
      $ npm cache clean
      $ rm -fR node_modules       # not sure it is needed, don't remember
      $ npm install grunt-contrib-imagemin
    2. Mocha/PhantomJS issue
    Problem with Mocha/PhantomJS launching grunt
    Warning: PhantomJS timed out, possibly due to a missing Mocha run() call. Use --force to continue.
    Solution:
    $ cd test
    $ bower install
    Run bower install in the test directory of webapp (pyramid_starter_seed/webapp/test). This is a known issue, see https://github.com/yeoman/generator-webapp/issues/446.

    Run you Pyramid app

    Now can choose to run Pyramid in development or production mode.
    Just type:
    $ YOUR_VIRTUALENV_PYTHON_PATH/bin/pserve development.ini
    or:
    $ YOUR_VIRTUALENV_PYTHON_PATH/bin/pserve production.ini
    Done!


    In the next blog post with topic Pyramid + Yeoman (coming soon) I'm going to talk about:
    • how to manage things with grunt and personalize pyramid_starter_seed registering other assets
    • how to clone pyramid_starter_seed. Yes, you can easily customize it creating something of more sophisticated and create your own starter seed with another name. Without having to write a package generator
     So stay tuned..

    Links

    2014-09-16

    Pyramid starter seed template powered by Yeoman (part 1)

    Book of the month I'm reading this summer: Pylons/Pyramid (http://docs.pylonsproject.org/en/latest).


    Pyramid (http://www.pylonsproject.org) is a minimal Python-based web development framework that let you "start small and finish big".

    It stole a lot of (good) ideas and concepts from other mature Python web frameworks and it is build with the pluggable and extensible concepts in mind. Read: no need to fork applications.

    Furthermore Pyramid is database and template engine agnostic: you are free.

    From the very beginning Pyramid allows you to become productive quickly. So why not start with something of useful?

    Pyramid + Yeoman

    The goal of this experiment is integrate yeoman with Pyramid (or other frameworks like NodeJs/Express with AngularJS or Plone as already did), preserving the yeoman's workflow.

    UPDATE 20140926: here you can see a Plone + AngularJS + Yeoman article (collective.angularstarter)

    In this article I'll talk about what are the benefits you get integrating your Pyramid app with Yeoman, in future posts I'll discuss how they work under the hood with additional technical details omitted here (each used component deserves an entire blog post).

    Yeoman
    You might wonder why? Because of the importance of tooling. Since it is very important build an effective developer tooling ecosystem, I want to integrate the simple starter demo app with commonly used tools to help you stay productive. So this simple application prototype it is just an experiment that should help you to integrate with modern web development tools provided by the yeoman workflow stack (http://yeoman.io).

    Choosing the right tools is very important for the best develop experience and I cannot work anymore without Yeoman, especially when coding with Javascript.

    Grunt
    Yeoman it is internally based on three important components (nodejs powered):
    • yo, scaffolding tool like pcreate, paster or zopeskel. It is widely adopted by a large and trasversal community
    • grunt, system used for build, preview and test your software. Gulp is another popular option
    • bower, used for dependency management, so that you no longer have to manually download and manage your scripts
    Bower

    So with the yeoman's tools you can just code, avoid annoying repetitive tasks and don't worry about:
    • javascript testing setup
    • javascript code linting
    • javascript/css minification and merging
    • image minification
    • html minification
    • switch to CDN versions of you vendor plugins in production mode
    • auto-reload browser
    • much much more
    So let's see together what happened to our pyramid starter demo template created with pcreate -t starter integrated with a yeoman's generator-webapp project.

    The result will be a Pyramid starter seed project integrated with modern non Python-based web development tools.

    Goals

    Management of third party assets

    You no longer have to manually download and manage your scripts with the Bower package manager.

    From http://bower.io:
    """Bower works by fetching and installing packages from all over, taking care of hunting, finding, downloading, and saving the stuff you’re looking for."""
    So just type something like: bower install angular-translate --save and you'll get the rigth resource with pinning support.

    Tasks automation

    Automation, automation, automation.

    From http://gruntjs.com:
    """Why use a task runner? In one word: automation. The less work you have to do when performing repetitive tasks like minification, compilation, unit testing, linting, etc, the easier your job becomes. After you've configured it, a task runner can do most of that mundane work for you—and your team—with basically zero effort."""
    Examples:
    • grunt serve
    • grunt test
    • grunt build
    • grunt YOUR TASK 
    • etc

    Jslint

    No more deploy Javascript code with bad indentation, syntax errors or bad code practices.

    All syntax errors or bad practise will be found.

    Image minification

    The build process will detect and minify automatically all your asset images.

    Uncss task

    Modern (and heavy) UI frameworks like Twitter Bootstrap provide an excellent solution for prototyping your initial project, but most of the times you are using a very minimal subset of their functionalities.

    https://twitter.com/davidemoroThis inspiring Addy Osmani's blog post helps you to remove unused css in your pages with a grunt task named grunt-uncss (https://github.com/addyosmani/grunt-uncss):
    The original not-minified bootstrap.css weights in at 120 kB before removing unused rule.

    Css concat and minification

    You can split your css code into different files and then the build process will concat and minify them creating a unique app.css file. This way you write modular and better readable css files, reducing the number of browser requests.

    The theme.css file is quite small but in real projects you can save more. In this case:
    The configured build pipeline is concat, uncss and cssmin. 122.85 kB (original bootstrap.css) -> 4.64 kB (uncss) -> 3.45 kB (minification)

    Automatic CDN-ification

    It is handy using unminified versions of third party javascript libraries during development and switch to CDN versions in production mode with well known benefits for your website.

    Don't worry: the cdnify task will take care about this boring issue. Automatically.

    You save a boring manual and error-prone configuration.

    Composable bootstrap.js version

    The Pyramid starter project is based on Twitter Bootstrap.

    Twitter Bootstrap
    Depending on your project you can load the whole Twitter Bootstrap Javascript code at once or including individual plugins.

    As you can see the Javascript component of Twitter Bootstrap is very modular: http://getbootstrap.com/javascript. So if you don't use a particular feature, just don't include it.

    This way in development mode you will have all individual plugins splitted in different files, in production it will served a unique concatenated and minified Javascript file built automatically.

    So if you just need alert.js and dropdown.js you can get a 2.79 kB plugins.js:

    The concatenation of alert.js and dropdown.js produces a 7.06 kB, that weight in at 2.79 kB after minification instead of the 8.9 kB (gzipped) bootstrap-min.js corresponding to not gzipped 27.2 kB.

    Html (template) minification

    Since the ZPT/Chameleon templating language is an extension of HTML with xml syntax,

    Brower are able to display unrendered ZPT/Chameleon templates
    theorically it can play well with html minificators.

    I know, template minification can lead to potential unexpected problems due to minification issues on template files... but this is my personal playground, so let me play please!

    So... why not switch to a pre-compiled minified template of your ZPT/Chameleon files when you are in "production mode"?

    Obviously during development you will use the original template files.

    The interesting side of this approach is that there is no overhead at response time, since the minification task runs just one time before deploying your application. It might be an option if you want just your html minified and you cannot feasibly add to your site or project additional optimization tools at web server level.

    Anyway I have tried this mad experiment and... if you don't use too aggressive minification params, it seems to work fine with good results. Try it at your own risk or just disable it. Here you can the effects on the generated index.html used in production:
    Template minified (7.62 kB -> 4.16 kB)

    Result: a lighter Pyramid

    Same results but a lighter Pyramid app:

    Let's see how it behave the standard Pyramid starter project:
    Standard Pyramid starter project (production.ini)
    And the Pyramid starter seed:
    Pyramid starter seed (production.ini)
    As you can see the seed version is ~38 Kb smaller and more performant.

    Useful links

    That's all?

    No, you can do more, for example:
    • reduce the  number or requests (for example you can merge vendor.css and app.css)
    • create and keep updated css sprites with grunt (https://github.com/Ensighten/grunt-spritesmith)
    • manage and upload all your assets to professional services like Amazon AWS (for example you can serve up all your images, styles and scripts from a S3 bucket + CloudFront). This way Pyramid will be able to handle more requests. Pyramid let you put static media on a separate webserver during production with static_url() in conjunction with add_static_view(), without having to change your templates code
    • generate static gzipped assets with Grunt and let your webserver serve them
    • install and configure dedicated performance modules at webserver level (Apache's mod_pagespeed)
    Let me know what you think about that, please. Hope soon I will manage to write the second part of this blog post explaining how I did it. In the mean time you can:

    Links

    2014-04-16

    Keystonejs CMS

    I've just installed KeystoneJS (http://keystonejs.com), a Nodejs CMS based on Mongodb and optional storage policies for binaries like images or files.

    First impression? I like it :)

    You only need to install NodeJs (NVM is your friend) and a MongoDB instance. After that you will be able to install it locally on your machine typing a couple of commands if you use the official generator-keystone Yeoman generator. Otherwise you can start from scratch as well.

    After that no extra work is needed, open http://localhost:3000 in your browser and add new categories or blob posts. Or if you want you can deploy and host your application into the cloud on Paas platform.


    Shortly:
    • you can create your own content types with a defined schema
    • admin UI automatically generated (add forms, edit forms)
    • supports logged in users and session management
    • form validations
    • dynamic routes
    • email sending
    • very basic workflow support (just what you need for a simple publishing experience)
    • you can switch to alternative template engines (default: Jade... nooo, I don't like it!)
    • easy customizable templates for object views and listing (just html)
    • mobile ready
    • indexing and search support (no advanced features like pdf-text extraction and indexing)
    • Paas ready for hosting solutions
    • no folder-aware conceps (for example blog items are just reachable from the /blob/posts/blog-slug, you cannot nest items in folders. But it is ok for a wide range of applications)
    • editable slug urls
    • different storage policies for images and files
      • CloudinaryImage(s) for automatically manages images stored in Cloudinary, including uploading, resizing and deleting. See http://cloudinary.com/
      • LocalFile, this field type is not compatible with PAAS hosts like Heroku https://www.heroku.com because it relies on the local file system
      • S3, automatically manages files stored in Amazon S3, including uploading and deleting (http://aws.amazon.com/s3/)
      • AzureFile, automatically manages files stored in Windows Azure Storage, including uploading and deleting
    Not supported (or not yet):
    • advanced, configurable and generic workflow engine
    • field level security on content types
    • configurable portlet items or user defined boxes
    • not sure, no out of the box minification assets solutions for css and javascripts when you switch to production mode? (more or less something like already discussed on this old blog post hack http://davidemoro.blogspot.it/2013/08/yeoman-express-and-angularjs.html)
    So if you compare its features with enterprise level CMS like Plone (http://plone.org) you might think that it is a very simple CMS solution.

    But you should not consider it just like a CMS but as a simple but flexible framework for creating NodeJS/ExpressJS/MongoDB based generic web applications with an autogenerated UI. You can save a lot of time!

    It is a very young project and I don't know if it will become the nodejs killer app but the approach sounds very good and probably it is the most advanced CMS solution based on NodeJS at this time of writing.

    Very cool guys, keep up the good work!

    2014-03-28

    yeoman-generator's template() now accept a forth parameter being the _.templateSettings

    We are talking about yeoman generators with custom _templateSettings rules.

    Sometimes when you are using underscore.js or lodash templates you have to change how parameters and expressions will be interpolated.

    You might want to do so because the syntax of your generated file does not fit the templateSettings defaults (example: you get a lodash/underscore template error like "SyntaxError: Unexpected token :") or you just want to use another syntax to interpolate vars or expressions.

    How can you do that with yeoman?

    Starting from 0.17.0-pre.1 prerelease version the yeoman-generator's template() accept a forth parameter being the _.templateSettings (see https://github.com/yeoman/generator/releases/tag/v0.17.0-pre.1).

    Here you can find an example about how to use custom _.templateSettings rules in a custom yeoman generator created with generator-generator (see http://yeoman.io/generators.html).

    Note well: this post won't talk about how to create a custom generator. You can find more information about this topic following the official yeoman guide. Anyway installing generator-generator is as simple as typing the following command:
    $ npm install -g yo generator-generator
    (after doing that you can have a coffee and/or brush your cat’s fur since it might requires a long time depending on your network or machine)

    So let's see how it works!

    app/index.js

    The template method usage is similar to the older versions of yeoman-generator except a richer signature:
    function template(source, destination, data, options)
    where the fourth parameter is an object to be used as _.templateSettings. For example here it is a working example:
    this.template('_buildout.cfg',
                  'buildout.cfg',
                   this,
        {
            evaluate: /\{\{([\s\S]+?)\}\}/g,
            interpolate: /\{\{=([\s\S]+?)\}\}/g,
            escape: /\{\{-([\s\S]+?)\}\}/g
        });

    app/templates/_buildout.cfg

    This is our _buildout.cfg template, you can populate values using the {{}} syntax. In this particular case we are building the download url of mongodb depending on the user input (mongodbVersion). For example:
    [buildout]
    ...
    # Do not remove this: <%= mongodbVersion %>
    recipe = rod.recipe.mongodb
    darwin-32bit-url = http://downloads.mongodb.org/...-{{=mongodbVersion}}.tgz
    You might wonder why there is still a line with <%= mongodbVersion %>. It seems to be necessary because without this line this prerelease version of yeoman-generator will produce the unrendered output. See https://github.com/yeoman/generator/issues/517.

    With this workaround all works fine, probably it won't be necessary in future versions.

    Example usage


    Results

    The resulting buildout.cfg contents will be similar to the following lines, depending on the user input:
    [buildout]
    ...
    [mongodb]
    ...
    # Do not remove this: <%= mongodbVersion %>
    recipe = rod.recipe.mongodb
    darwin-32bit-url = http://downloads.mongodb.org/osx/mongodb-osx-i386-2.4.9.tgz
    The rendered file will be used to install and configure automatically the given version of mongodb.

    Done

    First of all: feedback, please!

    And... I think to write a second part of this blog post talking about how this particular generator works under the hood (a yeoman based mongodb installer based internally on a widely used build system for creating, assembling, configuring and deploying applications). So if you are pretty curious stay tuned on @davidemoro for future write ups.

    20140407: see http://davidemoro.blogspot.com/2014/04/yeoman-generator-mongodb-installer.html fur further information.

    2013-08-24

    Deploy your nodeJS/Express app to AppFog Paas

    AppFog is a cloud based "platform as a service" (PaaS) that let you run your web applications, even on private clouds.
    It supports different technologies and offers a lot of installable plugins or services. Therefore no matters if you have to deploy a Python, Django, Java, NodeJS, PHP app based on MongoDB, MySQL, Redis and so on.

    Appfog does not force you to change your devel habits: you can develop locally your app as usual and then deploy it with just one command as we will see. The main philosophy is: "work on code, not management".

    At this time appfog supports the following versions:
    • Python (2.7.3)
    • NodeJS (0.8.14, 0.6.17, 0.4.12)
    • PHP (5.3.10)
    • Ruby (1.8.7, 1.9.3, 1.9.2)
    • Java (1.7.0)
    You can choose the supported environment you prefer. Obviously for the most reliable development experience, make sure you have the same version on your local development environment.

    Can't wait for trying AppFog?

    Here it is the basic getting started playing with the console offline:
    1. sign up to http://console.appfog.com/signup 
    2. install the appfog af command line interface https://docs.appfog.com/getting-started/af-cli 
    Now you can play as well with the AppFog console online as shown here https://docs.appfog.com/getting-started/jumpstarts but I suggest to have a look at the command line syntax.

    All you need to know is covered in the docs area https://docs.appfog.com but we we'll see the most useful commands right now.

    In the next sections we will consider a NodeJS / Express app as example, so let's start with NodeJS, Express and AppFog now.

    NodeJS installation

    Talking about NodeJS, you might use the Node Version Manager (NVM) to manage multiple Node.js versions as described in this article http://codetheory.in/using-node-version-manager-nvm-to-manage-multiple-node-js-versions/. Installing the right version of NodeJS is as simple as typing the command:
    $ nvm install NODE_VERSION (for example: 0.8.14)

    Create your app NodeJS/Express app

    Now you can develop locally your app as usual with Node and Express.
    If you want to create a hello world application you can start using the express executable or starting from scratch. Both of the above options are described in this guide http://expressjs.com/guide.html

    Or if you prefer you can start with an app generated by one of the available yeoman's generators. You can see the full list of the yeoman's community generators: http://yeoman.io/community-generators.html.
    You can use a specific yeoman's express generator or choosing another one that fits better your needs and then add the Express dependency by hand. For this post I'll use as reference the hello world app based on Yeoman/Node/Express/AngularJS/generator-angular shown in this previous post:
    Once created your NodeJS/Express app as usual you need to perform some small changes.

    Make your app compatible with AppFog

    It's quite simple.

    Firstly make sure you have provided the start command under the scripts key in your package.json file, for example:
      "scripts": {
        "test": "grunt test",
        "start": "node app.js"
      }
    If you don't provide the start command AppFog runs the first of the following files it finds:
    • server.js
    • app.js
    • index.js
    • main.js
    • application.js
    After that you need to change the listen port of your app: AppFog passes the listen port for your app in an environment variable, accessed by process.env.VCAP_APP_PORT. So depending on how it is organized your app.js, you need to change the listend port:
    -app.set('port', process.env.PORT || 3000);
    +app.set('port', process.env.VCAP_APP_PORT || 3000);
    AppFog requires also a manifest file named manifest.yml, but don't worry: the first time you push your app there will be an interactive prompt as you will see in the next section.

    Now you are ready to deploy your app to AppFog.

    Deploy your app to AppFog

    Since AppFog supports npm shrinkwrap (see https://npmjs.org/doc/shrinkwrap.html for more details), before pushing your app you might want to lock down the versions of your package's dependencies: this way you can control exactly which versions of each dependency will be used when your package is installed in the AppFog cloud.

    It requires you just one command:
    $ npm shrinkwrap
    wrote npm-shrinkwrap.json
    Now we are close to pushing our app. Basically you have to login using the credentials typed during the sign up process. It is very simple as you can see:
    $ af login
    Attempting login to [https://api.appfog.com]
    Email: YOUREMAIL
    Password: *********************
    Successfully logged into [https://api.appfog.com]
    Type the push command with the interactive prompt:
    $ af push
    Would you like to deploy from the current directory? [Yn]: Y
    Application Name: YOURAPP
    Detected a Node.js Application, is this correct? [Yn]: Y
    1: AWS US East - Virginia
    2: AWS EU West - Ireland
    3: AWS Asia SE - Singapore
    4: HP AZ 2 - Las Vegas
    Select Infrastructure: 2
    Application Deployed URL [YOURAPP.eu01.aws.af.cm]:
    Memory reservation (128M, 256M, 512M, 1G, 2G) [64M]:
    How many instances? [1]:
    Create services to bind to 'YOURAPP'? [yN]: N
    Would you like to save this configuration? [yN]: y
    Manifest written to manifest.yml.
    Creating Application: OK
    Uploading Application:
      Checking for available resources: OK
      Processing resources: OK
      Packing application: OK
      Uploading (800K): OK 
    Push Status: OK
    Staging Application 'YOURAPP': OK                                         
    Starting Application 'YOURAPP': OK
    The generated manifest.yml file is similar to the following:
    $ cat manifest.yml
    ---
    applications:
      .:
        mem: 64M
        framework:
          info:
            description: NodeJS, Express, AngularJS Application
            exec:
            mem: 64M
          name: node
        instances: 1
        url: ${name}.${target-base}
        infra: eu-aws
        name: YOURAPP
    If you need to do some future changes you should run the af update command instead.

    Done, your app is online at http://YOURAPP.eu01.aws.af.cm!

    If you have some tips or suggestions let me know please.

    Additional notes

    Errors during push or upload

    Sometimes you may experiment this error trying to update or pushing your app:

    HTTP exception: RestClient::ServerBrokeConnection:Server broke connection:
    After a quick search on the net it seems a recurring problem and, if it happens, it may persist for a lot of hours or several days. Probably it is due to overload issues. I don't think it's related to a code problem because sometimes it works.

    Fortunately it was only an annoying problem in my case because it was just a hello world app but... you can image if you are in a hurry and you have to update your business app what a problem!

    AppFog guys, please let me know if I'm doing something of wrong!

    Anyway if you experiment similar problems see https://www.appfog.com/support/

    Update 20130825: the problem seems to be fixed for me using the --no-resource option (for example: af update --no-resource). This option is not listed at all in the af --help command. Now the update command works fine, good! Hope it might help other people this experience.
    If you have other troubles you can visit the Node section of AppFog troubleshooting page https://docs.appfog.com/troubleshooting

    Environment vars

    You must notice that AppFog supports environment vars.

    These will be accessible to your app at runtime. You can specify data that you do not want in your source code like passwords, API keys, or differentiate between staging and production environments.

    Since also Express supports arbitrary environments, like production and development, you can use the configure method to set different configurations under the different environments.

    For example in production mode you may use images, css and js minified, disabling devel settings, etc.

    You can add environment vars through the web using the console online or via command line:
    $ af env-add YOURAPP status=production
    Adding Environment Variable [status=production]: OK
    Stopping Application 'YOURAPP': OK
    Staging Application 'YOURAPP': OK                                      
    Starting Application 'YOURAPP': OK 
    Update 20130825: you can get your env app with process.env.YOURENVVAR.
      

    Quickstart

    If you are not familiar with Node, Express, yeoman&co and you want to have a try, you can start from this hello world I presented in this previous post:
    You should perform these actions:
    1. git clone git@github.com:davidemoro/express-angular.git
    2. $ cd express-angular
    3. change your manifest.yml and other files that reference the old app name (grep is your friend)
    4. $ npm install
    5. $ bower install
    6. $ af login
    7. $ af push
    If you want to enable the production mode you should type:
    1. $ grunt build
    2. $ af update
    3. $ af env-add YOURAPP status=production
    Let me know if you find some problems.

    Links

    2013-08-04

    Yeoman, Express and AngularJS

    I'm a great fan of yeoman: it provides for free a lot of goodies that let you easily bootstrap and managing an application. Tests setup, minification, dependencies manager, script automation, etc: using the yeoman workflow you can save a lot of time, being more productive and following the best devel practices.

    I already used yeoman for AngularJS applications: now I want to build a NodeJS/Express application powered by AngularJS with all the goodies provided by yeoman.

    And... before searching for and trying an existing express-angularjs yeoman generators I'd like to do it by hand, just for fun and for diving into NodeJS/grunt & co.

    AngularJS setup with yo

    Start with creating and empty dir as suggested on this StackOverflow question http://stackoverflow.com/questions/14106248/yeoman-inside-expressjs:
    $ mkdir express-angular
    $ cd express-angular
    Then launch the angular generator:
    $ yo angular --minsafe
    If you want you can init this folder with git.

    Express initialization

    After that rename the package.json because it will be replaced soon by the express init command:
    $ mv package.json package_yo.json
    And init this folder with express:
    $ express -e -f .
    The -e option stands for using the ejs template engine, the -f will force the overwrite of existing files.

    Now you can launch a diff on the package.json files and merge the differences. After that you can get rid of the temporary package_yo.json.
    This way we won't lost the devDependencies and other setups that let your grunt routines works fine.

    Now launch the following commands
    $ npm install
    $ node app -> run on port 3000
    Express server listening on port 3000
    If you open a browser on http://localhost:3000 you will see a working Express view.

    But... this is not what we want, where are the view provided by the AngularJS generator? Wait a moment.

    Express integration with AngularJS

    Now let's tell Express to use the AngularJS views created by yo.
    Firstly you can get rid of public and views dirs needed by Express because we will use the app folder generated by yo.
    $ rm -fR public
    $ rm -fR views
    You have also to edit the app.js:
    ...
     // all environments
     app.set('port', process.env.PORT || 3000);
    -app.set('views', __dirname + '/views');
     app.set('view engine', 'ejs');
    +app.engine('html', require('ejs').renderFile);
     app.use(express.favicon());
     app.use(express.logger('dev'));
     app.use(express.bodyParser());
    ...

     app.use(express.methodOverride());
     app.use(app.router);
    -app.use(express.static(path.join(__dirname, 'public')));

     // development only
     if ('development' == app.get('env')) {
    +app.set('views', __dirname + '/app');
     
    +  app.use(express.static(path.join(__dirname, 'app')));
       app.use(express.errorHandler());
     }
    +else {
    +app.set('views', __dirname + '/dist'); 
    +  app.use(express.static(path.join(__dirname, 'dist')));
    +}
    ...
    Let me explain, we are doing the following things:
    • get rid of the /views, we will use the app/ folder with the yeoman templates
    • get rid of the public dir, we will use the app dir for serving the resources or the dist if you are on a production environment
    • we are telling Express to map the EJS template engine to ".html" files. This way you can avoid to rename the app/index.html file. See http://expressjs.com/api.html#app.engine for more info
    Now let's modify the app/index.html putting some EJS flavour.
    ...
       <head>
         <meta charset="utf-8">
         <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
    -    <title></title>
    +    <title><%= title %></title>
         <meta name="description" content="">
    ...
    The title var will use what it's provided by routes/index.js.

    Now we have to change the routes/index.js also in order to avoid problems (we are using index.html instead of index.ejs):
     exports.index = function(req, res){
    -  res.render('index', { title: 'Express' });
    -};
    +  res.render('index.html', { title: 'Express AngularJS app' });
    +};
    And now if you re-run the "node app" you will see your Express-based angularJS application, so it works!

    As you will see the work is not finished.

    Fix grunt build

    Well, but what about grunt tasks provided by yeoman? Let's try:
    $ grunt
        Warning: Running "htmlmin:dist" (htmlmin) task
        File dist/404.html created.
        Warning: app/index.html
        Parse Error: <%= title %></title>
    ... ouch! What happened? The htmlmin task failed trying to parse the Ejs statements.

    So, before finishing we have to apply a few changes to our Gruntfile.js:
        concurrent: {
          server: [
            'coffee:dist'
          ],
          test: [
            'coffee'
          ],
          dist: [
            'coffee',
            'imagemin',
    -        'svgmin',
    +        'svgmin'
    +        //'htmlmin'

          ]
        },
    ...
        // Put files not handled in other tasks here
        copy: {
          dist: {
            files: [{
              expand: true,
              dot: true,
              cwd: '<%= yeoman.app %>',
              dest: '<%= yeoman.dist %>',
              src: [
                '*.{ico,png,txt}',
    +            '*.html', 'views/*.html',
                '.htaccess',
                'bower_components/**/*',
                'images/{,*/}*.{gif,webp}',
                'styles/fonts/*'
              ]
    In the changes above we just disabled the htmlmin task and add the *.html files stuff to the copy section.

    Finished? Not yet!

    Grunt server and livereload

    Now the grunt command will work fine, even the build task. If you run "node app" all it's fine but running "grunt server" you may notice that the page title is not "Express AngularJS app" as expected but "<%= title %>".

    What's the matter? The Gruntfile.js is not aware about Express so it needs some extra love and the grunt-express task can help you! See the grunt-express readme for more info https://github.com/blai/grunt-express.

    Basically you'll have to do these things:
    • install grunt-express with a "npm install grunt-express --save-dev"
    • add a module.exports to your app.js. This is required by grunt-express if you want to avoid a "Fatal error: Server should provide a function called "listen" that acts as http.Server.listen"
    • modify your Gruntfile.js replacing the connect/livereload stuff with the grunt-express task
    This way the "grunt server" command will run Express with live reload enabled.
    Here you can see the most significant part of Gruntfile.js, basically you'll have to comment the connect/livereload stuff and adding the following lines:
        express: {
          options: {
            port: 9000,
            // Change this to '0.0.0.0' to access the server from outside.
            hostname: 'localhost'
          },
          livereload: {
            options: {
              server: path.resolve('./app.js'),
              livereload: true,
              serverreload: false,
              bases: [path.resolve('./.tmp'), path.resolve(__dirname, yeomanConfig.app)]
            }
          },
          test: {
            options: {
              server: path.resolve('./app.js'),
              bases: [path.resolve('./.tmp'), path.resolve(__dirname, 'test')]
            }
          },
          dist: {
            options: {
              server: path.resolve('./app.js'),
              bases: path.resolve(__dirname, yeomanConfig.dist)
            }
          }
        },
    For the full list of changes you can see this package as reference: https://github.com/davidemoro/express-angular. Note: I had to set the serverreload option to false because it didn't worked for me.

    Done!

    Here you can see the result:
    Notes: I'm quite new to these arguments because I come from the Python, Zope and Plone world, so let me know if you have some hints!

    Links