¿Como crear un entorno de desarrollo WEB?

Parece una tontería, pero un entorno de desarrollo WEB se basa en tantas herramientas y se pueden usar tantas, que muchas veces configurarlo correctamente se convierte en un buen dolor de cabeza.

Para todos aquellos que venimos de entornos de desarrollo monolíticos, como podía ser Visual Studio o Borland, o xCode, un entorno de desarrollo WEB nos parece un poco como un frankestein que se monta a piezas, que casi siempre funcionan a la segunda o la tercera.

No hace falta decir que no hay un desarrollo WEB standard, se trata de ir escogiendo qué herramientas usar y cómo configurarlas. Seguramente, incluso dentro de un mismo equipo de desarrollo podremos encontrar diferentes configuraciones.

Como ejemplo he decidido utilizar mi entorno de desarrollo, que es muy simple, casi podría decir que es minimalista, uso lo mínimo de lo mínimo pero está preparado para recibir mas librerias o herramientas.

¿Que tengo en mi entorno de desarrollo?

Tengo exactamente lo mínimo necesario, un editor y GULP y SASS. También tengo que explicar que trabajo con GAE, el cloud de google. El problema es que GULP requiere de Node y NPM, y tambíen que he instalado unos cuantos plugins para GULP. Por cierto, trabajo en un MAC, la instalación será muy parecida en Windows y sobretodo en Linux. Pero hay algunas diferencias, en Mac usaremos sudo para todo y en linux seguramente no hará falta. Para Windows tenemos que sustituir la tecla Cmd por la Ctrl.

Elementos que instalaremos como parte del entorno de desarrollo WEB

  • Editor de texto: Sublime Text. Sublime es el editor más conocido, hay otros como Brackets o Atom, o incluso Notepad ++, pero Sublime es el que tiene la comunidad más grande detrás.
  • Node. Node es una librería javascript usada por el gestor de paquetes npm. Lo necesitamos y punto, lo vamos a necesitar usemos lo que usemos, así que tenemos que instalarlo, y es sencillo si funciona a la primera.
  • NPM. Un gestor de paquetes, que nos sirve para instalar tanto GULP como sus diferentes plugins.
  • GULP. Nos sirve para automatizar procesos. Hay otras opciones como GRUNT, pero de nuevo GULP es la mas usada. Es sencilla, potente y su lenguaje de configuración es javascript.

Instalación y configuración de Sublime Text

Nos lo descargamos desde https://www.sublimetext.com/, seguro que no cuesta nada encontrar el botón de download. Lo más seguro es que en la pantalla principal aparezca el botón de download de vuestra versión de SO.

Web sublimetext.

Una vez instalado nos toca configurar Sublime para que se adapte al desarrollo WEB. Sublime dispone de todo un sistema de script y de gestión de paquetes, que conviene entender un poco. Dispone de múltiples shortcuts de teclado, algunos de ellos muy útiles.

Algunos comandos útiles de Sublime:

    • Cmd + T. Buscador de ficheros. Podemos usarlo para abrir el fichero que queramos sin tener que buscarlo entre las pestañas o el menú de la izquierda.

      Al pulsar Cmd+T podemos indicar a Sublime que fichero queremos abrir.

    • Cmd + R. Buscador de funciones o indicadores. Va perfecto para buscar funciones dentro de ficheros muy grandes, mucho mejor que el buscador.

      Cmd+R nos permite buscar funciones dentro de un documento.

    • Cmd + Alt + G. Busca todas las ocurrencias en el documento de la palabra resaltada al pulsar la combinación.
    • Cmd + Ctrl + G. Selecciona todas las ocurrencias del texto resaltado. Nos permite modificar todas las instancias al mismo tiempo que escribimos. Es muy útil por si queremos cambiar el nombre de una variable.

      Editando una selección multiple con SublimeText

Instalando package control en Sublime Text

Lo primero que tenemos que instalar en SublimeText para aumentar su potencia es el package control, desde el que instalaremos todos los otros paquetes.
Para ello visitaremos la web https://packagecontrol.io/installation y recuperaremos un codigo parecido a este que os dejo aquí:

import urllib.request,os,hashlib; h = 'df21e130d211cfc94d9b0905775a7c0f' + '1e3d39e33b79698005270310898eea76'; pf = 'Package Control.sublime-package'; ipp = sublime.installed_packages_path(); urllib.request.install_opener( urllib.request.build_opener( urllib.request.ProxyHandler()) ); by = urllib.request.urlopen( 'http://packagecontrol.io/' + pf.replace(' ', '%20')).read(); dh = hashlib.sha256(by).hexdigest(); print('Error validating download (got %s instead of %s), please try manual install' % (dh, h)) if dh != h else open(os.path.join( ipp, pf), 'wb' ).write(by)

Es importante que lo cojais directamente de su web, ya que lo pueden modificar y es la única forma de asegurarnos que tenemos la última versión.
Este código lo pegaremos en la consola de Sublime. Podemos abrir una consola desde el menú: view -> console.
Para comprobar que la instalación ha ido bien pulsamos Cmd + Shift + P, y buscamos poac. Veremos como se nos muestran muchos comandos del package control. De ellos el que mas usaremos es Install Packages.

El package control de Sublime despues de pulsar Cmd + Shift + P

Los que nosotros vamos a instalar (por ahora) son:

  • Emet. Imprescindible para HTML i CSS. Nos permite escribir y él hace las acciones de autocompletar, cerrando los comandos que abrimos.
  • Sidebar Enhacements. Incorpora muchas opciones cuando pulsamos con el botón derecho sobre la lista de la derecha.

    El menu del boton derecho con todas las opciones que nos da Sidebar Enhacements.

  • Color Picker. Nos permite escoger un color con Cmd + Shift + C.

    Escogiendo el color que queremos gracias a color picker.

  • Color HighLighter.Nos muestra los colores usados en el CSS.

Dejemos por ahora el editor, y vayamos a instalar Node y NPM que son necesarios para instalar GULP

Instalando Node y NPM

Lo primero que vamos a hacer es identificar qué versión de Node tenemos. Más que nada para comprobar que la instalación de Node ha funcionado correctamente, si señor, porque no siempre funciona bien. Hay muchos modos de instalar node, yo desaconsejo Bower.

Para ver la versión de Node ejecutaremos en un terminal:

node -v

Esto nos dará la versión de Node que tenemos instalada. Al final del proceso de instalación tendría que cambiar, a no ser que ya tengamos la última, o que algo haya ido mal.

Lo más simple es bajarse de la web de Node la última versión, y como buena noticia, ya viene npm incorporado!

Podeis encontrar Node en: https://nodejs.org/en/.

Os lo descargáis e instaláis, así sin secretos. Ahora, reiniciando el terminal (o cerrando y volviendo a abrir la ventana de terminal), volvemos a consultar la versión de Node. ¿Se ha actualizado? Perfecto: pasamos directamente a instalar GULP. ¿No se actualiza la versión de Node? Bueno, vamos a ver una posible solución.

¿Qué hacer cuando node no se actualiza?

Es posible, realmente muy posible, que tengamos alguna versión de node antigua y que por cualquier razón predomina sobre la nueva instalación. Para solucionarlo vamos a intentar borrar todas las versiones anteriores de Node con este comando:

sudo rm -rf /usr/local/{lib/node{,/.npm,_modules},bin,share/man}/{npm*,node*,man1/node*}

Como podéis ver este comando está preparado para MacOs. Para linux funciona igualmente sin el sudo.
Una vez realizado este paso repetimos la instalación nueva de Node.

Instalando GULP

Lo primero que he hecho ha sido eliminar cualquier rastro de GULP que pudiera tener anteriormente en mi máquina, con:

sudo npm rm --global gulp

Como podéis ver ya estoy usando el gestor de paquetes NPM, a partir de ahora lo vamos a usar bastante. No ignoréis lo que nos dice, es posible que se de algún error que otro, pero podéis ignorar los warnings.
El siguiente comando ya es el que le pedimos a NPM que instale GULP:

#npm install --save-dev gulp

Vamos a ver una posible respuesta del comando:

sudo npm install --global gulp-cli
/usr/local/bin/gulp -> /usr/local/lib/node_modules/gulp-cli/bin/gulp.js
- lodash.assignwith@4.2.0 node_modules/gulp-cli/node_modules/lodash.assignwith
- lodash.isempty@4.4.0 node_modules/gulp-cli/node_modules/lodash.isempty
- lodash.pick@4.4.0 node_modules/gulp-cli/node_modules/lodash.pick
/usr/local/lib
└─┬ gulp-cli@1.3.0 
└─┬ liftoff@2.3.0
└─┬ fined@1.1.0 
├── expand-tilde@2.0.2 
├─┬ object.defaults@1.1.0 
│ ├── array-each@1.0.1 
│ ├── array-slice@1.0.0 
│ └── for-own@1.0.0 
└─┬ object.pick@1.2.0 
└── isobject@2.1.0 

Hemos realizado una instalación de GULP que tendría que servir para todos los usuarios de la máquina. Ahora tenemos que instalar una parte específicamente en la carpeta de nuestro proyecto WEB. Así que nos vamos al directorio raíz de nuestro proyecto y ejecutamos:

sudo npm install --save-dev gulp

Este comando nos creará un directorio node_modules con un montón de contenido, todos los módulos de Node, y alguno mas que le vamos a incorporar.

Cuando instalé Node lo hice sobre el directorio de desarrollo, que era el que subía directamente a producción. Como resultado se subieron todos los ficheros de los módulos de Node que no hacen nada en producción. Tuve que cambiar la estructura y mantener un directorio de trabajo diferente al de subida a producción. Para ello usé GULP, después vemos como.

Después de esta instrucción ya tendriamos que ser capaces de correr GULP, vamos a probarlo, escribimos en el terminal:

gulp

tendriamos que ver algo parecido a:

[19:15:05] Using gulpfile ~/DEV/uadla/gulpfile.js
[19:15:05] Starting 'default'...
[19:15:05] Finished 'default' after 85 μs

Ya está! Ya tenemos GULP! Ahora queda configurarlo para que nos sea de ayuda en nuestras tareas de desarrollo WEB.
En el proceso os daréis cuenta de que no hay una sola manera de usar GULP, que tiene múltiples packages y que puede usarse para muchas cosas, hay una infinidad de desarrollos creados por la comunidad que hace de GULP una herramienta impresionante. Vamos a ver cuales son los que uso Yo, y a configurarlos.

Configurando GULP

Hay infinidad de plugins que se pueden usar junto a GULP y cada uno con una funciòn diferente, vamos a configurar tan solo unos cuantos. Configuraremos:

  • SASS: Sass nos permite escribir CSS de una forma más sencilla. GULP se encargará de pasar de SASS a CSS.
  • Autoprefixer: Nos mantiene la compatibilidad del CSS con los navegadores mas antiguos. Es decir, nosotros escribimos SASS, y GULP lo transforma en CSS y con Autoprefixer lo hace compatible con navegadores mas antiguos. Nosotros le podemos indicar cuantos.
  • Uglify: Transforma nuestro codigo en algo realmente poco legible para un humano pero perfectamente interpretable por un navegador. Con lo que ahorramos tamaño.
  • Imagemin: Optimizador de imágenes. Para reducir su peso antes de subirlas a producción.

Otros packages que conviene ver (pero que Yo por una razon u otra no uso).

  • browser-sync: Puede indicarle a GULP que este vigilando unos ficheros y lance un proceso cuando estos se modifican. Por ejemplo que recargue la WEB cuando guardas un HTML o CSS.
  • Htmlmin: Como Uglify pero para los ficheros html.

Instalando los plugin de GULP

sudo npm install --save-dev gulp-sass
sudo npm install --save-dev gulp-autoprefixer
sudo npm install --save-dev  gulp-uglify
sudo npm install --save-dev gulp-imagemin
sudo npm install --save imagemin-pngquant

Bueno, seguro que queda muy claro cómo se instalan los plugins que usaremos con GULP. Una vez instalados nos toca usarlos, para ello configuraremos el fichero gulpfile.js del directorio raíz de nuestro proyecto.

Configurando gulpfile.js

En la cabecera del fichero primero declaramos las variables de los plugins que vamos a usar:

var gulp = require("gulp");
var sass = require("gulp-sass");
var autoprefixer = require("gulp-autoprefixer");
var browserSync = require("browser-sync").create();
var uglify = require("gulp-uglify");
var imagemin = require("gulp-imagemin");
var pngquant = require("imagemin-pngquant");
var htmlmin = require("gulp-htmlmin");

En GULP todo se organiza en tareas, hay una tarea por defecto llamada default, que es la que se ejecuta cuando en la línea de comandos escribimos: gulp.

Esta tarea podemos dejarla vacía, o no, podemos crear tantas tareas como queramos. Vamos a ver un ejemplo de una task default de GULP.

gulp.task("default", ["styles"], function() {
gulp.watch("sass/**/*.scss", ["styles"]);
});

Vemos que estamos usando una funciona de la variable gulp (que hemos definido en la cabecera) que se llama watch. Esto le indica a GULP que esté atento a cualquier cambio que ocurra en los ficheros, y en ese caso ejecutará la tarea styles (tarea que tenemos que crear nosotros). Vemos la task styles:

gulp.task("styles", function() {
gulp.src("sass/**/*.scss")
.pipe(sass({outputStyle: "compressed"}).on("error", sass.logError))
.pipe(autoprefixer({browsers: ["last 3 versions"]}))
.pipe(gulp.dest("./static"));
});

Esta tarea se ejecutará cuando se modifique un fichero .scss (fichero sass), pero tambien puede ejecutarse llamandola directamente desde la línea de comandos con: gulp styles.
Lo primero que hacemos es indicar los ficheros sobres los que se realizarán las acciones: gulp.src(“sass/**/*.scss”). A cada uno de los ficheros que cumplan con el patrón indicado (ya habréis adivinado que son ficheros SASS) se le aplicará cada uno de los pipe que se indican. Vamos a ver qué hace cada uno:

  • .pipe(sass({outputStyle: “compressed”}).on(“error”, sass.logError)): Estamos usando la variable sass que hemos definido en la cabecera, en el parametro le decimos que le aplique el formato “compressed” al fichero,
    lo que quiere decir que aparte de transformarlo en CSS le va a quitar los espacios y retornos de carro innecesarios. En caso de error no parará pero nos lo mostrará por el terminal.
  • .pipe(autoprefixer({browsers: ["last 3 versions”]})): Esto es de lo mejor, se encarga automáticamente de incorporar los diferentes prefijos en los valores CSS para que sean compatibles con los browsers que tu indiques. En mi caso le digo que las tres últimas versiones. El se encarga de poner los -webkit o -ie necesarios.
  • .pipe(gulp.dest(“./static”)): Copia los ficheros en el directorio indicado.

Esta tarea toma como entrada unos ficheros SASS de un directorio y nos deja un .CSS comprimido y compatible con varias versiones de los browsers mas conocidos en otro directorio.

Vamos a ver otra tarea de mi fichero de Gulp, la que uso para trabajar con los scripts:

gulp.task("scripts", function() {
gulp.src("scripts/**/*.js")
.pipe(uglify())
.pipe(gulp.dest("../uadla/scripts"));
});

Seguro que ya lo entendeis. Cogemos todos los ficheros que cuadran con el patrón de entrada. Los pasamos por el uglify, lo que los deja feos e ilegibles pero interpretables, y los copiamos en otro directorio.

Veamos mi fichero de GULP entero:

var gulp = require("gulp");
var sass = require("gulp-sass");
var autoprefixer = require("gulp-autoprefixer");
var browserSync = require("browser-sync").create();
var uglify = require("gulp-uglify");
var imagemin = require("gulp-imagemin");
var pngquant = require("imagemin-pngquant");
var htmlmin = require("gulp-htmlmin");
gulp.task("default", ["["styles"]function() {
gulp.watch("sass/**/*.scss", ["["styles"]
browserSync.init({
server: "http://localhost:8080"
});
});
gulp.task("dist", [[
"styles",
"html",
"scripts"]function() {
gulp.src("./static/*.css")
.pipe(gulp.dest("../uadla/static"));
gulp.src("./static/*.{svg,gif,jpg,ico}")
.pipe(imagemin())
.pipe(gulp.dest("../uadla/static"));
gulp.src("./*.{py,pyc,xml,yaml}")
.pipe(gulp.dest("../uadla"));
});
gulp.task("scripts", function() {
gulp.src("scripts/**/*.js")
.pipe(uglify())
.pipe(gulp.dest("../uadla/scripts"));
});
gulp.task("html", function() {
gulp.src("./*.html")
.pipe(gulp.dest("../uadla"));
});
gulp.task("styles", function() {
gulp.src("sass/**/*.scss")
.pipe(sass({outputStyle: "compressed"}).on("error", sass.logError))
.pipe(autoprefixer({browsers: ["["last 3 versions"])
.pipe(gulp.dest("./static"));
});

La única tarea que introduce algo que no hemos visto es la dist. Es la que utilizo cuando creo que ya he acabado con el desarrollo, he realizado unas pruebas en bruto y decido pasar a distribución. Me aplica las tareas indicadas y copia los ficheros necesarios en el directorio previo a la subida a producción. Las pruebas que realizó después de ejecutar gulp dist ya son con los mismos ficheros que irán a producción. En este punto es también donde se optimizan las imágenes.

Empezando un proyecto WEB desde 0

Configurar nuestro entorno y entender GULP es muy importante, muchos hemos perdido mucho tiempo en estas dos cosas, o al principio nos hemos resistido a usar nada que no fuera un editor simple. Uno de los pasos que mas cuentan es crear una estructura de ficheros que funcione, que los CSS esten donde tienen que estar, igual que los Html, o los script, o los javascript, o como en mi caso el codigo servidor en python. Yo empece a lo bruto, todo en un directorio y he aprendido a ostias.
No hace falta repetir este error, lo mejor es pasarse por yeoman, donde se pueden encontrar esqueletos para que empieces tu proyecto con una estructura correcta y ya con todo lo que se tiene que instalar correctamente instalado y configurado…. uauhhh!! Seguro que vale la pena perder unas horas viendo como funciona.

Comentarios.