Header Ads Widget

Ticker

6/recent/ticker-posts

Snowpack + Eleventy + Sass + PostCSS

 Pude crear una configuración de Eleventy + Snowpack + Sass + PostCSS que funciona bastante bien. Quiero compartir esta configuración con ustedes en este artículo.

Estructura de archivo

Básicamente, hay dos formas de estructurar el código fuente:

  1. Pon todo lo que escribes dentro de una srccarpeta
  2. Divida la srccarpeta en dos: viewspublic.

Yo suelo utilizar el primer método. Pero decidí probar el segundo método esta vez. Lo probé porque Snowpack facilita el montaje de carpetas en un servidor de desarrollo.

Quería dividirme srcen viewsstaticporque puedo usarlos para responsabilidades específicas:

  • views se usa para todo lo relacionado con 11ty
  • static se utiliza para todos los activos estáticos (CSS, JS, imágenes, etc.).

Nota: usaremos CSS aquí por ahora. Agregaré Sass más tarde.

project
  |- views
    |- _includes
    |- index.njk
    |- Other 11ty related files
  |- static
    |- css
      |- styles.css
    |- images
      |- image.png
    |-js
      |- main.js

Once config

Primero, necesitas instalar Eleventy.

npm install @11ty/eleventy --save-dev

Para que esta estructura de archivos funcione, configuré Eleventy con un .eleventy.jsarchivo.

Aquí, me puse inputviewsoutputdist.

module.exports = function (eleventyConfig) {
  return {
    dir: {
      input: "views",
      output: "dist",
    },
  }
}

Servidor de desarrollo Snowpack

Si no conoce Snowpack, le sugiero que lea la entrada del blog de introducción de Snowpack y mis notas sobre Snowpack antes de continuar con el resto de este artículo.

Primero, asegúrese de instalar Snowpack.

npm install snowpack --save-dev

Podemos ejecutar comandos para Snowpack dentro de un snowpack.config.jsonarchivo. Aquí, hice distla raíz del servidor de Snowpack con un mountscript.

// snowpack.config.json
"scripts": {
  "mount:eleventy": "mount dist --to /",
}

También tuve que montar la staticcarpeta para poder acceder a mi CSS, imágenes y otros activos.

"scripts": {
  "mount:eleventy": "mount dist --to /",
  "mount:static": "mount static --to /",
}

Puedo acceder a activos estáticos desde mis archivos Eleventy como este:

<!-- CSS -->
<link rel="stylesheet" href="/css/styles.css">

<!-- JavaScript -->
<script src="/js/main.js"></script>

<!-- Images -->
<img src="/images/image.png" />

El siguiente paso es ejecutar once. Aquí, podemos usar un runscript. También miramos el once con un ::watchmodificador .

"scripts": {
  "mount:eleventy": "mount dist --to /",
  "mount:static": "mount static --to /",
  "run:eleventy": "eleventy",
  "run:eleventy::watch": "$1 --watch",
}

Hagamos correr la capa de nieve:

npx snowpack dev

Debería ver este registro. También se abrirá un navegador. Este navegador te dirige a http://localhost:8080(que es donde está alojado el servidor de desarrollo de Snowpack).

Finalmente lo configuré snowpack devcomo un script npm para poder usarlo npm run devnpm run deves más fácil para mí escribir porque tengo un alias para ello.

// package.json
"scripts": {
  "dev": "snowpack dev"
}

Ajustar el servidor de desarrollo

Configuré cuatro opciones para el servidor de desarrollo:

"devOptions": {
  "port": 3000,
  "open": "none",
  "bundle": false,
  "out": "dist"
}
  • portporque prefiero usar :3000over :8080.
  • opennoneporque no quiero que los navegadores abran una pestaña.
  • bundlepara falsesilenciar el bundleregistro.
  • outdistporque quiero que mi compilación final esté en una distcarpeta. (Aparece cuando corres snowpack build).

Intenta correr snowpack buildDebería ver un distEsta distcarpeta debe contener sus archivos generados por 11ty + archivos estáticos.

npx snowpack build
Carpeta Snowpack Dist.

Nuevamente, utilicé un script npm. Configuré esto en build.

"scripts": {
  "build": "snowpack build"
}

JavaScript

Snowpack le permite importar paquetes desde npm listos para usar. Aquí, debe asegurarse de guardar su paquete como archivo dependency.

Por ejemplo, instalemos un canvas-confetti paquete que crea confeti (que viene incluido en los ejemplos de Snowpack 😃).

npm install canvas-confetti --save

Podemos importar este canvas-confettipaquete en el archivo JavaScript.

// main.js
import confetti from 'canvas-confetti'

// Adds a canvas element to the HTML
const canvas = document.createElement('canvas')
canvas.style.width = '100vw';
canvas.style.height = '100vh';
document.body.appendChild(canvas)

// Makes confetti
confetti.create(canvas, {
  resize: true,
  useWorker: true
})({ particleCount: 200, spread: 200 })

Cuando corra snowpack build, debería ver una web_modulescarpeta. Esta web_modulescarpeta contiene las dependencias que importamos.

Snowpack JavaScript.

Snowpack también apuntará sus declaraciones de importación a esta /web_modulescarpeta automáticamente.

// In dist/js/main.js
import confetti from '/web_modules/canvas-confetti'

Sass + PostCSS

Snowpack tiene una peculiaridad extraña: los scripts en los que escribe se snowpack.config.jsonejecutan de forma asincrónica . No puede hacer que un guión dependa de otro.

Esto significa que no podemos usar Sass, luego PostCSS dentro con runscripts. Este es un gran problema.

La mejor solución que encontré es ejecutar Sass a través de PostCSS. Podemos hacer esto con postcss-sass de Jonathan Neal. Para usar postcss-sass, necesitamos instalar tres módulos:

  1. postcss-cli
  2. postcss-scss
  3. @csstools/postcss-sass

Aquí está el comando para instalar los tres módulos:

npm install postcss-cli postcss-scss @csstools/postcss-sass --save-dev

Configuración de PostCSS

Podemos configurar PostCSS con un postcss.config.jsarchivo. Me puse syntaxpostcss-scssdecirle a PostCSS a esperar un .scssarchivo. Luego, utilicé el complemento postcss-sass para hacer la parte de Sass.

También agregué una includePathsopción para poder importar bibliotecas desde node_modules.

module.exports = {
  syntax: 'postcss-scss',
  plugins: [
    require('@csstools/postcss-sass')({
      includePaths: ['./node_modules']
    }),
  ]
}

También agregué Autoprefixer a la compilación.

npm install autoprefixer --save-dev
module.exports = {
  syntax: 'postcss-scss',
  plugins: [
    require('@csstools/postcss-sass')({
      includePaths: ['./node_modules']
    }),
    require('autoprefixer')
  ]
}

Configuración de Snowpack para Sass + PostCSS

Como quiero staticcontener archivos fuente, cambié el formato static/cssstatic/scss.

project
  |- static
    |- scss
      |- styles.scss
  |- ...

El runguión con el que vine se ve así:

"scripts": {
  "run:css": "postcss static/scss/**/[^_]*.scss --dir dist/css --ext css",
  "run:css::watch": "$1 --watch"
},

Hace cinco cosas:

  1. Coge todos los .scssarchivos (excepto los parciales)
  2. Transformarlos con postcss
  3. Salida de los archivos dentro dist/css
  4. Cambie la extensión del archivo a .css
  5. Observe los .scssarchivos en busca de cambios (al usarlos snowpack dev).

Este proceso funciona bastante bien, pero me preocupan dos cosas.

Postcss-sass puede estar desactualizado

Se trabaja activamente en Dart Sass y Node Sass. La última vez que lo comprobé, Node Sass se actualizó hace 20 días. Sin embargo, el complemento postcss-sass de Jonathan se actualizó hace 14 meses.

También hay una diferencia considerable en las versiones de Sass. (10 versiones menores cuando revisé).

Me preocupan los retrasos en la actualización de este paquete. Estaré muy feliz si Jonathan mantiene el paquete actualizado, pero no podemos estar seguros de que esto suceda.

Preferiría usar el Sass -> PostCSSenfoque tradicional si es posible ... pero es imposible configurar esto con Snowpack (a menos que me esté equivocando).

Problemas con Sourcemaps

Los mapas de origen generados con el proceso anterior no se vinculan a los .scssarchivos. Se vincula al .cssarchivo generado ... por lo que los mapas de origen no son muy útiles.

No puedo encontrar una solución para esto después de horas de buscar en Google, así que me di por vencido.

Limpiar

Me gusta limpiar los archivos generados antes de ejecutar snowpack devsnowpack buildHago esto con del.

npm install del-cli --save-dev
"scripts": {
  "clean": "del dist",
  "dev": "npm run clean && snowpack dev",
  "build": "npm run clean && snowpack build"
}

Implementando

Ahora puedo crear un sitio con npm run buildLa distcarpeta generada está lista para su implementación.

El proceso de implementación ya está completo si utilizo Netlify para atender mis sitios. Realiza más optimizaciones y eliminación de caché automáticamente.

Pero es otra historia si no uso Netlify.

Minificación y optimización

Snowpack tiene buildscripts que se ejecutan después de los runscripts, imagino que podemos ejecutar cssnanopara minimizar CSS y terserminificar JavaScript. No los probé porque todavía no tengo tiempo para hacerlo.

Supongo que también podemos optimizar la imagen con imagemin… Así que no hay problemas reales con la optimización.

El verdadero problema es el almacenamiento en caché.

Destrucción de caché

Podemos almacenar en caché el busto de tres maneras:

  • Usando cadenas de consulta (como style.css?v=3.4.1)
  • Agregar un hash al nombre del archivo (como style.232124.css)
  • Usando ETags

CSS Tricks tiene un artículo completo que habla sobre cada una de estas estrategias si desea obtener más información.

Tradicionalmente, la mejor manera de almacenar en caché el busto es agregar un hash al archivo. Este hash se basa en el contenido del archivo, por lo que cambia cuando cambia el contenido. Webpack usa este método para generar hashes.

También utilicé el método hash para generar hash para este blog.

Sin embargo, para usar un hash con un generador de sitios estáticos como Eleventy, debe:

  1. Primero compile los archivos CSS y JavaScript.
  2. Guarde los detalles del hash en algún lugar
  3. Introduzca los detalles del hash en Eleventy.
  4. Deje que Eleventy genere los archivos.

Lo que significa que tenemos que usar Snowpack como parte de un proceso de compilación de npm o un script de compilación de gulp. Se siente como si estuviera mezclando demasiadas herramientas y esto no me gusta. Quizás me esté perdiendo algo aquí.

Segundo problema con el almacenamiento en caché: ¿Cuál es la mejor manera de almacenar en caché los archivos ESM? No he investigado sobre este proceso, por lo que aún no tengo respuestas.

De todos modos, el almacenamiento en caché es un problema con el que todavía lucho en un entorno Snowpack. Si tiene respuestas, ¡hágame saber cómo lo maneja! Mis ojos están abiertos :)

Publicar un comentario

0 Comentarios