Facebook では、信頼性の高い高品質のサービスを世界中のユーザーに提供するために、数千人のエンジニアがさまざまな製品ラインに取り組んでいますが、コードの品質管理においても特有の課題に直面しています。膨大なコードベースに直面しているだけでなく、機能の多様性が増加しているため、特定のモジュールをリファクタリングして改善したい場合、他の多くのモジュールに影響を与えることがよくあります。特に CSS では、常に変化する何千もの CSS ファイルを処理する必要があります。以前は、コード レビュー、コード スタイル仕様、リファクタリングを通じてコードの品質を確保するために協力することに重点を置いていましたが、依然として多くのエラーが目に留まり、コード ベースに送信されていました。基本的なコードのエラーを検出し、一貫したコーディング スタイルを確保するために、独自に構築した CSS Linter を使用してきましたが、まだ多くの問題があるため、この記事でその方法についても説明したいと思います。 CSS のコード品質を保証します。
古い Linter は主に多くの正規表現に基づいて CSS の文法を抽出しました。おそらく次のようになります。 🎜>
preg_match_all( // This pattern matches [attr] selectors with no preceding selector. '/\/\*.*?\*\/|\{[^}]*\}|\s(\[[^\]]+\])/s', $data, $matches, PREG_SET_ORDER | PREG_OFFSET_CAPTURE); foreach ($matches as $match) { if (isset($match[1])) { raiseError(...); }
抽象構文ツリー
{ display: none: background-color: #8B1D3; padding: 10px,10px,0,0; opacity: 1.0f;}
JavaScript の Esprima や ESLint と同様に、Stylelint は完全な AST へのアクセスを提供し、現在の検出ルールなどのさまざまな状況に応じて特定のコード ノードにより迅速かつ簡単にアクセスできるようにします。次のように記述されます。
root.walkDecls(node => { if (node.prop === 'text-transform' && node.value === 'uppercase') { report({ ... }); }});
// 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({ ... }); } } });});
カスタム ルール: カスタム ルール
自動置換: 自動置換
我们老的Linter还有个问题就是没有单元测试,这点就好像代码上线前不进行单元测试一样不靠谱。我们面对的可能是任意格式的处理文本,因此我们也要保证我们的检测规则能够适用于真实有效的环境,这里我们是选择了Jest这个测试框架,Stylelint对它的支持挺好的,然后大概一个单元测试是这个样子:
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');
换一个靠谱的CSS Linter工具只是保证高质量的CSS的代码的第一步,我们还打算添加很多自定义的检测规则来捕获一些常见的错误,保证使用规定的最佳实践以及统一代码约定规范。我们已经在JavaScript的校验中进行了这一工作。
另外对于React社区中存在的CSS-in-JS这种写法,对于CSS Linter也是个不小的挑战,现在的大部分的Linter都是着眼于处理传统的CSS文件,以后会添加对于JSX的处理规范吧。