SPAアプリケーションの量を減らす別の方法(webpack)

つい最近、私は新しいツールを学ぶ必要がありました。 別のそのようなツールはwebpackでした 。 このツールは興味深いものですが、Google Closure *から移行した後、 webpackがGoogle Closure Stylesheetsのようにクラス名を絞り込まない理由が謎になりました。 1日、ひざの上で、この機能を非常にうまく実装するプラグインを書きました。 以下の詳細な説明。



それでは、TKから始めましょう。 これは、まず自分のために、そして次に、それが起こっていることをまだ理解していないが、どういうわけかこのページに載っている人のために行われます。 個人的に、私は大きくて美しい長いクラス名を書くのが好きです。



例:



.header { position: fixed; top: 0; ... } .header a { display: block; float: right; ... } .sidebar { float:right; max-width: 30%; ... } .sidebar a { font-size: 16px; .... }
      
      





ただし、 ヘッダーhに、 サイドバーsに減らすことができるため、CSSだけでなくJSファイルでも多くのバイトを節約できます。 ほとんどの場合、JSにはクラス名によるセレクターが含まれます。



ただし、コードの可読性はこのような低下に悩まされ、その結果、開発速度が低下します。 したがって、この置換用のツールを自動的に作成する必要があります。



これがクロージャーでどのように機能するかの簡単な説明



Google Closureはいくつかのツールで構成され、そのうちの1つはGoogle Closure Stylesheetsです。これは、スタイルシートのプリプロセッサとポストプロセッサの両方です。



プリプロセッサとして、それはそのすべての兄弟に似ていますが、すべてのほとんどはSCSS / SASSに似ています。

ポストプロセッサとして、置換辞書を作成してクラス名を解析し、すべてのクラス名を短い表記に置き換えます。



たとえば、上記のコードは次のようになります。



 .a { position: fixed; top: 0; ... } .aa { display: block; float: right; ... } .b { float:right; max-width: 30%; ... } .ba { font-size: 16px; .... }
      
      





代替の辞書は次のとおりです。



 { "header": "a", "sidebar": "b" }
      
      





実際、はるかに多くの機能がありますが、この記事はそれについてではありません。 また、優れたテンプレートエンジンであるClosure Templatesもあります。このテンプレートエンジンでは、すべてのクラス名を特別なディレクティブでマークする必要があり、その後、テンプレートに置換辞書が適用されます。



例:



 {namespace test} /** * Test template * */ {template .test} <div class="{css header}">Header<a href="#">Home</a><a href="#">About</a><header> ... <div class="{css sidebar}">Sidebar<header>
      
      





また、すべてのCSSクラスの名前を「洗練」する必要があるJSがあることを忘れないでください。



 var header = goog.dom.getElementByClass(goog.getCssName('header')); var sidebar = goog.dom.getElementByClass(goog.getCssName('sidebar'));
      
      





そして、すべてのソースを修正し、それらを置換辞書とともにコンパイルに送信する場合にのみ、すべてが機能します。



この方法の主な欠点は、辞書がCSSでコンパイルされていることです。 JSからDOM要素を選択するためだけに使用されるクラスがある場合、辞書に入らない可能性があります(または、この記事がClosure Toolsのレビューではないことを予約します)。



プラグインに戻る



散乱関数はどこにでもあり、あまり便利ではないように思えたので、マスク___ <%className%> __でクラス名を設定することにしました。



したがって、スタイルが思い浮かびます:



 .___header__ { position: fixed; top: 0; ... } .___header__ a { display: block; float: right; ... } .___sidebar__ { float:right; max-width: 30%; ... } .___sidebar__ a { font-size: 16px; .... }
      
      





そして、jQueryを例として使用して、JSでDOMを操作します。



  var header = $('.___header__'); var sidebar = $('.___sidebar__');
      
      





たとえば、React:



 function Header(props) { return ( <div className="___header__"> {props.children} </div> ); }
      
      





たとえば、バックボーン:



 module.exports = Backbone.View.extend({ tagName: 'div', className: '___header__' });
      
      







UPD:

角度の場合、 は太いです。



次のような構造の予約をすぐに行います。



 var genClassName = function(v) { return '___' + v + '__'; } module.exports = Backbone.View.extend({ tagName: 'div', className: genClassName('header') });
      
      





動作しません。 スタイルと同様に:



 [class*="bold"] { font-weight:bolder; }
      
      





最初のステップ



パッケージをインストールすることにより:



 npm install --save cssrename-webpack-plugin
      
      





そして、 webpack.config.jsに少し手を加えて



 const CssRenameWebpackPlugin = require('cssrename-webpack-plugin'); ... module.exports = { ... plugins: [ CssRenameWebpackPluginConfig, ... ] };
      
      





アセンブリプロセス中に、次の行が表示されます。



利益:355



これは、保存されたバイト数を報告します。



不快感と解決策



しかし、JSの動物の多様な世界に1つのパーサーでカバーできない膨大な数のライブラリがある場合、この問題のCSSははるかに人道的であり、解析するのがはるかに簡単です(CSS)。



最も単純な形式では、1つの正規表現になります。 したがって、少なくともCSSにアンダースコアを追加しないようにする同様のローダーを追加してみてください。



 npm install --save cssrename-loader
      
      





次の突然変異webpack.config.js



 module.exports = { module: { loaders: [ { test: /\.css$/, loader: "style-loader!css-loader!cssrename-loader" } ] } };
      
      





テストプロジェクトで何が起こったのか



更新:



これについては書きたくありませんでしたが、明らかに追加する必要があります。 さらに、スタイルのみが考慮されるため、JSとテンプレートでの賞金は数えられないほど簡単です。 Google Closure Stylesheetsの場合:

サイト/ファイル 元のボリューム/ zip 受信したボリューム/ zip 貯蓄率(zip)
acss.io bundle.488facb7.css 13.8KB / 4.4KB 13.3KB / 4.0KB ≈9%
getbem.com/introduction getbem.com.1.0.0.css 13.3KB / 3.3KB 12KB / 3.1KB ≈6%
ブートストラップ 121.2KB / 18.7KB 96.9KB / 16.7KB ≈10%
habrahabr.ru global_main.css 212.3KB / 30.6KB 155.2KB / 26.9KB ≈13%


証明



Google Closure Stylesheetsに適合しなかったもの:



Atomicの場合、正規表現を2つ置き換える必要がありました。



 \\\(((?:(?!\\\)).)*?)\\\) => --$1-- \\. => --
      
      





BEMで「クロールしませんでした」:



 @supports (display: -moz-box) { [class*=LineClamp] { display: block } } @-webkit-keyframes bounce { 0% { -webkit-transform: translateY(-100%); transform: translateY(-100%); -webkit-filter: blur(5px); filter: blur(5px) } 100%, 40% { -webkit-transform: translateY(0); transform: translateY(0) } 60% { -webkit-transform: translateY(-10%); transform: translateY(-10%) } } @keyframes bounce { 0% { -webkit-transform: translateY(-100%); transform: translateY(-100%); -webkit-filter: blur(5px); filter: blur(5px) } 100%, 40% { -webkit-transform: translateY(0); transform: translateY(0) } 60% { -webkit-transform: translateY(-10%); transform: translateY(-10%) } }
      
      





ブートストラップから「クロールしませんでした」:



 border-top: 4px solid \9; @media all and (transform-3d),(-webkit-transform-3d) @-ms-viewport { width: device-width }
      
      





Habrから「クロールしませんでした」:



 @charset "UTF-8"; @-moz-document url-prefix() { .search-field__select { text-indent: .01px; text-overflow: '' } }
      
      






All Articles