Modo de producción de Parcel

Guía para subir nuestra app con Parcel


Hemos visto el modo de desarrollo de Parcel, que permite iniciar un servidor local para ir viendo los resultados en el navegador mientras editamos cómodamente. Sin embargo, en algún momento llegará la hora de subir o desplegar nuestra web a un servidor o alojamiento, lo que comúnmente llamamos un servidor de producción.

Para ello, debemos saber que no se debe subir la carpeta generada con el modo de desarrollo, sino que tenemos que utilizar el modo de producción o modo build de Parcel, que generará esos archivos finales de una forma más apropiada.

Modo de producción

El modo de producción de Parcel se consigue ejecutando el modo build en lugar del modo serve o watch. Veamos un ejemplo a continuación:

$ npx parcel build src/index.html

Esto generará los archivos finales en la carpeta dist (por defecto), aunque se puede modificar con el parámetro --dist-dir. Veamos que otros parámetros podemos utilizar (recuerda siempre que los parámetros van antes de src/index.html):

Parámetro Descripción
--no-optimize Desactiva la minificación de código (por defecto, activada).
--no-scope-hoist Desactiva el «scope hoisting», que elimina código no utilizado.
--public-url url Añade un prefijo a las url con assets o ficheros de código.
--dist-dir ruta Indica la ruta de destino cuando no se indican targets.
--detailed-report n Establece un máximo de n entradas por grupo en el resumen generado.

En primer lugar, podemos indicar el parámetro --no-optimize, lo que desactivará la minificación de código (uglify), o lo que es lo mismo, no eliminará espacios, enter y otros carácteres no necesarios para que el navegador pueda leer e interpretar el código correctamente. Esto se suele usar en el modo de producción para reducir el tamaño final del archivo generado.

Por otro lado, el parámetro --no-scope-hoist, desactiva la posibilidad de eliminar código no utilizado, ya que el scope hoisting lo que hace es detectar porciones de código que no se utilizan en la web, y las elimina o sustituye por un código vacío. Al contrario que en el modo serve o watch, el modo build tiene el scope hoisting activado por defecto.

El parámetro --public-url nos permite cambiar el prefijo de la URL, cuando nos referimos a ciertos assets o ficheros de código de nuestra web. Esto es algo muy habitual cuando desplegamos en GitHub Pages por ejemplo, ya que necesita modificar la URL de los assets y añadir el nombre del repositorio para que GitHub Pages despliegue y haga referencia a una dirección URL adecuada, de tipo https://user.github.io/repo-name/.

Para ilustrar esto mejor, consideremos el siguiente HTML:

<link rel="stylesheet" href="./css/index.css">

En modo desarrollo, la url enlazada sería https://localhost:1234/css/index.css. La página web generada funcionaría perfectamente y no habría ningún problema.

En modo producción, la url enlazada debería ser https://user.github.io/repo-name/css/index.css para que funcionara correctamente en GitHub Pages. Con el parámetro --public-url /repo-name/ conseguimos justo eso, que se añada ese prefijo y funcione correctamente.

Otros parámetros

Existen otros parámetros interesantes como --no-cache, para desactivar la cache de ficheros de Parcel, el parámetro --cache-dir, que permite establecer una carpeta de cache diferente a .parcel-cache/ o --no-source-maps, para evitar la generación de ficheros .map, entre otros parámetros que podemos ver en la siguiente tabla:

Parámetro Descripción
--no-cache Desactiva el caché de ficheros de Parcel.
--cache-dir ruta Indica la carpeta a usar de cache. Por defecto, .parcel-cache.
--no-source-maps No crea ficheros .map, que actuan de mapas entre ficheros originales y generados.
--target nombre Sólo construye el objetivo indicado. Por defecto, [].
--log-level nivel Establece el nivel de error: none, error, warn, info o verbose.
--profile Activa el «profiling» en la generación de builds.

Estos parámetros son comunes con el modo de desarrollo de Parcel y se explican en dicha sección anterior, Modo de desarrollo de Parcel, por lo que puedes echar un vistazo allí.

Parámetros de configuración

Otro parámetro interesante en el modo build de Parcel podría ser --no-content-hash. Por defecto, Parcel cambia el nombre de los archivos .css, .js, imágenes, etc... Esto lo hace para evitar problemas de invalidación de caché y que evitar que la web no se actualice en sistemas de cache muy agresivos:

src/index.html => dist/index.html
src/css/index.css => dist/index.be319887.css
src/js/index.js => dist/index.d07cbd8c.js

Si tras haber creado una build, volvemos a lanzar Parcel para volver a generar otra, los hashes (be319887, d07cbd8c, ...) cambiarán. Esto también hará que se vayan acumulando versiones antiguas en la carpeta, por lo que podría ser interesante automatizar la limpia de carpetas cada cierto tiempo.

Con el parámetro --no-content-hash no desactivas la generación de dichos hash, pero si lo haces de modo que no depende y no se genera en base al contenido.

Parámetro Descripción
--no-content-hash Desactiva la creación de hash en en base al contenido de los ficheros.
--config path Permite indicar un fichero de configuración .parcelrc.

Por último, y como novedad en Parcel 2, es posible indicar un fichero de configuración, por defecto llamado .parcelrc y situado en el raíz del proyecto. Este fichero de configuración permite indicar el comportamiento que tendrán ciertos plugins de Parcel respecto a nuestro proyecto.

Por ejemplo, el siguiente fichero .parcelrc sería un ejemplo inicial de fichero de configuración:

{
  "extends": "@parcel/config-default",
  "transformers": {
    "*.{png,jpg}": ["@parcel/transformer-raw"],
    "*.{ts,tsx}": ["@parcel/transformer-typescript-tsc"]
  }
}

En este ejemplo de configuración de .parcelrc estamos indicando a Parcel que aplique la configuración por defecto que puede obtener del paquete @parcel/config-default, y que aplique los transformadores dependiendo de la extensión de los archivos que encuentre al seguir enlaces desde Javascript:

  • Si son imágenes: Aplica el transformador @parcel/transfomer-raw
  • Si son archivos Typescript: Aplica el transformador @parcel/transformer-typescript-tsc.

Si no creamos este archivo de configuración, por defecto, nos mostrará un error como el siguiente:

🚨 Build failed.
Error: No transformers found for /home/manz/workspace/project-demo/src/assets/image.jpg.

Más adelante, en otro artículo, hablaremos de los ficheros de configuración de plugins de Parcel y como podemos adaptarlo a nuestro gusto.

Ejemplo de Parcel para GitHub Pages

El siguiente ejemplo sería un caso en el que configuraremos varios scripts de NPM en el package.json del proyecto que utilizarán Parcel para:

  • npm run start: Crea un servidor local para tareas de desarrollo
  • npm run build: Crea una nueva build en la carpeta build
  • npm run deploy: Sube el contenido de build y lo despliega en la rama gh-pages

El contenido de estos scripts sería el siguiente:

{
  "scripts": {
    "start": "parcel serve -d dist src/index.html",
    "build": "parcel build -d build --public-url /repo-name/ src/index.html",
    "deploy": "gh-pages -d build"
  }
}

Observa que habría que modificar /repo-name/ con el nombre del repo de GitHub para que funcione adecuadamente. También habría que instalar el paquete gh-pages con el comando npm install -D gh-pages.

Si queremos simplificarlo aún más y no separar las tareas build y deploy, o incluso borrar la carpeta build para no acumular ficheros antiguos, podríamos hacer lo siguiente:

{
  "scripts": {
    "start": "parcel serve -d dist src/index.html",
    "deploy": "rm -rf build && parcel build -d build --public-url /repo-name/ src/index.html && gh-pages -d build"
  }
}

En este caso, la tarea npm run deploy se encarga de eliminar la carpeta build/ y su contenido, volverla a generar con Parcel y si todo ha ido bien, desplegarlo en la rama gh-pages.

¿Quién soy yo?

Soy Manz, vivo en Tenerife (España) y soy streamer partner en Twitch y profesor. Me apasiona el universo de la programación web, el diseño y desarrollo web y la tecnología en general. Aunque soy full-stack, mi pasión es el front-end, la terminal y crear cosas divertidas y locas.

Puedes encontrar más sobre mi en Manz.dev