bitcalm.comサービスの開発中に、プロジェクトの自動アセンブリを整理する必要がありました。 私たちの目標は、アプリケーションのフロントエンド部分のパフォーマンスを改善し、サーバー上の開発プロセスと展開プロセスを最適化することでした。
解決すべき主なタスクは次のとおりです。
- スクリプトの結合と縮小
- スタイルの組み合わせと縮小
- PNG圧縮
- すべての画像からのスプライトの作成(便利な使用の可能性と、異なるPPIを持つデバイス用の2種類のスプライトのサポート)
- 開発用と本番用に異なるバージョンのhtmlドキュメントを作成する
最初の3つの点はささいなことなので、スプライトの処理とHTML処理に焦点を当てようとします。
最初の3つのポイントで使用されるプラグインについて簡単に説明します。 スクリプトを最適化するには、
grunt-contrib-concatと
grunt-contrib-uglifyが関係します。 スタイルの操作は
grunt-contrib-cssminを使用して行われます。 画像圧縮は
grunt-contrib-imageminのおかげです 。
grunt-contrib-concatを使用する際に言及すべきトリックは、言及する価値があります。 事実、ディレクトリ内のすべてのファイルを
srcパラメーター(
src:["/scripts/*.js"] )で指定するだけの場合、ファイルは必ずしも必要な順序で結合するとは限りません。 これは、ライブラリファイルがこのライブラリが使用されるファイルの後に続く場合によく発生します。 この場合の最も簡単で信頼性の高い方法は、スクリプトを手動で処理する順序を指定することです。
以下にその方法の例を示します。
dist: { src: [ '/scripts/lib/*.js', '/scripts/app/modules/*.js', '/scripts/app/*js' ], dest: '/dist/scripts.min.js' }
自動スプライト作成
スプライトを作成するには、
grunt-spritesmithプラグインを使用し
ます 。 彼は特定のフォルダからすべての画像を取得し、それらを1つのシートに接着し、結果のスプライト用のcssファイルを作成します。 このため、特定のCSSセレクターを使用してソース画像にアクセスできます(便宜上、 `
.icon- <source file name> 'が使用されます)。
小さな例:ソースファイルはrawフォルダーから取得されます。
├───img
│└───生
│├───img-1.png
│├───img-2.png
│└───img-3.png
タスクが完了すると、
spritesheet.pngスプライト自体と
spritestyles.cssスタイルファイル
自体の 2つのファイルが表示されます。
├───img
│├───生
││├───img-1.png
││├───img-2.png
││└───img-3.png
││
│└───spritesheet.png
│
├───スタイル
│└───spritestyles.css
spritestyles.cssファイルには、スプライトを使用するためのスタイルが含まれています。
.icon-img-1{ background-position: 0px 0px; width: 40px; height: 40px; } .icon-img-2{ background-position: -129px 0px; width: 95px; height: 80px; } .icon-img-3{ background-position: -42px 0px; width: 85px; height: 85px; }
さらに、このスプライトを使用するための一般的なスタイルは、このファイルの冒頭で説明されています。
.sprite { display: inline-block; background-image: url(../img/spritesheet.png); background-repeat: no-repeat; }
その結果、いくつかのクラスを使用して、レイアウト内の任意の画像を使用できます。
<span class=”sprite icon-img-1”></span>
大きなPPIを持つデバイス用のスプライトを作成する
ピクセル密度の高いデバイスで画像をきれいに表示するには、スプライトの拡大バージョンを作成する必要があります。 実際、すべての画面で大きなバージョンのスプライトのみを使用するのは簡単です。 ただし、大きなスプライトは通常の数倍「重い」ため、このアプローチは完全に正しいとは限りません。
したがって、さまざまなサイズのスプライトはどのように作成されますか:
img / rawフォルダーには通常のデバイスの画像が含まれ、
img / raw @ 2xフォルダーには同じ画像の拡大コピーが含まれます。 ピクセル比が2以上の画面の場合、別個の
spritesheet@2x.pngスプライトと
spritestyles@2x.cssスタイルファイルが
作成されます。 メディアクエリの使用により、ブラウザ自体が使用するスプライトを選択します。
spritestyles@2x.cssは次の
ようになります。
@media only screen and (-webkit-min-device-pixel-ratio: 2), only screen and (-moz-min-device-pixel-ratio: 2), only screen and (-o-min-device-pixel-ratio: 2/1), only screen and (min-device-pixel-ratio: 2), only screen and (min-resolution: 192dpi), only screen and (min-resolution: 2dppx) { .sprite { display: inline-block; background-image: url(../img/spritesheet@2x.png); background-repeat: no-repeat; } .icon-img-1 { ... } .icon-img-2 { ... } .icon-img-3 { ... } }
grunt-spritesmithプラグインが上記のすべてを実行できるようにするには、独自のMustacheテンプレートを作成するか、CSSを作成するJS関数を作成する必要がありました。 最初のソリューションを処理する時間も力もなかったため、いくつかの機能をすばやく記述し、「後で」テンプレートの作成を延期することにしました。
タスクコード sprite: { normal: { src: 'img/raw/*.png', destImg: 'img/spritesheet.png', destCSS: 'styles/spritestyles.css', padding: 2, cssTemplate: function (params) { var result = '.sprite {display: inline-block; background-image: url(../img/spritesheet.png); background-repeat: no-repeat;}'; for (var i = 0, ii = params.items.length; i < ii; i += 1) { result += '.icon-' + params.items[i].name + '{' + 'background-position: ' + params.items[i].px.offset_x + ' ' + params.items[i].px.offset_y + ';' + 'width: ' + params.items[i].px.width + ';' + 'height: ' + params.items[i].px.height + ';' + '}\n' } return result; } }, large: { src: 'img/raw@2x/*.png', destImg: 'img/spritesheet@2x.png', destCSS: 'styles/spritestyles@2x.css', padding: 4, cssTemplate: function (params) { var result = '.sprite {display: inline-block; background-image: url(../img/spritesheet@2x.png); background-repeat: no-repeat;}'; result += '@media only screen and (-webkit-min-device-pixel-ratio: 2), only screen and (-moz-min-device-pixel-ratio: 2), only screen and (-o-min-device-pixel-ratio: 2/1), only screen and (min-device-pixel-ratio: 2), only screen and (min-resolution: 192dpi), only screen and (min-resolution: 2dppx) {\n'; for (var i = 0, ii = params.items.length; i < ii; i += 1) { result += '.icon-' + params.items[i].name + '{' + 'background-position: ' + params.items[i].offset_x/2 + 'px ' + params.items[i].offset_y/2 + 'px;' + 'background-size: ' + params.items[i].total_width/2 + 'px ' + params.items[i].total_height/2 + 'px;' + 'width: ' + params.items[i].width/2 + 'px;' + 'height: ' + params.items[i].height/2 + 'px;' + '}\n' } result += '}'; return result; } } }
このタスクのコードからわかるように、大きなスプライトの作成は、メディアクエリを追加し、background-sizeプロパティを指定し、すべてのサイズを半分にすることのみが異なります。
このようなシステムをセットアップすることにより、組版中に画像を操作することで気が散ることはありません。 このメソッドをPhotoshopプラグイン
-Retinize Itと組み合わせて使用すると特に便利です。
さまざまなバージョンのHTMLドキュメントの構築
確かに、多くの人が多くのスタイルとスクリプトが開発用のhtmlファイルに接続されている状況に精通しており、本番環境ではそれらを縮小版に置き換える必要があります。 手動でファイルを変更したり、ホイールを再発明したりするのは疑わしい喜びであるため、Gruntに電話して支援を求めることにしました。
短い検索は
grunt-processhtmlにつながりました 。 このプラグインを使用する基本的な原則を考慮してください。
処理されたhtmlファイルはルートにあります。 このファイルから操作を実行する必要があります。これは、
distフォルダー内のhtml文書がそこから生成されるためです。
テンプレート
├───dist
│└───app.html
├───app.html
distフォルダー内の
app.htmlファイルをブラウザーにロードする必要があります。つまり、すべてのサーバールーティングは、ルート内の
app.htmlファイルではなく、それを指す必要が
あります。 gruntでこのタスクを設定するのはとても簡単です:
var templates = { cwd: 'templates/', src: ['*.html'], dest: 'templates/dist/', ext: '.html' }; ... processhtml: { dev: { files: [templates] }, dist: { files: [templates] } }
ソースファイルがあるフォルダーと、処理されたファイルを保存するフォルダーを指定するだけです。 また、タスク自体には、異なるバージョンのアセンブリに異なるファイルと設定を使用できる
devおよび
distコンテナーがあります。 これらのコンテナを使用して、条件付き構成がファイル内で処理されます。選択されたビルドモードに応じて、このコードまたはそのコードが削除されます。
<!DOCTYPE html> <html> <head> <title></title> <link rel="stylesheet" href="dist/styles.min.css" /> <link rel="stylesheet" href="styles/styles-1.css"/> <link rel="stylesheet" href="styles/styles-2.css"/> <link rel="stylesheet" href="styles/styles-3.css"/> </head> <body> <div></div> <script src="dist/scripts.min.js"></script> <script src="scripts/scripts-1.js"></script> <script src="scripts/scripts-2.js"></script> <script src="scripts/scripts-3.js"></script> </body> </html>
build:remove:devブロックの内容は開発中に削除され、
build:remove:distの内容は本番用のアセンブリ中に
削除されます。 開発を容易にするために、次のエイリアスを使用できます。
grunt.registerTask('dev', ['processhtml:dev']); grunt.registerTask('default', ['processhtml:dist', ...]);
さて、製品版を作成するには、コンソールで
gruntコマンドを実行するだけで十分であり、開発のために
grunt devを実行する必要があります。
この方法の主な欠点は、htmlファイルを変更した後、手動でgruntを実行して、最終ファイルを更新する必要があることです。 この問題の解決策は非常に簡単です:
grunt-contrib-watchを使用します。 このプラグインはファイルの変更を監視し、目的のタスクを起動します(この場合は
devです )。
watch: { html: { files: ['templates/*.html'], tasks: ['dev'] } }
おわりに
私は、既存のプロジェクトでGruntを使い始めるのがどれほど簡単で速いかを示しました。 このシステムは、サーバー上で更新プログラムを開発および展開するプロセスを加速し、サービスのフロントエンド部分を大幅に最適化しました。
これは、
bitcalm.comサーバーのクラウドバックアップサービスの作成方法に関するシリーズの3番目の記事です。
最初の記事:
独自のDjango課金システムの開発2番目の記事:
AngularJSとDjangoでアプリケーションフレームワークを作成した方法