Sunday, March 12, 2017

Visual Studio Code Tips and Tricks March 2017 - Working with Node

Debugging like a pro

Add a launch configuration to enable Node debugging.

{
    // Use IntelliSense to learn about possible Node.js debug attributes.
    // Hover to view descriptions of existing attributes.
    // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
    "version""0.2.0",
    "configurations": [

        {
            "type""node",
            "request""launch",
            "cwd""${workspaceRoot}",
            "name""API",
            "program""${workspaceRoot}/service/lib/hapi/index.js",
            "env": {
                "JWT_SECRET""hapi land",
                "FE_HOSTNAME""https://localhost",
                "MONGODB_CONFIG""mongodb://localhost/mydb"
            }
        }
    ]
}

You can have more than one launch config and browser support is available.

Documentation with JSDoc

VSCode enables JSDoc all over the editor with intellisense, in version 1.10, type /** to add a JSDoc annotation.
/**
 * Verifies authorizations
 * @param {string} accessRequest - The ACL in context
 * @param {string} configPre - The name of the prereq containing the config
 * @param {boolean}   denyUnauthorization - Returns 401 if unauthorized
 */
exports.checkAuthorizations = (accessRequest, configPre, denyUnauthorization) =>
    (request, reply) => { ... }

Quick Actions

These work like code refactoring, just like Resharper and Visual Studio. 


Debugger pane and console

Like Chrome Inspector, you get access to a REPL console, Variables, Watch, Call Stack, Breakpoints and some other nice things like auto display of a variable value.


Sunday, April 12, 2015

rutha - past, present and what's next

Origins

The fact that rutha is based in Hapi and Angular is a weird story. A while ago I worked for Admios who back then had a outsourcing service to a Santa Barbara cloud computing brokerage startup (or a grown up one at least).

The fashion trends back then was Backbone, so we build from zero to one a whole framework using Backbone, Underscore and Grunt, with Bootstrap as CSS theme and NodeJS running the boilerplate.

I had probably the best time building and using all these new things. Then Angular showed up. 


Don't you call this a regular jam
I'm gonna rock this land
I'm gonna take this itty bitty world by storm
And I'm just getting warm

 - Mama Said Knock You Out - LL Cool J

Being this a team focused on value, we might had tried to sell our boilerplate with workshops or presentations. But Angular was being supported by Google and in the end time to market is the rule in most places.

By the end of outsourcing gig, our 2 years tech baby was already "legacy".

One of the engineers went to another place and we tried to get the code open source but it never got traction. At least we tried.

In the meantime, I started using Express and Angular to learn what the fuss was all about. I think I figure out I needed a mentor so I asked my good friend Edgar to teach me. It worked. And it was like taking the pill to the rabbit hole.

Ah roomie zoom zim, I'm off to be wed
To Rhymealinda I remember umm, when we first met
In eighty-two back in school used to play up all the fools

 - 4 better or 4 worse - The Pharcyde

And I kind of disliked Express. It was like Sinatra all over again, spend time finding out good, community supported gems to get a good, web boilerplate. Somehow I stumble upon Hapi and remembered my good old days of ASP.NET. Comparing what I'd in Express vs what (in theory) could be accomplished, I was stuck. And the journey to rule them all Hapi and Angular began.

Present

With 100 commits and version stuck at 1.0.0, we have over 20 likes and over 300 page views, I can say the idea that started around August 2014 has worked. Currently, we have 3 projects using it and hopefully more. Our time to market has been reduced and developers can focus on Hapi and Angular and forget about tooling.

What's Next

Our roadmap will focus on pragmatism over bleeding edge patterns and trends, with two exceptions: ES6 and Angular 2.

Things we are considering and would like feedback

  • Client side modules: We might moved to all npm, it depends on how easy is to get ES6 with angular.
  • API CLI: For Hapi APIs, is something I see useful.
  • John Papa/Todd Motto ng conventions CLI
  • Sample apps
  • Mobile First: Is very likely we'll take a NativeScript or Kendo UI Mobile approach. 

Thanks
Rogelio Morrell and rutha team

Friday, February 6, 2015

rutha - A Hapi and Angular boilerplate stack

Introduction

Rutha is a simple, one of many, Hapi boilerplate stack that  uses AngularJS as default client side technology. The basic premise is that it contains npm modules that handles the Grunt tasks, Mongo migrations (yes we are MEAN oriented) and system utils. Plus one forthcoming Vagrant / Ansible based deployment repo.


Rutha Modules

rutha-utils (npm: rutha-utils, github: molekilla/rutha-utils)

Based on my experience with Express, I'm using nconf and winston for configuration and logging management. Additionally, rutha-utils/mongoose binds the Mongoose schemas and events. This module keeps the boilerplate at a minimum but at the same time lets you decide which dependencies will be linked with the internal Hapi controllers. Look here for more details: https://github.com/molekilla/rutha/blob/master/ui/lib/hapi/index.js#L1-L63

rutha-grunt-mongo-migrations 

(npm: rutha-grunt-mongo-migrations, github: molekilla/rutha-grunt-mongo-migrations)

Runs a shell script for mongo-migrate. An optional module for those using Mongo. It might even be possible to add it as a set of npm scripts, but works for the use case required. Look here for more details: https://github.com/molekilla/rutha-grunt-mongo-migrations/blob/master/grunt/shell.js

rutha-grunt-tasks-service 

(npm: rutha-grunt-tasks-service, github: molekilla/rutha-grunt-tasks-service)

Groups all service layer tasks. Separates having all grunt tasks inside rutha and allows for decoupling (rutha might use a newer version than a cloned repo). Because service doesn't required client side madness, it contains a really simple set of task flows.

  • grunt serve: Runs concurrent
  • grunt spec: Runs jshint and jasmine 2.0 specs
  • grunt coverage: Runs jshint, cleans previous coverage and runs Istanbul js code coverage
  • grunt auditpkg: Checks module security
  • grunt docs: Runs jsdoc3


rutha-grunt-tasks-ui 

(npm: rutha-grunt-tasks-ui, github: molekilla/rutha-grunt-tasks-ui)

Groups all UI related tasks. This is where the magic happens for the client side part. It handles both developer and build / deployment environment.

grunt autosync

This never got traction so it will be deprecated in 1.0

grunt serve

The tasks are:
  • preprocess: Runs any grunt-preprocess template found in any client side HTML. Will not process any server side HTML. For that use Hapi.
  • ngtemplates: Runs grunt-angular-templates. Takes the output in dist/html and generates a templates.js
  • concat: Concat files
  • ngannotate: Takes care of Angular Depedency Injection tagging. Uses grunt-ng-annotate.
  • uglify: Does a uglify run and generates sourcemaps.
  • bower_concat: Concats bower dependencies
  • wiredep: For serving files, we recommend bower_concat, but wiredep is still an option.
  • copy: Copies images in src/img and any inside src/css
  • cssmin: Minifies bower CSS and src/css
  • concurrent: Runs concurrent

grunt spec

The tasks are:
  • preprocess: Runs any grunt-preprocess template found in any client side HTML. Will not process any server side HTML. For that use Hapi.
  • jshint: Runs jshint
  • jasmine_node: Runs Jasmine 2.0 Hapi Specs
  • ngtemplates: Runs grunt-angular-templates. Takes the output in dist/html and generates a templates.js
  • wiredep: Generates a list of dependencies for Karma.
  • karma: Runs Karma

grunt build

The tasks are:
  • preprocess: Runs any grunt-preprocess template found in any client side HTML. Will not process any server side HTML. For that use Hapi.
  • ngtemplates: Runs grunt-angular-templates. Takes the output in dist/html and generates a templates.js
  • copy: Copies images in src/img and any inside src/css
  • bower_concat: Concats bower dependencies
  • copy: Copies views and front end code (those required)
  • concat: Concat files
  • ngannotate: Takes care of Angular Depedency Injection tagging. Uses grunt-ng-annotate.
  • uglify: Does a uglify run with no sourcemaps.
  • cssmin: Minifies bower CSS and src/css
  • compress: Zip files
There are other tasks, but these are the ones you'll use almost daily.

rutha_deploy (github: molekilla/rutha_deploy)

This will help you test your apps locally inside a Vagrant VM. Because the provisioning is Ansible based, you will be able to deploy to any cloud (AWS, Azure, DigitalOcean, etc)

rutha (github: molekilla/rutha)

rutha is then the main repo. At the top level you have a travis.yml and a package.json with a set of npm scripts that actually runs both service and UI specs to satisfy Travis or any CI package.

Service

The folder structure is as follow
  • config: Add your JSON config by NODE_ENV name. Example: production.json will be read by an environment variable NODE_ENV=production
  • lib: Contains the service business logic
    • hapi/index.js: Important to know that it contains the REST documentation Swagger API. For production release, we recommend to remove this plugin.
    • controllers: hapi based plugins.
  • migrations: mongo-migrate migrations
  • models: Mongoose schemas
  • spec: Jasmine 2.0 specs

UI

The folder structure is as follow
  • config: Add your JSON config by NODE_ENV name. Example: production.json will be read by an environment variable NODE_ENV=production
  • lib: Contains the service business logic
    • hapi/index.js: Handles server side pages and security.
    • controllers: hapi based plugins.
  • migrations: mongo-migrate migrations
  • views: Hapi views
    • partials: Hapi partials
  • spec: Jasmine 2.0 specs

Up Next

Next post we'll show how to start with Hapi and some basics of how to create APIs and Views.

Rogelio Morrell





Saturday, November 22, 2014

Panama: Educar emprendimiento en nuestra generacion

He estado involucrado en las tecnologías de la información desde 1995. He visto como la tecnología cambia sociedades y como el énfasis en el recurso humano y la integración de maquinas y software orientan la economía de países. Al tener alrededor de 18 años me acuerdo que al dejar el país donde pase gran parte de mi juventud le dije a mi papa que la programación es universal, era lógica, lo que aprendería en Panamá me iba servir en cualquier parte del mundo.

Estuve ciertamente en lo correcto, desde 2006 he liderado equipos de desarrollo de software para una empresa con raíces en lo que suelen llamar Sillicon Valley. Mas sin embargo, a pesar del contraste tecnológico, sofisticación financiera y cultura emprendedora, he siempre tratado de buscar como replicar ese éxito en otros emprendedores y empresas locales. Esto ha sido un descubrimiento de políticas erradas, de varios actores, llámese estatal o privado. Ejemplos hay muchos, uno que resalta, estudios realizados por CAPATEC y Senacyt donde vaticinan que para 2018 se van a requerir miles de plazas en las TICs (Tecnología, Información y Comunicación) (Ver http://www.capatec.org.pa/proyectos/estrategia-nacional/). Como vamos a suplir la demanda ? No generamos suficientes egresados de las universidades. La migración de personal calificado es onerosa para empresas que inician ("startups") y el 10% (1 por cada 10 panameños) para empresas fuera de clusters (como la Ciudad del Saber y Panamá Pacifico) complica mas el panorama.

Mientras tanto en Estados Unidos, el presidente Obama, en su mas reciente plan de política migratoria de Noviembre de 2014, dedica varias pautas para abrir el compas a mas mano de obra tecnológica calificada. Otros  países como Canadá y Australia tienen facilidades similares, orientado a las TICs. En América Latina, Chile tiene uno de los planes mas exitosos, con StartupChile http://www.startupchile.org/.

Este es un pilar entre otros de la economía del conocimiento. Yo veo mas al futuro la evolución económica y me atrevo a decir que la economía del conocimiento va a convertirse en la economía del emprendedor. Todos seremos emprendedores tarde o temprano. Panamá no es ajeno a las tendencias actuales. Es por tal razón, un grupo de conocedores jóvenes en el tema, estamos por lanzar los lineamientos, o manifiesto de como educar, evangelizar y motivar a futuras generaciones. Nuestra zona búfer es desde la secundaria. Tan obsesionados estamos en el tema, que descubrimos cuando los jóvenes llegan a la universidad, la mayoría están sin rumbo de que quieren lograr.

El Manifiesto de Panama StartupWay (https://github.com/Startup-Panama/manifiesto/wiki) es un primer paso. Estos diez puntos brindara las pautas generales. Pretendemos incluir un Kit de 'Como iniciar un startup en Panamá?', potencialmente clínicas y charlas y mas que nada, invitamos a otros luminarios expertos que colaboren con nosotros para de una vez por todas, educar emprendimiento que tanto se requiere y que veamos los frutos en nuestra generación. Este no es un plan de 5 años (no somos un plan de gobierno). Ni es un plan de lucro instantáneo (ni somos un plan corporativo). Es simplemente la visión que necesitamos lograr si queremos seguir adelante como nación de servicios al mundo.

Saturday, September 27, 2014

AngularJS - Por que es AngularJS tan complejo ?

Introducción

Hace unos dias conversaba con un amigo sobre AngularJS y la razon de su complejidad. En si no es complejo del todo, tiene que ver mas bien con previas experiencias que el equipo de AngularJS obtuvo en proyectos anteriores (por ejemplo Google Closure, quizas GWT). Pero mis puntos claves que he descubierto son los siguientes.

Tiempo de curva de aprendizaje vs tiempo al mercado

Yo estuve en un proyecto de 24 a 28 meses usando Backbone, jQuery y Bootstrap. Al principio seguiamos todos los patrones y mejores practicas. El codigo era escalable. Pero fallamos en varios aspectos que a continuacion describo:

Entrenamiento y divulgacion interna

Eramos malos documentando el API recien creado. Otros equipos encontraron dificultad en adaptarse.

Obsolesencia

A los seis meses, el mismo Backbone de nuestro framework nunca lo actualizamos.

Tiempo al mercado (Time to Market)

Cuando finalmente llego AngularJS al cliente, la entrega de los otros equipos de algun modo era mas rapida que la nuestra. Seguramente porque evitaron el sindrome NIH (Not Invented Here).

La curva

Obsolesencia y divulgacion son dos puntos claves. Pero no explica por si solo el "Time to Market". Es aqui la diferencia de "Angular Way" vs tu framework con librerias. AngularJS "normaliza" el conocimiento, al tener directivas como la forma para interactuar con jQuery y factorias/servicios como la forma de creacion de objetos. Esto permite desarrollar sumamente rapido con los mismos conceptos entre equipos. De tal modo que con 100 horas (casi un mes solo en Angular) obtienes un conocimiento intermedio al que obtendrias con la misma cantidad que con Backbone, jQuery y todo lo relacionado (templates, grunt, requirejs, stickit, marionette, thorax, etc)

La curva de aprendizaje siempre va ser importante como tambien el time to market. Yo lo veo como un Ying Yang. Hay un balance entre estos dos.

Realmente debo usar AngularJS para todo emprendimiento?

La respuesta es facil, todo va depender de tu escenario, en las habilidades de tu equipo, el presupuesto y la crema, que tanto "edgy" o en boga quieran usar tecnologia innovadora (Polymer WebComponents, ES6 transpiler, ClojureScript/Om)

En las siguientes entregas tocare brevemente el tema del empleo y los informales, despues continuo con mas AngularJS y posteriormente un poco de HapiJS y Joi

Hasta la siguiente entrega




Tuesday, September 9, 2014

AngularJS - Validaciones de formularios #1

Introducción

En este articulo explicamos brevemente ciertas cualidades de AngularJS 1.3.x

Validar debería ser fácil con Angular

Sin embargo, hay flujos de validaciones que no son soportados, por ejemplo:
  • Cargar formulario con campos "required": En Angular, siempre son mostrados. No hay forma sencilla de decirle después que salga del foco.
  • Validaciones cuando haces clic el botón de submit o un botón cualquiera.

Usando Angular 1.3 ngMessages

Yearofmoo describe ngMessages de una manera correcta. Lo esencial es que ngMessages lee el $error del campo (ejemplo form.campo.$error) y toma el primer key/value y presenta este error en caso de estar activo.
Lo cual funciona de perfectamente bien. Hasta que queremos resolver los dos casos extremos mencionados (que en Backbone son fáciles de implementar ciertamente).

Caso #1 - Solo debe mostrarme requerido al perder el foco


Mi solución rudimentaria fue usar un combo de ng-blur y ng-change, mantener el required message en el conjunto de ng-messages y tener una simple función en el controller. Esto se puede mejorar mucho mas con un Angular Directive.




Ahora, al cargar el formulario, solo se muestra requerido al perder el foco (blur). Lo bueno de esto es que reusamos ngMessages tal como esta.

En la próxima entrega explicaremos como resolver el Caso #2 con el submit.

Correciones: En vez de setear invalid = true, debe usarse $setValidity

Hasta la siguiente entrega
Rogelio Morrell




Wednesday, August 27, 2014

HapiJS - View Partials con UnderscoreJS

Introducción

En este articulo explicamos el uso de "view partials" o vistas parciales, que son en esencia pedazos de HTML.

Para que usamos parciales

Son utiles cuando tienes una plantilla maestra (master template) y quieres por ejemplo generar la barra de navegacion que contiene el enlace de perfil de usuario.

Configurando parciales en HapiJS

En la variable partialsPath se agrega donde residen las plantillas parciales.

Usando parciales con Underscore

Por medio de server.render logramos obtener el parcial generado. Estoy pensando en que seria posible precargar los parciales y posteriormente sean accedidos para ser usados, como un tipo de precompilacion. Otra forma es usar promises para cuando se requieran generar mas de un partial y usarlos en una vista.

Usando LoDash

Con LoDash debe funcionar igualmente y podriamos usar el imports para los parciales precargados. De tal modo que se podria llamar a la funcion desde la plantilla, en vez de enviar el HTML como otra variable a la plantilla maestra. Esta tarea se la dejo a los seguidores del blog para que investiguen.

Hasta la siguiente entrega
Rogelio Morrell