style9: CSS en JS en tiempo de compilación

Índice
  1. ¿Por qué otra biblioteca CIJ?
  2. He aquí cómo usarlo
  3. Definiendo estilos
  4. Estilos de resolución
  5. Combinando estilos
  6. resumen

En abril del año pasado, Facebook reveló su gran nuevo rediseño. Un proyecto ambicioso, era la reconstrucción de un sitio grande con una gran cantidad de usuarios. Para lograr esto, utilizaron varias tecnologías que ellas mismas crearon y de código abierto, como React, GraphQL, Relay y una nueva biblioteca CSS-in-JS llamada stylex.

Esta nueva biblioteca es interna de Facebook, pero han compartido suficiente información al respecto para hacer posible una implementación de código abierto, style9.

¿Por qué otra biblioteca CIJ?

Ya existen muchas bibliotecas CSS-in-JS (CIJ), por lo que puede que no sea obvio por qué se necesita otra. style9 tiene los mismos beneficios que todas las demás soluciones CIJ, como lo expresó Christopher Chedeau, incluidos selectores de alcance, eliminación de código muerto, resolución determinista y la capacidad de compartir valores entre CSS y JavaScript.

Sin embargo, hay un par de cosas que hacen que style9 sea único.

Tiempo de ejecución mínimo

Aunque los estilos están definidos en JavaScript, el compilador los extrae en un archivo CSS normal. Eso significa que no se envían estilos en su archivo JavaScript final. Lo único que queda son los nombres finales de las clases, que el tiempo de ejecución mínimo impuesto condicionalmente, tal como lo haría normalmente. Esto da como resultado paquetes de código más pequeños, una reducción en el uso de memoria y una renderización más rápida.

Dado que los valores se extraen en el tiempo de compilación, no se pueden utilizar valores verdaderamente dinámicos. Afortunadamente, estos no son muy comunes y, dado que son únicos, no se ven afectados por la definición en línea. Lo que es más común es aplicar estilos condicionalmente, lo cual por supuesto es compatible. También lo son las constantes locales y las expresiones matemáticas, gracias a Babel path.evaluate.

Salida atómica

Debido a cómo funciona style9, cada declaración de propiedad se puede convertir en su propia clase con una única propiedad. Entonces, por ejemplo, si usamos opacity: 0en varios lugares de nuestro código, solo existirá una vez en el CSS generado. El beneficio de esto es que el archivo CSS crece con la cantidad de declaraciones únicas, no con la cantidad total de declaraciones. Dado que la mayoría de las propiedades se utilizan muchas veces, esto puede generar archivos CSS dramáticamente más pequeños. Por ejemplo, la antigua página de inicio de Facebook usaba 413 KB de CSS comprimido con gzip. El rediseño utiliza 74 KB para todas las páginas. Nuevamente, un tamaño de archivo más pequeño conduce a un mejor rendimiento.

Algunos pueden quejarse de esto, que los nombres de clases generados no son semánticos, que son opacos y que ignoran la cascada. Esto es cierto. Tratamos a CSS como un objetivo de compilación. Pero por una buena razón. Al cuestionar las mejores prácticas asumidas previamente, podemos mejorar tanto la experiencia del usuario como la del desarrollador.

Además, style9 tiene muchas otras características excelentes, que incluyen: estilos escritos usando TypeScript, eliminación de estilos no utilizados, la capacidad de usar variables de JavaScript y soporte para consultas de medios, pseudoselectores y fotogramas clave.

He aquí cómo usarlo

Primero, instálalo como de costumbre:

npm install style9

style9 tiene complementos para Rollup, Webpack, Gatsby y Next.js, todos ellos basados ​​en un complemento de Babel. Las instrucciones sobre cómo usarlos están disponibles en el repositorio. Aquí usaremos el complemento webpack.

const Style9Plugin = require('style9/webpack');const MiniCssExtractPlugin = require('mini-css-extract-plugin');module.exports = {  module: {    rules: [      // This will transform the style9 calls      {        test: /.(tsx|ts|js|mjs|jsx)$/,        use: Style9Plugin.loader      },      // This is part of the normal Webpack CSS extraction      {        test: /.css$/i,        use: [MiniCssExtractPlugin.loader, 'css-loader']      }    ]  },  plugins: [    // This will sort and remove duplicate declarations in the final CSS file    new Style9Plugin(),    // This is part of the normal Webpack CSS extraction    new MiniCssExtractPlugin()  ]};

Definiendo estilos

La sintaxis para crear estilos se parece mucho a la de otras bibliotecas. Empezamos llamando style9.createcon objetos de estilos:

import style9 from 'style9';const styles = style9.create({  button: {    padding: 0,    color: 'rebeccapurple'  },  padding: {    padding: 12  },  icon: {    width: 24,    height: 24  }});

Debido a que todas las declaraciones darán como resultado clases atómicas, abreviaturas como flex: 1y background: blueno funcionarán, ya que establecen múltiples propiedades. Las propiedades que se pueden expandir, como padding, margin, overflow, etc., se convertirán automáticamente a sus variantes escritas a mano. Si usa TypeScript, recibirá un error al usar propiedades no admitidas.

Estilos de resolución

Para generar un nombre de clase, ahora podemos llamar a la función devuelta por style9.create. Acepta como argumentos las claves de los estilos que queremos utilizar:

const className = styles('button');

La función funciona de tal manera que los estilos de la derecha tienen prioridad y se fusionarán con los estilos de la izquierda, como Object.assign. Lo siguiente daría como resultado un elemento con un relleno de 12px y con rebeccapurpletexto.

const className = styles('button', 'padding');

Podemos aplicar estilos condicionalmente usando cualquiera de los siguientes formatos:

// logical ANDstyles('button', hasPadding  'padding');// ternarystyles('button', isGreen ? 'green' : 'red');// object of booleansstyles({  button: true,  green: isGreen,  padding: hasPadding});

Estas llamadas a funciones se eliminarán durante la compilación y se reemplazarán con concatenación directa de cadenas. La primera línea del código anterior será reemplazada por algo como 'c1r9f2e5 ' + hasPadding ? 'cu2kwdz ' : ''. Ningún tiempo de ejecución se queda atrás.

Combinando estilos

Podemos extender un objeto de estilo accediendo a él con un nombre de propiedad y pasándolo a style9.

const styles = style9.create({ blue: { color: 'blue; } });const otherStyles = style9.create({ red: { color: 'red; } });// will be redconst className = style9(styles.blue, otherStyles.red);

Al igual que con la llamada a función, los estilos de la derecha tienen prioridad. Sin embargo, en este caso, el nombre de la clase no se puede resolver estáticamente. En cambio, los valores de las propiedades serán reemplazados por clases y se unirán en el tiempo de ejecución. Las propiedades se agregan al archivo CSS como antes.

resumen

Los beneficios de CSS-in-JS son muy reales. Dicho esto, estamos imponiendo un costo de rendimiento al incorporar estilos en nuestro código. Al extraer los valores durante el tiempo de construcción, podemos tener lo mejor de ambos mundos. Nos beneficiamos de la ubicación conjunta de nuestros estilos con nuestro marcado y la capacidad de utilizar la infraestructura JavaScript existente, al mismo tiempo que podemos generar hojas de estilo óptimos.

Si style9 te parece interesante, echa un vistazo al repositorio y pruébalo. Y si tiene alguna pregunta, no dude en abrir un problema o ponerse en contacto.

Agradecimientos

Gracias a Giuseppe Gurgone por su trabajo en hojas de estilo y dss, Nicolas Gallagher por reaccionar-nativo-web, Satyajit Sahoo y todos en Callstack por linaria, Christopher Chedeau, Sebastian McKenzie, Frank Yan, Ashley Watkins, Naman Goel y todos los demás. . que trabajó en stylex en Facebook para tener la amabilidad de compartir sus lecciones públicamente. Y a todos los demás a los que he echado de menos.

Enlaces

  • johanholmerin/estilo9
  • Construyendo el nuevo facebook.com con React, GraphQL y Relay – 30 de abril de 2019
  • Construyendo el nuevo Facebook con React y Relay | Frank Yan – 30 de octubre de 2019
  • Reconstrucción de la pila tecnológica para un nuevo Facebook.com – 8 de mayo de 2020
  • johanholmerin/style9-components.macro: API de componentes con estilo para style9 – experimental
SUSCRÍBETE A NUESTRO BOLETÍN 
No te pierdas de nuestro contenido ni de ninguna de nuestras guías para que puedas avanzar en los juegos que más te gustan.

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Subir

Este sitio web utiliza cookies para mejorar tu experiencia mientras navegas por él. Este sitio web utiliza cookies para mejorar tu experiencia de usuario. Al continuar navegando, aceptas su uso. Mas informacion