MEAN_STACK.md 32 KB

MEAN Stack (MongoDB, Express, Angular and Node) Tutorial.

Crear, configurar, desarrollar y desplegar un proyecto MEAN.

Subtareas a realizar:

  • Instalar Node, Mongo, Express y Angular.
  • Administrar dependencias utilizando un archivo package.json.
  • Crear y configurar proyectos Express.
  • Configurar un entorno Modelo Vista-Controlador (MVC).
  • Agregar Bootstrap de Twitter para el diseño.
  • Publicar el proyecto a una URL en vivo utilizando Git y Heroku.

Instalar node, mongo, express y angular.

En Windows:

  1. Node: Neoguías tiene una guía de instalación aquí.
  2. MongoDB: Descarga mongodb y sigue las instrucciones del instalador.
  3. Express: Puedes instalarlo a través de cmd.exe o PowerShell una vez que hayas instalado node. Usando el comando npm install -g express-generator.
  4. Angular: La forma de instalarlo es como una dependencia de tu proyecto, utilizando npm install angular o agregandolo al archivo package.json en el apartado "dependencies"

En archlinux:

Necesitarás teclear el numero del paquete que corresponde exactamente con el nombre:

usr@system {~}$ yaourt nodejs
usr@system {~}$ yaourt mongodb
usr@system {~}$ yaourt nodejs-express-generator
usr@system {~}$ yaourt nodejs-nodemon

Comprobar que se han instalado:

usr@system {~}$ node -v
v10.1.0
usr@system {~}$ mongod --version
db version v3.6.3
usr@system {~}$ express --version
v4.15.0
usr@system {~}$ nodemon --version
1.11.0

En ubuntu:

user@ubuntu {~}$ curl -sL https://deb.nodesource.com/setup_10.x | sudo -E bash -
sudo apt-get install -y nodejs
...
user@ubuntu {~}$ sudo apt-get install -y mongodb-org
...
user@ubuntu {~}$ npm install -g express-generator
...
user@ubuntu {~}$ npm install -g nodemon

Ojo, si te muestra error en la instalación con npm, tal vez necesites agregar sudo a los comandos, dependiendo de la configuración de tu Sistema Operativo. Para mayor detalle visitar la página de node, mongodb, express-generator y nodemon.

Administrar dependencias utilizando npm y el archivo package.json

Cuando instalas Node.js normalmente incluye el gestor de paquetes npm con el cual instalas express. Para administrar dependencias de un proyecto node, normalmente lo haces utilizando npm, ya sea directamente en la terminal o editando el archivo package.json. Para utilizar npm necesitas crear una carpeta donde pondrás todos los archivos de tu proyecto, cambiarte a ese directorio y ejecutar el comando npm init. A partir de aquí podrás ir agregando dependencias a tu proyecto, por ejemplo, las que instala express por defecto.

usr@system {~}$ mkdir restaurant
usr@system {~}$ cd restaurant
usr@system { restaurant }$ npm init
...
package name: (restaurant) 
version: (1.0.0) 0.1.0
description: Un restaurant vegetariano.
entry point: (index.js) app.js
test command:
git repository:
keywords: comida, vegetarian, vegan, guadalajara, jalisco, mexico
author: Programador distraído
license (ISC) GPL-3.0
About to write /home/usr/restaurant/package.json
...

Utilizando npm:

Para instalar dependencias se utiliza el comando npm install <paquete> donde el parametro es opcional.

  • npm install: Si el directorio actual contiene un archivo package.json, es decir, ya se ha ejecutado npm init previamente.
  • npm install <paquete>: Instala el paquete en el directorio node_modules del proyecto actual, pero no guarda los cambios en package.json.
  • npm install <paquete> --save: Instala el paquete y guarda los cambios en package.json.
  • npm install <paquete> --save-dev: Instala el paquete y guarda los cambios en package.json, para la fase de desarrollo solamente, estos paquetes se descartan en la fase de despliegue.
  • npm install -g <paquete>: Instala el paquete globalmente, es decir, para todos los usuarios del sistema.

Algunos ejemplos:

usr@system { restaurant }$ npm install express --save
usr@system { restaurant }$ npm install jquery --save
usr@system { restaurant }$ npm install angular --save
usr@system { restaurant }$ npm install gulp --save-dev
usr@system { restaurant }$ npm install -g express-generator
usr@system { restaurant }$ npm install -g nodemon

Editando package.json:

También, si ya inicializaste tu directorio de trabajo con npm init, puedes editar directamente el archivo package.json, agregando dependencias en el apartado "dependencies":

{
  "name": "restaurant",
  "version": "0.1.0",
  "private": true,
  "scripts": {
    "start": "node ./bin/www"
  },
  "dependencies": {
    "body-parser": "~1.17.1",
    "cookie-parser": "~1.4.3",
    "debug": "~2.6.3",
    "express": "~4.15.2",
    "jade": "~1.11.0",
    "morgan": "~1.8.1",
    "serve-favicon": "~2.4.2",
    "angular": "~1.7.0"
  }
}

Una vez que ya agregaste dependencias en el archivo package.json necesitas ejecutar npm install sin mas parametros, para que se actualizen y se instalen los paquetes de las dependencias. Oviamente necesitas hacer npm install cada vez que modifiques el package.json, por esta razón es mas práctico utilizar las opciones --save y --save-dev.

Crear y configurar proyectos Express.

Necesitamos primero crear un directorio donde trabajaremos con nuestro proyecto, opcionalmente podemos utilizar el comando npm, que es el administrador de paquetes de node.

usr@system {~}$ mkdir tienda
usr@system {~}$ cd tienda
usr@system { tienda }$ npm init

Esto creara un archivo que se llama package.json con un contenido parecido a este, dependiendo de lo que pusiste en las preguntas que hace npm.

{
  "name": "tienda",
  "version": "1.0.0",
  "description": "Una descripcion bien chida en ingles.",
  "main": "index.js",
  "scripts": {
    "test": "algun comando para lanzar tareas de prueba"
  },
  "author": "",
  "license": "ISC"
}

Ejecuta express:

usr@system { tienda }$ express

Este comando generara los siguientes directorios: bin node_modules public routes views y el archivo app.js. También modifica también el archivo package.json, indicando que express tiene esas dependencias, incluyendo así mismo.

{
  "name": "tienda",
  "version": "0.0.0",
  "private": true,
  "scripts": {
    "start": "node ./bin/www"
  },
  "dependencies": {
    "body-parser": "~1.17.1",
    "cookie-parser": "~1.4.3",
    "debug": "~2.6.3",
    "express": "~4.15.2",
    "jade": "~1.11.0",
    "morgan": "~1.8.1",
    "serve-favicon": "~2.4.2"
  }
}

Una vez que el directorio está listo. Para arrancar el servidor node teclea:

usr@system { tienda }$ npm start

La desventaja de esto es que cada vez que hagas un cambio al proyecto tendras que reiniciar el servidor, presionando Ctrl-C y despues tecleando el comando npm start. Si quieres evitar esto puedes instalar el paquete nodemon que monitorea el código y reinicia el servidor automaticamente cada vez que haces un cambio.

Para instalar nodemon globalmente teclea:

usr@system { tienda }$ npm install -g nodemon

Ahora en lugar de ejecutar npm start ejecuta nodemon en la carpeta de trabajo. Una vez hecho esto podrás seguir trabajando y viendo las modificaciones en tiempo real simultaneamente. Además podras observar las peticiones que recibe el servidor desde un navegador.

usr@system { tienda }$ nodemon
[nodemon] 1.11.0
[nodemon] to restart at any time, enter `rs`
[nodemon] watching: *.*
[nodemon] starting `node ./bin/www`
GET / 304 1381.870 ms - -
GET /stylesheets/style.css 304 4.933 ms - -
GET /favicon.ico 404 59.718 ms - 1285

Configurar un entorno Modelo Vista Controlador (MVC).

El modelo vista controlador es una arquitectura cuyo objetivo es separar los datos (modelo), lo que se muestra (vista), y la lógica de la aplicación (controlador). Esta separación se enfoca en remover cualquier atadura entre los componentes, teoricamente haciendo el código mas mantenible y reusable.

Funcionamiento del modelo vista controlador

La mayoría de las aplicaciones o sitios que construirás estarán diseñados para recibir una petición, hacer algo con ella y retornar una respuesta. Al nivel mas simple, este ciclo funciona así en la arquitectura MVC:

  1. Una petición llega a la aplicación.
  2. La petición se enruta un controlador.
  3. El controlador, si es necesario, hace una petición al modelo (base de datos).
  4. El modelo responde al controlador.
  5. El controlador envía una respuesta a una vista.
  6. La vista envía una respuesta al cliente que envió la petición.
+-------+                   +--------+                   +-----------+                   ."****".
|Cliente| --- Peticion ---> |Ruteador| --- Peticion ---> |Controlador| --- Petición ---> |Modelo|
|       |                   +--------+                   |           |                   |      |
|       |                   +--------+                   |           |                   |      |
|       | <---Respuesta --- | Vista  | <---Respuesta --- |           | <---Respuesta --- |      |
+-------+                   +--------+                   +-----------+                   \______/

Cambiando la estructura del directorio para MVC.

Para adaptar el proyecto a la arquitectura MVC, necesitamos aislar en nuestro directorio de trabajo, la parte del funcionamiento del servidor. Al ejecutar express nos creó dos directorios llamados routes y views, los cuales moveremos al adaptar el modelo:

  1. Crear una nueva carpeta especial para la arquitectura MVC.
  2. Crear dos nuevas carpetas dentro de la carpeta especial llamadas models y controllers.
  3. Mover las carpetas views y routes del directorio raíz del proyecto.

Por ejemplo:

usr@system { tienda }$ mkdir -p server/models
usr@system { tienda }$ mkdir -p server/controllers
usr@system { tienda }$ mv views server
usr@system { tienda }$ mv routes server

Por supuesto que esto rompera la configuración del servidor que se está ejecutando y esperará a que la corrijamos. Para hacer esto necesitamos notificar a express que hemos movido las vistas y las rutas, ya que estas dejaron de existir. Express estará buscando las vistas en /views y nosotros lo hemos movido a /server/views. Para informarle a express que lo cambiamos, editamos el archivo de la aplicación principal app.js y cambiamos las rutas:

En la parte donde se encuentra la linea:

app.set('views', path.join(__dirname, 'views'));

cambiala a:

app.set('views', path.join(__dirname, 'server', 'views'));

esto avisará a express que busque dentro de la carpeta server, todas las vistas. Nuestros cambios también modificaron las rutas, por lo tanto también necesitamos notificarle a express hacia donde cambiamos la carpeta con las rutas, es decir, cambia ./routes/index a ./server/routes/index y ./routes/users a ./server/routes/users:

En la parte donde se e encuentran las lineas:

var routes = require('./routes/index');
var users = require('./routes/users');

cambialas a la forma siguiente:

var routes = require('./server/routes/index');
var users = require('./server/routes/users');

Separando controladores de las rutas.

Por defecto Express unifica bastante los controladores con las rutas, pero esto no se adapta a la arquitectura MVC por lo que necesitamos separarlos. Para entender como functionan las rutas, hecha un vistaso a la ruta que está instalada por defecto abriendo el archivo index.js que se encuentra en /server/routes:

router.get('/', function(req, res) {
  res.render('index', { title: 'Express' });
});

El código router.get('/', describe a una instancia del router de express que recibe una petición GET al directorio raíz del sitio. La parte del código que describe al controlador es function(req, res) { res.render('index', { title: 'Express' }); }, es decir, si el router recibe una petición GET al directorio '/' raíz del sitio, el controlador responde con una "vista", en este caso index que en el sistema de archivos se guarda como index.jade, index.html o index.pug, dependiendo de como hayas configurado express. El segundo parámetro { title: 'Express' }, es un objeto que consiste en pares { variable: valor } que se pasan a la vista como variables reutilizables. Acontinuación se puede observar en index.jade el uso de estas variables.

En este caso el archivo index.jade contiene:

extends layout

block content
  h1= title
  p Welcome to #{title}

Este código se compila previamente a html y se envía para que el navegador dibuje la vista, con la función 'render'. El codigo anterior se convertiria a html como sigue:

<h1>Express</h1>
<p>Welcome to Express</p>

Para separar el código del controlador del router proseguimos como sigue:

Sacar el codigo del controlador del router en el archivo /server/router/index.js:

var homeController = function (req, res) {
	res.render('index', { title: 'Express' });
};

router.get('/', homeController);

Mover el controlador fuera del archivo del router, creando un nuevo modulo en la carpeta /server/controllers/, al que llamaremos main.js. A este archivo agregaremos el controlador que controla la vista 'index'.

/* /server/controllers/main.js */
module.exports.index = function(req, res) {
	res.render('index', { title: 'Express' });
};

Actualizar el archivo /server/routes/index.js para utilizar el nuevo controlador externo:

var express = require('express');
var router = express.Router();
var mainController = require('../controllers/main');

router.get('/', mainController.index);

module.exports = router;

Una vez hecho esto, ahora tendremos una arquitectura router-controlador separados y por lo tanto completamos el cambio a la arquitectura MVC. Cada vez que se requiera una nueva vista para tu applicación, necesitas agregar por ejemplo:

La vista /server/views/about.jade.

extends layout
block content
	h1= title
	p Express is a node framework.	

Su correspondiente controlador /server/controllers/about.js con el código:

module.exports.index = function(req, res) {
	res.render('about', { title: 'About Express' });
};

Un nuevo router /server/routes/about.js con el código:

var express = require('express');
var router = express.Router();
var aboutController = require('../controllers/about');

router.get('/about', aboutController.index);

module.exports = router;

Agregar el nuevo router /server/routes/about.js al archivo app.js:

	var about = require('./server/routes/about');
	app.use('/about', about);

Así de manera iterativa se agregan nuevos recursos (vista, controlador, ruta), que en este caso son solo páginas estáticas que no hacen nada. Aún falta agregar un modelo para almacenar datos que el usuario introduce en formularios, pero para hacer eso dirijirse a [MEAN_STACK_mongodb]() dónde se hará uso extensivo del directorio /server/models.

Agregar Bootstrap de Twitter para el diseño.

Existen muchas formas de agregar componentes visuales a tu proyecto express:

Descargar los componentes y agregarlos a los archivos estaticos del proyecto

Descargar Bootstrap y extraerlo en tu carpeta /public/assets por ejemplo. No olvides descargar JQuery en el mismo directorio, ya que es un requerimiento de bootstrap.

Utilizar la Red Distribuida (CDN) De Bootstrap y JQuery

La mejor opcion si quieres aprovechar la red distribuida (CDN) de los proveedores de bootstrap y jquery es agregar los links en tu layout principal:

<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.1/css/bootstrap.min.css" integrity="sha384-WskhaSGFgHYWDcbwN70/dfYBj47jz9qbsMId/iRN3ewGhXQFZCSftd1LZCfmhktB" crossorigin="anonymous">
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.3/umd/popper.min.js" integrity="sha384-ZMP7rVo3mIykV+2+9J3UJ46jBk0WLaUAdn689aCwoqbBJiSnjAK/l8WvCWPIPm49" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.1/js/bootstrap.min.js" integrity="sha384-smHYKdLADwkXOn1EmN1qk/HfnUcbVRZyYmZ4qpPea6sjB/pTJ0euyQp0Mk8ck+5T" crossorigin="anonymous"></script>

Instalar Bootstrap y JQuery como dependencias y agregar ruta estatica al servidor express.

usr@system { tienda }$ npm install jquery --save
usr@system { tienda }$ npm install popper.js --save
usr@system { tienda }$ npm install bootstrap --save

Estas dependencias se agregaran a la carpeta que contiene los modulos de tu aplicación /node_modules. Entonces en el archivo del servidor app.js necesitas agregar una ruta estática para que el navegador la cargue y agregue a la cache una sola vez.

app.use('/css', express.static(__dirname + '/node_modules/bootstrap/dist/css'));

Ahora necesitas importar las hojas de estilo en tu html, jade o pug:

<link rel="stylesheet" href="/css/bootstrap.min.css" />

Debes asegurarte que las rutas esten correctamente escritas, de otra manera no cargara las hojas de estilo de bootstrap.

Utilizar un 'bundler' como webpack.

En tu directorio principal de tu proyecto (donde se encuentra packages.json), instala el paquete bootstrap-loader:

usr@system { tienda }$ npm install bootstrap-loader --save-dev

Si retorna errores de dependencia instalalas igualmente:

usr@system { tienda }$ npm install resolve-url-loader url-loader --save-dev

Ahora instala bootstrap 3 y algunas dependencias:

usr@system { tienda }$ npm install bootstrap-sass --save-dev
usr@system { tienda }$ npm install css-loader node-sass sass-loader style-loader --save-dev

o si prefieres bootstrap 4 y utilizaras Webpack 2:

usr@system { tienda }$ npm install bootstrap --save-dev
usr@system { tienda }$ npm install imports-loader exports-loader postcss-loader --save-dev

Obviamente necesitas importar el modulo bootstrap-loader en tu app.js de otra manera no se cargará.

require('bootstrap-loader');

Si quieres personalizar los componentes de bootstrap y seleccionar las caracteristicas que utilizaras, necesitas agregar un .bootstraprc y copiar la configuración ejemplo de bootstraprc-3-default o si utilizarás bootstrap 4 copia la configuracion de bootstraprc-4-default.

Dentro de la configuración local de bootstrap .bootstraprc que copiaste, encontrarás un apartado como el siguiente:

### Bootstrap styles
styles:

  # Mixins
  mixins: true

  # Reset and dependencies
  normalize: true
  print: true
  glyphicons: true

  # Core CSS
  scaffolding: true
  type: true
  code: true
  grid: true
  tables: true
  forms: true
  buttons: true

  # Components
  component-animations: true
  dropdowns: true
  button-groups: true
  input-groups: true
  navs: true
  navbar: true
  breadcrumbs: true
  pagination: true
  pager: true
  labels: true
  badges: true
  jumbotron: true
  thumbnails: true
  alerts: true
  progress-bars: true
  media: true
  list-group: true
  panels: true
  wells: true
  responsive-embed: true
  close: true

  # Components w/ JavaScript
  modals: true
  tooltip: true
  popovers: true
  carousel: true

  # Utility classes
  utilities: true
  responsive-utilities: true

### Bootstrap scripts
scripts:
  transition: true
  alert: true
  button: true
  carousel: true
  collapse: true
  dropdown: true
  modal: true
  tooltip: true
  popover: true
  scrollspy: true
  tab: true
  affix: true

Dependiendo de tus preferencias, si deseas desactivar un componente remplaza true con false, si deseas activar un componente, debes asegurarte que tenga true.

A continuacion necesitas configurar el archivo webpack.dev.config.js para la fase de desarrollo y webpack.prod.config.js para la fase de producción. Puedes copiar los ejemplos del repositorio de bootstrap-loader: webpack.dev.config.js webpack.prod.config.js

Por ultimo agregamos la configuracion siguiente al archivo app.js:

var webpack = require('webpack');
var bootstrapEntry;

if (process.env.NODE_ENV === 'production') {
	bootstrapEntry = require('webpack.prod.config');
} else {
	bootstrapEntry = require('webpack.dev.config');
}

var boostrap = webpack(bootstrapEntry);

Nota: Este método es uno de los mas dificiles debido a la variación en las versiones de los paquetes (lo se Webpack es una patada en los...). La ventaja es que tienes mas libertad de configuración, pero este método requiere que te vuelvas un experto. Puedes optar por metodos alternativos, para evitar frustraciones. Para mas información sobre este método leer: Bootstrap through webpack Webpack Guides

Utilizar un servicio de express para obtener siempre la version mas nueva.

Una alternativa a los métodos anteriores que resulta mas simple es instalar express-bootstrap-service.

usr@system { tienda }$ npm install express-bootstrap-service --save

Agregar a app.js el siguiente codigo:

var bootstrap = require('express-bootstrap-service');
app.use(bootstrap.serve);

Este método crea las rutas para servir los archivos estaticos /bootstrap/js, /bootstrap/css y /bootstrap/fonts. Se pueden configurar algunas opciones con el metodo init(), por ejemplo:

bootstrap.init({
	minified: false,
	path: "assets" // Esto sobreescribe '/bootstrap/js' en '/assets/js'
});
app.use(bootstrap.serve);

Para mas información leer: express-bootstrap-service

Publicar el proyecto a una URL en vivo utilizando Git y Heroku.

Una vez que ya tienes la aplicación funcionando localmente sigue lo mas importante: desplegarla a un servidor de producción. Antes de desplegarla es importante llevar un control de los cambios que realizas en el código. Esto normalmente se realiza utilizando un Sistema de Control de Versiones. Existen varios sistemas de control de versiones (por ejemplo: mercurial, cvs, svn, bazaar), para este ejemplo utilizaremos git.

Agregar control de versiones a tu proyecto:

Para agregar tu proyecto al control de versiones de git necesitas instalar git en tu sistema. Puedes descargarlo y seguir las instrucciones indicadas en git-scm.com. En sistemas GNU/Linux basados en Arch:

usr@system ~$ yaourt git
...

o con pacman:

usr@system ~$ sudo pacman -S git
...

Una vez que ya tengas instalado git, cambias tu directorio de trabajo a donde se encuentra tu proyecto y ejecutas git init. Esto inicializará la carpeta que contiene tu proyecto como un repositorio git, listo para seguir trabajando, solo que ahora los cambios que hagas quedaran registrados en el arbol de cambios de git.

usr@system { tienda }$ git init
Inicializando repositorio Git vacío en /home/usr/../tienda/.git

Para ver el estado del arbol de trabajo en el directorio actual teclea git status:

usr@system { tienda }$ git status
En la rama master

No hay commits todavía

Archivos sin seguimiento:
	(usa "git add <archivo>..." para incluirlo a lo que será confirmado)

... lista de archivos de tu proyecto ...

no hay nada agregado al commit pero hay archivos sin seguimiento presentes (usa "git add" para hacerles seguimiento)

Como puedes ver en los mensajes de git, te sugiere que agregues los archivos de tu proyecto para su seguimiento. Esto quiere decir que no son agregados por defecto. Tienes que agregarlos tú usando la sintaxis git add <archivo>..., aunque realmente casi nadie agrega archivo por archivo al arbol de trabajo. Para agregar todo el contenido de tu directorio al arbol de trabajo ejecuta git add .. El . significa "agrega el directorio actual de forma recursiva al arbol de trabajo", este comando agregará todo al arbol de trabajo.

usr@system { tienda }$ git add .

Una vez hecho esto, necesitas perpetrar los cambios, es decir: confirmar que los cambios se mantengan para versiones posteriores. Para hacer esto utiliza el comando git commit. El comando de confirmación commit requiere que escribas un mensaje, ya sea con una explicación de lo que has hecho o algún tip; si no proporcionas un mensaje, se abortará la operación y git no dará seguimiento a esos cambios. Por ejemplo:

usr@system { tienda }$ git commit -m "Commit inicial: esta es la versión inicial de mi tienda."

Siempre puedes revisar el estado del árbol de trabajo con git status para que hagas los cambios necesarios. Básicamente este proceso es ciclico, haces cambios, los agregas al árbol y los confirmas con un mensaje de lo que has hecho. Para mayor conocimiento sobre este programa, puedes consultar la siguiente hoja de referencia Git Spanish Cheatsheet. De ahora en adelante, cada vez que hagas un cambio dentro de esa carpeta, necesitas repetir el proceso de git.

Crear una cuenta, instalar y configurar Heroku.

Heroku es una plataforma que te permite desplegar tu aplicación web en la nube. Proporciona muchos servicios, como el hospedaje, la asignación y reservación de un nombre de dominio, bases de datos, entre otras cosas. Esta plataforma nos permitirá desplegar la aplicación pero antes necesitas:

  1. Crear una cuenta registrandote en Signup to Heroku.
  2. Descargar e instalar el conjunto de herramientas de heroku Heroku Toolbelt
  3. Configurar heroku localmente con los datos (correo y contraseña) que proporcionaste a la hora de registrarte.

Para instalar heroku en distribuciones GNU/Linux basadas en Arch:

usr@system ~$ yaourt heroku-cli
...

o con pacman:

usr@system ~$ sudo pacman -S heroku-cli 
...

Comprobar que se instaló correctamente, ejecutando:

usr@system ~$ heroku --version
heroku/7.14.4 linux-x64 node-v10.10.0

En mi equipo se puede observar que instalé la versión 7.14.4 y que tengo node v10.10.0, esto no necesariamente tiene que ser igual si utilizas Debian o Windows. Para mayor información consulta las versiones con sus respectivos desarrolladores.

Para configurar heroku localmente necesitas introducir el correo y la contraseña de la cuenta que creaste en la página de heroku.

usr@system ~$ heroku login
Enter your Heroku credentials.
Email: tu-correo-electronico@company.com
Password (typing will be hidden): # Teclea aquí la contraseña con la que te registraste en heroku
Authentication successful.

Acontinuación necesitas iniciar tu proyecto como un proyecto heroku, para hacerlo necesitas localizarte en la carpeta de tu proyecto, en mi caso la carpeta tienda y ejecutar el comando heroku create.

usr@system ~$ cd tienda
usr@system { tienda } $ heroku create
Creating app... done, # sleepy-meadow-81798
https://sleepy-meadow-81798.herokuapp.com/ | https://git.heroku.com/sleepy-meadow-81798.git

Guarda muy bien esas URL ya que con ellas podrás ver tu aplicación correndo en linea.

Las URL varían para cada proyecto ya que heroku genera aleatoriamente las url.

Actualizar package.json para heroku

Antes de poder desplegar tu aplicación, necesitas proporcionarle información a heroku sobre el entorno en el cual estás desarrollando tu aplicación. Entre otras cosas, la version de node y npm que estés utilizando, estas puedes obtenerlas ejecutando:

usr@system ~$ node --version
v10.10.0
usr@system ~$ npm --version
6.4.1

A continuación edita el archivo package.json y agregale las versiones creando una seccion "engines" que obtuviste al ejecutar los comandos anteriores:

"engines": {
"node": "~10.10.0",
"npm": "~6.4.1"
},

El archivo package.json debe quedar similar al siguiente:

{
  "name": "restaurant",
  "version": "0.1.0",
  "private": true,
  "scripts": {
    "start": "node ./bin/www"
  },

  "engines": {
    "node": "~10.10.0",
    "npm": "~6.4.1"
  },

  "dependencies": {
    "body-parser": "~1.17.1",
    "cookie-parser": "~1.4.3",
    "debug": "~2.6.3",
    "express": "~4.15.2",
    "jade": "~1.11.0",
    "morgan": "~1.8.1",
    "serve-favicon": "~2.4.2",
    "angular": "~1.7.0"
  }
}

Con esos cambios le informas a heroku que estás utilizando node y npm, además que necesita ejecutar esas versiones para poder tener una replica exácta de tu aplicación local. Aunque paresca suficiente, heroku no sabe como ejecutar tu aplicación y necesitas avisarle con un archivo Procfile. En el archivo Procfile escribirás el comando que ejecutas para correr el servidor localmente, y por supuesto esto no es nodemon. Si prestas atención al archivo package.json hay una sección que se llama "scripts", esta sección describe comandos que puedes ejecutar ordenandole a npm que lo haga. Por ejemplo $ npm run, $ npm test, etcétera. En el ejemplo anterior hay un script llamado "start" que contiene un comando que ya conocemos "node ./bin/www". Lo que quiere decír que esta aplicación se pone en funcionamiento ejecutando ese comando, entonces esto es lo que pondremos en el Procfile para que heroku sepa como ejecutar nuestra aplicación. Dentro del archivo Procfile agrega solamente la linea web: npm start y nada mas:

Ejemplo de Procfile

web: npm start

Antes de desplegar la aplicación a heroku, probamos que funcione nuestra configuración localmente utilzando foreman que es como nodemon de heroku:

usr@system { tienda }$ foreman start
16:09:01 web.1 | started with pid 91976
16:09:02 web.1 | > tienda@0.1.0 start /home/usr/tienda
16:09:02 web.1 | > node ./bin/www

Si todo funciona bien, no hay que olvidar agregar los cambios al arbol de trabajo de git:

usr@system { tienda }$ git add .
usr@system { tienda }$ git commit -m "Agregué soporte para heroku"

Desplegar la aplicación a heroku

usr@system { tienda }$ git push heroku master
https://sleepy-meadow-81798.herokuapp.com deployed to Heroku

Como puedes ver, la URL tal vez no sea la que tu deseas, para obtener una URL con tu propio dominio necesitas desenbolsar una pequeña cantidad mensualmente o anualmente. Para mas información visita Custom Domain Names for Apps, Accounts & Billing, Getting Started on Heroku with Node.js y Heroku Documentation