Facebook released its major revision last April. This is an ambitious project, a reconstruction of a huge website with a large number of users. To achieve this, they used several technologies that they created and open sourced on their own, such as React, GraphQL, Relay and a new CSS-in-JS library called stylex.
This new library is used internally by Facebook, but they shared enough information to make it possible to implement style9 open source.
Why do you need another CIJ library?
There are already a large number of CSS-in-JS (CIJ) libraries, so it may not be clear why another library is needed. As Christopher Chedeau explains, style9 has the same benefits as all other CIJ solutions, including scope selectors, dead code elimination, deterministic parsing, and the ability to share values ??between CSS and JavaScript.
However, there are some aspects that make style9 unique.
Minimum runtime
Although styles are defined in JavaScript, they are extracted by the compiler into regular CSS files. This means that the final JavaScript file will not contain any styles. The only thing left is the final class name, which the smallest runtime will conditionally apply, just like you usually do. This will result in smaller code packages, reduced memory usage, and faster rendering.
Since values ??are extracted at compile time, truly dynamic values ??cannot be used. Fortunately, these values ??are not common and since they are unique, they are not affected by inline definitions. More common is the application of styles conditionally, which is of course supported. Thanks to babel's path.evaluate, local constants and mathematical expressions are also supported.
Atomic output
Due to the way style9 works, each property declaration can become a separate class with a single property. For example, if we use opacity: 0 in multiple places in our code, it will only exist once in the generated CSS. The benefit of this is that the size of the CSS file grows with the number of unique declarations , not with the total number of declarations. Since most properties are used multiple times, this can cause a large reduction in the CSS file. For example, Facebook's old homepage used 413 KB of gzip compressed CSS. After the revision, the CSS size of all pages is 74 KB. Similarly, smaller file sizes lead to better performance.
Some people may complain about this, thinking that the generated class names are not semantic, that they are opaque and ignore cascades. This is true. We consider CSS as a compilation target. But there is a good reason. By questioning the practices that were previously considered best, we can improve the experience for both users and developers.
In addition, style9 has many other powerful features, including: typed styles with TypeScript, eliminating unused styles, the ability to use JavaScript variables, and support for media queries, pseudo-selectors, and keyframes.
How to use it
First, install it as usual:
<code>npm install style9</code>
style9 has plugins for Rollup, Webpack, Gatsby, and Next.js, all based on Babel plugins. Instructions on how to use them are found in the repository. Here we will use the webpack plugin.
<code>const Style9Plugin = require('style9/webpack'); const MiniCssExtractPlugin = require('mini-css-extract-plugin'); module.exports = { module: { rules: [ // 這將轉(zhuǎn)換style9調(diào)用{ test: /\.(tsx|ts|js|mjs|jsx)$/, use: Style9Plugin.loader }, // 這是正常的Webpack CSS提取的一部分{ test: /\.css$/i, use: [MiniCssExtractPlugin.loader, 'css-loader'] } ] }, plugins: [ // 這將對(duì)最終的CSS文件中的聲明進(jìn)行排序并刪除重復(fù)的聲明new Style9Plugin(), // 這是正常的Webpack CSS提取的一部分new MiniCssExtractPlugin() ] };</code>
Define styles
The syntax for creating styles is very similar to other libraries. We first call style9.create using a style object:
<code>import style9 from 'style9'; const styles = style9.create({ button: { padding: 0, color: 'rebeccapurple' }, padding: { padding: 12 }, icon: { width: 24, height: 24 } });</code>
Because all declarations will produce atomic classes, abbreviations like flex: 1 and background: blue will not work because they set multiple properties. Properties that can be expanded, such as padding, margin, overflow, etc., will automatically be converted into their full form. If you use TypeScript, you will receive an error when using unsupported properties.
Analytical styles
To generate the class name, we can now call the function returned by style9.create. It accepts the style key we want to use as parameters:
<code>const className = styles('button');</code>
The function works like this: the style on the right takes precedence and merges with the style on the left, just like Object.assign. The following will produce an element filled with 12px and the text is rebeccapurple.
<code>const className = styles('button', 'padding');</code>
We can apply styles conditionally using any of the following formats:
<code>// 邏輯與styles('button', hasPadding && 'padding'); // 三元運(yùn)算符styles('button', isGreen ? 'green' : 'red'); // 布爾對(duì)象styles({ button: true, green: isGreen, padding: hasPadding });</code>
These function calls will be removed during compilation and replaced with direct string concatenation. The first line in the above code will be replaced with something like 'c1r9f2e5 ' hasPadding ? 'cu2kwdz ' : ''. No runtime code is left.
Combination styles
We can extend the style object by accessing the style object with the property name and passing it to style9.
<code>const styles = style9.create({ blue: { color: 'blue; } }); const otherStyles = style9.create({ red: { color: 'red; } }); // 將為紅色const className = style9(styles.blue, otherStyles.red);</code>
Just like a function call, the style on the right takes precedence. However, in this case, the class name cannot be parsed statically. Instead, the property values ??will be replaced by the class and connected at runtime. The properties are added to the CSS file as before.
Summarize
The benefits of CSS-in-JS are real. That is, when we embed styles into our code, there is a performance cost. By extracting values ??at build time, we can achieve the best of both worlds at the same time. We can benefit from putting styles with tags together and using existing JavaScript infrastructure, while also generating the best stylesheets.
If style9 sounds fun, check out the repository and give it a try. If you have any questions, feel free to ask questions or contact us.
Acknowledgements
Thanks to Giuseppe Gurgone for his work on style-sheet and dss, Nicolas Gallagher for his work on react-native-web, Satyajit Sahoo and all members of Callstack for their work on linaria, Christopher Chedeau, Sebastian McKenzie, Frank Yan, Ashley Watkins, Naman Goel and everyone else working on stylex on Facebook for their willingness to share their lessons publicly. And any other people I missed.
Link
- johanholmerin/style9
- Build a new facebook.com with React, GraphQL and Relay – April 30, 2019
- Build a new Facebook with React and Relay | Frank Yan – October 30, 2019
- New Facebook.com's Tech Stack Rebuild – May 8, 2020
- johanholmerin/style9-components.macro: Styled Components API for style9 – Experimental
The above is the detailed content of style9: build-time CSS-in-JS. For more information, please follow other related articles on the PHP Chinese website!

Hot AI Tools

Undress AI Tool
Undress images for free

Undresser.AI Undress
AI-powered app for creating realistic nude photos

AI Clothes Remover
Online AI tool for removing clothes from photos.

Clothoff.io
AI clothes remover

Video Face Swap
Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Article

Hot Tools

Notepad++7.3.1
Easy-to-use and free code editor

SublimeText3 Chinese version
Chinese version, very easy to use

Zend Studio 13.0.1
Powerful PHP integrated development environment

Dreamweaver CS6
Visual web development tools

SublimeText3 Mac version
God-level code editing software (SublimeText3)

Hot Topics

There are three ways to selectively include CSS on a specific page: 1. Inline CSS, suitable for pages that are not frequently accessed or require unique styles; 2. Load external CSS files using JavaScript conditions, suitable for situations where flexibility is required; 3. Containment on the server side, suitable for scenarios using server-side languages. This approach can optimize website performance and maintainability, but requires balance of modularity and performance.

Flexboxisidealforone-dimensionallayouts,whileGridsuitstwo-dimensional,complexlayouts.UseFlexboxforaligningitemsinasingleaxisandGridforprecisecontroloverrowsandcolumnsinintricatedesigns.

The HTML popover attribute transforms elements into top-layer elements that can be opened and closed with a button or JavaScript. Popovers can be dismissed a number of ways, but there is no option to auto-close them. Preethi has a technique you can u

CSS blocks page rendering because browsers view inline and external CSS as key resources by default, especially with imported stylesheets, header large amounts of inline CSS, and unoptimized media query styles. 1. Extract critical CSS and embed it into HTML; 2. Delay loading non-critical CSS through JavaScript; 3. Use media attributes to optimize loading such as print styles; 4. Compress and merge CSS to reduce requests. It is recommended to use tools to extract key CSS, combine rel="preload" asynchronous loading, and use media delayed loading reasonably to avoid excessive splitting and complex script control.

In the following tutorial, I will show you how to create Lottie animations in Figma. We'll use two colorful designs to exmplify how you can animate in Figma, and then I'll show you how to go from Figma to Lottie animations. All you need is a free Fig

We put it to the test and it turns out Sass can replace JavaScript, at least when it comes to low-level logic and puzzle behavior. With nothing but maps, mixins, functions, and a whole lot of math, we managed to bring our Tangram puzzle to life, no J

ThebestapproachforCSSdependsontheproject'sspecificneeds.Forlargerprojects,externalCSSisbetterduetomaintainabilityandreusability;forsmallerprojectsorsingle-pageapplications,internalCSSmightbemoresuitable.It'scrucialtobalanceprojectsize,performanceneed

No,CSSdoesnothavetobeinlowercase.However,usinglowercaseisrecommendedfor:1)Consistencyandreadability,2)Avoidingerrorsinrelatedtechnologies,3)Potentialperformancebenefits,and4)Improvedcollaborationwithinteams.
