Para este tutorial, voy a dar por sentado que ya sabes lo que es un módulo UMD, incluso que ya has desarrollado uno. De no ser así, no te preocupes, que publicaré un post sobre el tema en breve.

Si has llegado a este punto, probablemente seas un desarrollador de paquetes NPM con una versión UMD. Y, además, necesitarás servirla desde un CDN para que otras personas puedan usarla.

Seguramente hayas intentado, como yo, usar la combinación Github + Rawgit. Es una buena opción, pero te obliga a comitear la carpeta umd a Github, cosa que afea mucho el código y que dificulta enormemente los diff en las pull-request.

Me gustaría enseñarte una opción mucho mejor: ¿qué te parece si te digo que puedes publicar en Github las fuentes de tu proyecto y en NPM el código compilado, además de disponer de una URL pública (que está detrás de un CDN) para poder acceder al fichero de tu paquete de NPM? Pues esto es exactamente lo que hace NPMCDN.

Proyecto

Para ilustrar mejor lo que es NPMCDN, vamos a crear un proyecto que implementa un cliente de la PokeAPI.

Primero, creamos una estructura bastante simple de ficheros, compuesta por nuestro package.json y el código de nuestro cliente de la API:

.
├── README.md
├── package.json
├── src
    └── index.js

En el código de la API pondremos:

import axios from 'axios'

export default class CVPokeapi {

  static get ROOT(){return "http://pokeapi.co/api/v1/"}

  constructor () {
    this._fetcher = axios
  }

  pokemon({id} = {}){
    return this._fetcher.get(`${CVPokeapi.ROOT}pokemon/${id}`).then(response => response.data);
  }
}

Como puedes ver, lo importante no es el código del proyecto en sí, que no puede ser más simple. Lo interesante comienza cuando nos proponemos que los usuarios de Node mediante NPM puedan usar nuestro cliente. También queremos poder cargar el proyecto como un módulo UMD.

Para ello vamos a crear las siguientes tareas NPM en nuestro package.json

{
  "name": "cvpokeapi",
  "version": "0.2.2",
  "description": "código usado en el post:",
  "main": "index.js",
  "files": [
    "lib",
    "umd"
  ],
  "scripts": {
    "build": "babel src -d lib",
    "umd": "mkdir -p umd && npm run umd:development && npm run umd:min",
    "umd:development": "browserify -t babelify src/index.js --standalone CVPokeapi -o umd/cvpokeapi.umd.js -d",
    "umd:min": "browserify -t babelify src/index.js --standalone CVPokeapi | uglifyjs > umd/cvpokeapi.umd.min.js",
    "prepublish": "npm run build && npm run umd"
  },
  "repository": {
    "type": "git",
    "url": "git+https://github.com/carlosvillu-com/npmcdn.git"
  },
  "keywords": [],
  "author": "Carlos Villuendas <carlosvillu@gmail.com>",
  "license": "MIT",
  "bugs": {
    "url": "https://github.com/carlosvillu-com/npmcdn/issues"
  },
  "homepage": "https://github.com/carlosvillu-com/npmcdn#readme",
  "dependencies": {
    "axios": "0.9.1"
  },
  "devDependencies": {
    "babel": "6.5.2",
    "babel-cli": "6.7.5",
    "babel-preset-es2015": "6.6.0",
    "babelify": "7.2.0",
    "browserify": "13.0.0",
    "live-server": "0.9.2",
    "uglify-js": "2.6.2"
  },
  "babel": {
    "presets": [
      "es2015"
    ]
  }
}

La parte más importante de este package.json son estas dos claves:

  "files": [
    "lib",
    "umd"
  ],
  "scripts": {
    "build": "babel src -d lib",
    "umd": "mkdir -p umd && npm run umd:development && npm run umd:min",
    "umd:development": "browserify -t babelify src/index.js --standalone CVPokeapi -o umd/cvpokeapi.umd.js -d",
    "umd:min": "browserify -t babelify src/index.js --standalone CVPokeapi | uglifyjs > umd/cvpokeapi.umd.min.js",
    "prepublish": "npm run build && npm run umd"
  },

Primero nos vamos a centrar en los scripts:

  • build: transpila el código con Babel y lo deja preparado para importarlo desde cualquier proyecto de Node.
  • umd: en sus dos variantes, genera el bundle UMD usando Browserify y partiendo del punto de entrada del proyecto.

Cuando estos dos scripts se ejecutan, generan dos nuevas carpetas en nuestro proyecto: lib y umd.

Normalmente, ignoramos lib en git y nos vemos obligados a comitear la carpeta umd para que sea accesible desde Gitraw.

Pues bien, en este caso ignoraremos, además, la carpeta umd, tal y como hemos hecho con la carpeta lib:

// .gitignore
lib/  
umd/  
node_modules/  

Así, a nuestro repositorio solo vamos a subir la carpeta de sources, como debería ser siempre. En cambio, en nuestro package.json en la clave files indicamos que queremos subir solo la carpeta lib y umd ignorando el resto de carpetas, entre ellas, src.

Con esto conseguimos tener en NPM solo los siguientes ficheros:

.
├── README.md
├── lib
│   └── index.js
├── package.json
└── umd
    ├── cvpokeapi.umd.js
    └── cvpokeapi.umd.min.js

Esto es fantástico, porque solo tenemos código compilado y nada de las fuentes; también, como debería ser.

Ahora ya podemos añadir en cualquier página web un script que cargue nuestro módulo UMD recién publicado a UMD para poder usarlo:

<script src="https://npmcdn.com/cvpokeapi@0.2.2/umd/cvpokeapi.umd.js"></script>  

El formato de la url de NPMCDN tiene la siguiente forma:

https://npmcdn.com/package@version/path/to/file.  

Dejo el código fuente que he usado en este tutorial en mi cuenta de Github para que lo podáis bichear todo lo que quieras :)

Si te ha gustado este post, difunde la palabra. Tampoco dudes en dejar comentarios u observaciones. ¡Gracias! :)

Suscríbete a mi lista de correo

* Campos obligatorios