Quality improvement and prospect of FACEBOOK:CSS

Source: Internet
Author: User
Tags postcss

With thousands of Facebook engineers collaborating with each other on this complex product line, code quality often poses unique challenges.

Not only do we need to deal with huge databases, we need to keep up with the pace of the Times-new features are on-line, improvements have been made, and even the need for product reorganization.

For CSS, this means that thousands of files are in a state of constant change.

Even though we've tried to ensure the quality of our CSS code through code reviews, style guides, and even refactoring, unintentional small errors can be a surprise to us.

Until recently, we used a self-developed CSS detector (CSS Linter) to get some basic errors to ensure the consistency of the Code style (diligent learning qkxue.net). Although it has reached our goal, what we need is a more powerful solution.

The regular is not enough.

The old CSS detectors are basically some regular expression search and replace rules. The correct parsing of CSS is not a simple issue, and the changes in vendor expansion and customization specifications are more challenging for accountants.

Here is an example of an old code:

Preg_match_all (
This rule matches a property selector without a predecessor selector.
'/\/\*.*?\*\/|\{[^}]*\}|\s (\[[^\]]+\])/s ',
$data,
$matches,, K
Preg_set_order | Preg_offset_capture);
foreach ($matches as $match) {
if (Isset ($match [1])) {
RaiseError (...);
}
Maintaining this mysterious matching rule maintenance is extremely uninteresting. And without saying it's hard to change and understand, performance is also a problem. For each rule, we have to go through the input over and over again, matching the different regular expressions.

# #抽象语法树

We decided that the new solution was based on a real, compliant CSS parser (mobile app development ty300.com). Since the code must work on this type of syntax effective parser, we can no longer use our entire CSS codebase as a huge text. This new approach will significantly improve CSS code quality typing errors, otherwise they will be overlooked, leading to incorrect view rendering or behavior silently.

What kind of behavior?

Some of the code lurking in the shadows of our huge codebase might be the following:

{
Display:none;
Background-color: #8B1D3;
padding:10px,10px,0,0;
opacity:1.0f;}
Can you find the subtle difference? Property name input error, incorrect hexadecimal, wrong delimiter--the browser ignores these, which is a far cry from the intentions of our developers.

It realizes that not long postcss will be a great job, a suitable tool, based on the standard CSS parser with an excellent modular architecture. We then chose Stylelint as our CSS detector. It is based on postcss, is very flexible, and has good support.
Similar to the JavaScript parser/filter-based Esprima and Eslint,postcss Stylelint gives you access to the entire AST (abstract syntax tree). The AST node can easily use any condition to access any node: Do we use the correct class name? Do we include the right abstraction? Are there extensions that are deprecated or unsupported? Do you have a localization problem?

In the following example, we will iterate through all the declarations and find all the first uppercase ("Text-transform:uppercase") fragments.

ROOT.WALKDECLS (node = {
if (Node.prop = = = ' Text-transform ' && node.value = = = ' uppercase ') {
Report ({...});
}});
We can even parse and deconstruct low-level functions such as linear-gradient. Here's a more complicated example: Find the Linear-gradient function and check its first parameter.

Disallow things like Linear-gradient (top, Blue, green) W Incorrect first valueroot.walkdecls (node =
Const Parsedvalue = Styleparser (Node.value);
Parsedvalue.walk (Valuenode = {
if (Valuenode.type = = = ' function ' && valuenode.value = = = ' Linear-gradient ') {
Const Firstvalueingradient = styleparser.stringify (Valuenode.nodes[0]);
if (Disallowedfirstvaluesingradient.indexof (firstvalueingradient) >-1) {
Report ({...});
}
}
});});
All of these CSS codes are easy to understand and update, regardless of how they are formatted, how rules, declarations, and how they are bound.

We can be very pleased to see that by using POSTCSS and Stylelint, when we deal with such as correcting typos, key frames,! Important, complex selectors, non-standard attributes, and any common and potential problems become handy.

# #自定义规则

We can customize our rules with a very handy internal plug-in mechanism (built-in plugin mechanism). Our existing plugins are as follows:

Slow-css-properties to warn against performance-sensitive properties like opacity or Box-shadow (just to be mindful of the M
Filters-with-svg-files to warn against filters not being supported on Edge when referencing SVG files
Use-variables to warn against values this could be replaced with existing constants (we use Customvar (...) abstraction)
Common-properties-whitelist to catch potentially nonexistent properties (i.e., typos)
Mobile-flexbox to catch Multi-value flex this ' s not supported in older mobile browsers
Text-transform-uppercase to warn against "text-transform:uppercase" (which are not internationalization-friendly)
We've developed a lot of rules and regulations for these stylelint plugins, trying to release them to a separate repository or a stylelint team of threads.

# #自动替换

A very important aspect of our static analysis process is automatic formatting. Linter supports patching, and if it does not, it asks if you need to replace it according to the rules. This can be a powerful and time-saving concept. The last thing you want to do when you commit is to see a detection error, and then go back and fix them, especially if the work is a very common task, such as a letter reordering rule. It is usually better to have an auto-formatted tool to complete its work to save development time.

Unfortunately, Stylelint does not have built-in auto-formatting (which can be said, Linter should not care about such a task), so we have to re-add and implement some existing stylelint rules to improve our infrastructure support. At the same time, we are developing a potential generic stylelint that can serve all users in the future.


Test everything.

One of the problems with our old CSS detector is that we don't have unit tests. This is a crucial thing because we need to parse any text. In using Stylelint to rewrite our detectors, we added testing every rule to make sure that rules can get the right things, ignore irrelevant things, and suggest appropriate alternatives.

We use a credible and easy-to-understand jest framework that is tested like this:

Test.ok (' div {background-image:linear-gradient (0deg, blue, green 40%, red);} ',
' Linear gradient with valid syntax '); Test.notok (' A {background:linear-gradient (top, blue, green);} ',
Message
' Linear-gradient with invalid syntax ');
What's next?

This high-quality CSS rewrite is just the first step. There are many useful rules we plan to add (built-in and custom)-all of which are designed to catch common mistakes, execute best practices, and control code style conventions. We have used JavaScript (via Eslint) so there is no reason why we should not use it to handle CSS.

The current detector has been integrated with phabricator and has become our Code collaboration tool, with all the warnings/suggestions being revised.

This makes the CSS detector a very big step forward in the workflow.

Another great benefit of having a suitable CSS parser is that it collects accurate statistics about the code base. What are the most recently used properties/values? Perhaps they should be removed or replaced (sending fewer bytes by wire). What is the most popular color/font size/hierarchy? Perhaps they should be abstracted into reusable components or variables. What is the "heaviest" selector? There may be a performance issue here, and so on.

All of these can help it improve performance and maintenance.

About react and inline styles?

It is worth mentioning that the concept of CSS-IN-JS is becoming popular in the react community. Now, the case of a CSS detector is largely a matter of a trivial CSS file detector. It is currently designed to parse the traditional CSS files, and may gradually adapt to parsing in JS defined as CSS code snippets. However, it should be fairly straightforward to handle these by Postcss's JS API.

While we are actively exploring CSS-IN-JS's approach to Facebook, which is still in its early stages of experimentation, we still have a lot of CSS code base maintenance.

Working together

We are happy to use open source tools and get as much feedback as possible. Sincerely hope that it can provide a solid modern rules and guidelines for everyone to use and cooperate with each other.

Thanks to JS Infra and Webspeed team, and any one of the help rewriting friends, Stylelint David Clark and Richard Hallows. And the whole community that makes postcss such a magical tool possible.

This is a result of sincere cooperation and concerted efforts.

Quality improvement and prospect of FACEBOOK:CSS

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.