List of Local Tech Groups

Written by Anthony DeBonis on . Posted in Productivity

Techvalley/Albany/Capital Regions Groups Events

www.meetup.com

http://nextplex.com/tech-valley-ny

 

Google Developer Group of the Capital Region TBD TBD Apprenda Troy NY or Informz Saratoga Spring NY
https://www.meetup.com/Google-Developer-Group-of-the-Capital-Region/
Startup TechVally 1st Wednesday 12/7/2016 Brown’s Brewing Revolution Hall, Troy NY
http://startuptechvalley.org/events/
Javascript UG 2nd Wednesday TBD Enable Labs in Troy NY
https://www.meetup.com/capital-district-javascript/
Captialt Area SQL Server User Group 2nd Monday 11/24/2014 AutoTask East Greenbush NY
https://www.meetup.com/Capital-Area-SQL-Server-User-Group/
Techvalley .Net Group – Tuesday night 3rd Tuesday 11/15/2016 Tyler Technologies Albany NY by Airport
https://www.meetup.com/TechValleyNETUserGroup/
Startup Grind Albany Tuesday 11/15//2016 RPI Tech Park East Greenbush NY
https://www.meetup.com/Startup-Grind-Albany/
CEG – Venture B – Tuesday AM at 7:30AM RPI Tuesday 11/15/2016 RPI, Troy NY
http://www.ceg.org/economic_development/entrepreneurship/venture-bplan/
Berkshire County Technology Group Tuesday 11/15/2016 Pittsfield MA
https://www.meetup.com/Berkshire-County-Technology-Group/
Albany Chapter of 1 Million Cups Wednesday 11/16/2016 Albany Barn Albany NY
https://www.meetup.com/Albany-Chapter-Of-1-Million-Cups/
Sharatoga Techtalks Wednesday 11/16/2016 Saratoga Springs NY
https://www.meetup.com/Sharatoga-TechTalks/
Tech Valley Ruby Brigade Wednesday 11/16/2016 Enable Labs in Troy NY
https://www.meetup.com/Tech-Valley-Ruby-Brigade/
Techvalley Game Space Many Days 11/18/2016 Center of Gravity Troy NY
https://www.meetup.com/TechValleyGameSpace/
Albany 2600 Meetup Friday 12/2/2016 Starbucks Albany
https://www.meetup.com/Albany-2600/events/235207143/
Albany UX Group TBD TBD All over the area
https://www.meetup.com/albany-ux/
Capital Region Test Automated Group TBD TBD All over the area
https://www.meetup.com/AutomationRocks/

Using Grunt to Auto-Restart node.js with File Watchers

Written by Russell on . Posted in App Dev, Deployment, Front End, Productivity, Software

Preprocessors have become a very important part of the development life cycle. In the past we would just write some HTML, JavaScript and CSS with a backend and deploy a website.  Now for better speed, development experience and more manageable outcomes we have a multitude of languages that compile into these standards, e.g: CoffeeScript–> JavaScript, LESS –> CSS, Jade –> HTML… Then there is JS, CSS and HTML compression and minification after that.

Creating a development workflow to manage all of these transformations can be a very daunting task at the beginning of a new project. The complexity of the workflow can can also make or break a project. When ever I try to solve a problem I always try to look at the difficulty curve of reproduction and repeatability. In other words, it shouldn’t be difficult to setup a new developer on the project and it should be easy to perform 1k times a day without a work-performance loss.

Grunt has become a very important part of our  development life cycles. For compiled projects such as Java, adding in Grunt from ANT or Maven is relatively simple to in-line. For our node.js projects we wanted to be able to not only run the node server, but we wanted to be able to auto-restart the process while also auto-building resource files like LESS and JS files. Below you will find a lengthy Grunt file with commentary interlaced. This should help you get started with your own development environment.

'use strict';

module.exports = function(grunt) {
    grunt.initConfig({
        /**
            The concurrent task will let us spin up all of required tasks. It is very 
            important to list the 'watch' task last because it is blocking and nothing 
            after it will be run.
        **/
        concurrent: {
            dev: ["less:dev", "nodemon", "watch"],
            options: {
                logConcurrentOutput: true
            }
        },

        /**
            The nodemon task will start your node server. The watch parameter will tell 
            nodemon what files to look at that will trigger a restart. Full grunt-nodemon 
            documentation
        **/
        nodemon: {
            dev: {
                script: 'index.js',
                options: {
                    /** Environment variables required by the NODE application **/
                    env: {
                          "NODE_ENV": "development"
                        , "NODE_CONFIG": "dev"
                    },
                    watch: ["server"],
                    delay: 300,

                    callback: function (nodemon) {
                        nodemon.on('log', function (event) {
                            console.log(event.colour);
                        });

                        /** Open the application in a new browser window and is optional **/
                        nodemon.on('config:update', function () {
                            // Delay before server listens on port
                            setTimeout(function() {
                                require('open')('http://127.0.0.1:8000');
                            }, 1000);
                        });

                        /** Update .rebooted to fire Live-Reload **/
                        nodemon.on('restart', function () {
                            // Delay before server listens on port
                            setTimeout(function() {
                                require('fs').writeFileSync('.rebooted', 'rebooted');
                            }, 1000);
                        });
                    }
                }
            }
        },

        /**
            Watch the JS and LESS folders for changes. Triggering 
            fires off the listed tasks
        **/
        watch: {
            js: {
                files: ["client/resources/less/**/*.js"],
                tasks: ['copy:dev:custom'],
                options: { nospawn: true, livereload: true }
            },
            less: {
                files: ["client/resources/less/**/*.less"],
                tasks: ['less'],
                options: { nospawn: true, livereload: true }
            }
        },

        /** 
            Less task to compile LESS into CSS.
            Different options for dev and prod
        **/
        less: {
            dev: {
                options: {
                    compress: false,
                    yuicompress: false,
                    strictMath: true,
                    strictUnits: true,
                    strictImports: true
                },
                files: lessFiles
            }, 
            prod: {
                options: {
                    compress: true,
                    yuicompress: true,
                    strictMath: true,
                    strictUnits: true,
                    strictImports: true
                },
                files: lessFiles
            }
        },

        /**
            Used for production mode, minify and uglyfy the JavaScript Output
        **/
        uglify: {
            prod: {
                options: {
                    mangle: true,
                    compress: true,
                    sourceMap: true,
                    drop_console: true
                },
                files: {
                    'client/public/js/main.js': ['client/resources/js/main.js']
                }
            }
        },

        /**
            This copy tasks has two parts. The libraries will be rarely updated and are 
            only copied on startup. The custom sub-task will copy over application specific 
            JS since it doesn't need a preprocessor in dev
        **/
        copy: {
            dev: {
                custom: {
                    files: [
                        {
                            src: ["client/public/js/*.js"], 
                            dest: "client/public/js", 
                            expand: true, 
                            flatten: true
                        }
                    ]
                },
                libs: {
                    files: [
                      /** 
                        Array of file objects that reference bower libs }}
                      **/
                    ]
                }
            }
        }
    });

    /**
        Load all the GRUNT tasks
    **/
    grunt.loadNpmTasks("grunt-nodemon");
    grunt.loadNpmTasks("grunt-concurrent")
    grunt.loadNpmTasks("grunt-contrib-copy")
    grunt.loadNpmTasks("grunt-contrib-less")
    grunt.loadNpmTasks("grunt-contrib-watch");
    grunt.loadNpmTasks("grunt-contrib-uglify");

    /**
        Register tasks allowing you to run:
            grunt
            grunt run
            grun dev
            grun prod
    **/
    grunt.registerTask("run", ["concurrent:dev"]);
    grunt.registerTask("default", ["concurrent:dev"]);

    grunt.registerTask("dev", ["less:dev", "copy:dev"]);
    grunt.registerTask("prod", ["uglify:prod", "less:prod"]);
};

You will need to add a few requirements to your packages.json file to pull in the new requrements

    "devDependencies": {
          "open": "*"
        , "grunt-nodemon": "*"
        , "grunt-concurrent": "*"
        , "grunt-contrib-copy": "*"
        , "grunt-contrib-less": "*"
        , "grunt-contrib-watch": "*"
        , "grunt-contrib-uglify": "*"
    }