素敵なビルドフロントエンドプロジェクト

この記事では、日常業務に根付いており、日常業務を大幅に促進したフロントエンドプロジェクトの組み立てプロセスを詳細に分析します。



この記事は究極の真実であるとは主張していません。なぜなら、今日では多くの異なるアセンブラーとアセンブリーへのアプローチがあり、誰もが味を選ぶからです。 このトピックに関する私の考えを共有し、ワークフローを示します。



UPD(2015年3月13日):いくつかのプラグインをより関連性の高いプラグインに置き換え、CSSSファイルをSCSS内にインポートする際の問題を解決しました





Gulpコレクターを使用します。 したがって、ノードjsをシステムにインストールする必要があります。 特定のプラットフォームにノードをインストールすることは考慮しません。 それは数分でグーグルです。

そもそも、質問に答える-なぜGulpなのか?



多かれ少なかれ許容できる選択肢のうち、 GruntBrunchがあります。



アセンブラーに参加し始めたばかりの頃、GruntとGulpはすでに市場に出ていました。 最初のものは以前に登場したため、より大きなコミュニティとさまざまなプラグインがあります。 npmによると:

Grunt-11171パッケージ

Gulp-4371パック



しかし、Gruntは少し冗長に見えました。 そして、いくつかの比較記事を読んだ後、そのシンプルさと明快さからGulpを好みました。



ブランチは比較的新しいプロジェクトであり、すべての賛否両論はこの結果です。 私は彼を興味を持って見ていますが、私の仕事ではまだ使っていません。



続行:


プロジェクト用のフォルダー(たとえば、「habr」)を作成します。 コンソールで開き、コマンドを実行します。



npm init
      
      





インストーラーのすべての質問でEnterキーを押すだけです。 今では問題ではありません。

その結果、プロジェクトのあるフォルダーで、次のようなpackage.jsonファイルを生成します。



 { "name": "habr", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1" }, "author": "", "license": "ISC" }
      
      





ニーズに合わせて少し変更します。



 { "name": "habr", "version": "1.0.0", "description": "", "author": "", "license": "ISC", "dependencies": { "gulp": "^3.8.11" } }
      
      





依存関係ブロックで、gulpが必要であることを示し、すべてのプラグインをすぐに登録します。



プラグイン


gulp-autoprefixer-ベンダープレフィックスをCSSプロパティに自動的に追加します(数年前は、このようなツールのために殺していました)

gulp-minify-css -CSSコードの圧縮に必要

browser- sync-このプラグインを使用すると、ブラックジャックとライブリロードを使用してローカル開発サーバーを簡単にデプロイできます。また、ローカルホストへのトンネルを作成できます。

gulp-imagemin-画像の圧縮用

imagemin-pngquant -PNGを操作するための以前のプラグインへの追加

gulp-uglify -JSを圧縮します

gulp-sass -SCSSコードをコンパイルします

ホリバーラのためではない
私は仕事でLESSを非常に長い間使用しました。 このプリプロセッサのスピードと学習のしやすさには非常に感銘を受けました。 ロストフのハッカソンでも報告しました。 特にこのレポートでは、SASSについてあまりお世辞を言いませんでした。

しかし、時間が経つにつれて、私は年を取り、賢くなりました:)そして今、私はこのプリプロセッサに加わりました。

SASSに対する私の不満の基礎は、私がこすらないでいるということでした。 そして、SASS / SCSSコードをコンパイルする必要があったとき-必要なバンドルを使用してプロジェクトをドラッグする必要がありました-それは本当に私を混乱させました。

しかし、それはすべてLibSassのようなものの出現によって変わりました。 これは、SASSのC / C ++コンパイラポートです。 gulp-sassプラグインはそれを使用します。 これで、ネイティブノード環境でSASSを使用できるようになり、非常に満足しています。



gulp-sourcemaps -css sourscemapsを生成して生成します。これはコードのデバッグに役立ちます

gulp-riggerは単なる機能キラーです。 プラグインを使用すると、シンプルなデザインで1つのファイルを別のファイルにインポートできます。

 //= footer.html
      
      





コンパイル時のこの行は、footer.htmlファイルの内容に置き換えられます

gulp-watch-ファイルの変更を監視するために必要になります。 Gulpにはウォッチが組み込まれていることは知っていますが、特に問題がありました。特に、新しく作成されたファイルが表示されず、再起動する必要がありました。 このプラグインは問題を解決しました(これはgulpの将来のバージョンで修正されることを望みます)。

rimraf -rm -rf for node



すべてのプラグインをインストールし、出力で次のpackage.jsonを取得します。



 { "name": "habr", "version": "1.0.0", "description": "", "author": "", "license": "ISC", "dependencies": { "browser-sync": "^2.2.3", "gulp": "^3.8.11", "gulp-autoprefixer": "^2.1.0", "gulp-imagemin": "^2.2.1", "gulp-minify-css": "^1.0.0", "gulp-rigger": "^0.5.8", "gulp-sass": "^1.3.3", "gulp-sourcemaps": "^1.5.0", "gulp-uglify": "^1.1.0", "gulp-watch": "^4.1.1", "imagemin-pngquant": "^4.0.0", "rimraf": "^2.3.1" } }
      
      







バウアー


Bowerパッケージマネージャーがなければ私の仕事を想像することはできません。 そうでない場合は、それが何であり、 ここで何が食べられるかについて読んでください

プロジェクトに追加しましょう。 これを行うには、コンソールでコマンドを実行します。



 bower init
      
      





すべての質問を入力することもできます。

最後に、このbower.jsonファイルのようなものを取得します。



 { "name": "habr", "version": "0.0.0", "authors": [ "Insayt <insait.rostov@ya.ru>" ], "license": "MIT", "ignore": [ "**/.*", "node_modules", "bower_components", "test", "tests" ] }
      
      





そして、必要な状態に変更します。



 { "name": "habr", "version": "0.0.0", "authors": [ "Insayt <insait.rostov@ya.ru>" ], "license": "MIT", "ignore": [ "**/.*", "node_modules", "bower_components", "test", "tests" ], "dependencies": { "normalize.css": "*", "jquery": "2.*" } }
      
      





依存関係ブロックでは、プロジェクトの依存関係を示します。 さて、テストのためだけにノーマライズとjQueryを行います(これらを使用せずにプロジェクトをいつ開始したか覚えていません)。

そしてもちろん、次のコマンドでインストールします:



 bower i
      
      





さて、今最も興味深い。 プロジェクトの構造を作成し、コレクターを構成します。



プロジェクト構造:



これは非常に物議を醸す瞬間です。 もちろん、プロジェクトと開発者の好みは異なります。 yeoman.ioの Webサイトを見るだけです(ちなみに、これはあらゆる種類の機能を備えたプロジェクト用の多数の準備されたフレームワークを提供する非常にクールなツールです。 ぜひご覧ください。 何も発明せず、最も単純な構造を作成します。



まず、2つのフォルダーが必要です。 1つ(src)で実際にコードを記述し、2つ目(build)でコレクターが完成したファイルを吐き出します。 それらをプロジェクトに追加します。 現在の構造は次のようになります。







srcフォルダーに、平均的なプロジェクトの典型的な構造を作成します。 js /およびstyle /フォルダーにメインファイルを作成し、そのようなコンテンツを含む最初のhtmlページを作成しましょう。



index.html

 <!DOCTYPE html> <html> <head lang="ru"> <meta charset="UTF-8"> <title>     </title> </head> <body> <section class="header"> Header </section> <section class="content"> Content </section> <section class="footer"> Footer </section> </body> </html>
      
      





srcフォルダー構造は次のようになります。







ここではすべてが簡単です。

フォント-フォント

img-写真

js-スクリプト。 このフォルダーのルートにあるのはmain.jsファイルのみで、これはアセンブリに役立ちます。 すべてのjsファイル-パーシャルフォルダーに配置する必要があります

スタイル-スタイル。 また、ルートにはmain.scssのみがあり、partialsフォルダーには作業ファイルがあります。

テンプレート-ここでは、繰り返しのHTMLコードを保存します

タイプセットするすべてのhtmlページは、src /のルートにあります。

最初のjsファイルとscssファイルをパーシャルに追加し、最後に-プロジェクトのルートに移動して、gulpfile.jsファイルを作成します。 プロジェクトフォルダー全体は次のようになります。







これでコレクターを設定する準備がすべて整いましたので、ロックしましょう!



Gulpfile.js


すべての魔法はこのファイルに含まれます。 まず、すべてのプラグインをインポートして、gulp自体をインポートします



gulpfile.js

 'use strict'; var gulp = require('gulp'), watch = require('gulp-watch'), prefixer = require('gulp-autoprefixer'), uglify = require('gulp-uglify'), sass = require('gulp-sass'), sourcemaps = require('gulp-sourcemaps'), rigger = require('gulp-rigger'), cssmin = require('gulp-minify-css'), imagemin = require('gulp-imagemin'), pngquant = require('imagemin-pngquant'), rimraf = require('rimraf'), browserSync = require("browser-sync"), reload = browserSync.reload;
      
      





もちろん、そうする必要はありません。 gulp-load-pluginsプラグインを使用すると、requireからこのヌードルをすべて作成する必要がなくなります。 しかし、何がどこに接続されているかを明確に確認し、必要に応じてオフにできます。 このために、私は昔ながらの方法で書きます。



また、必要なすべてのパスを書き込むjsオブジェクトを作成します。これにより、必要に応じて1か所で簡単に編集できます。



 var path = { build: { //         html: 'build/', js: 'build/js/', css: 'build/css/', img: 'build/img/', fonts: 'build/fonts/' }, src: { //    html: 'src/*.html', // src/*.html  gulp         .html js: 'src/js/main.js',//       main  style: 'src/style/main.scss', img: 'src/img/**/*.*', // img/**/*.*  -            fonts: 'src/fonts/**/*.*' }, watch: { //  ,        html: 'src/**/*.html', js: 'src/js/**/*.js', style: 'src/style/**/*.scss', img: 'src/img/**/*.*', fonts: 'src/fonts/**/*.*' }, clean: './build' };
      
      







開発サーバーの設定で変数を作成します。



 var config = { server: { baseDir: "./build" }, tunnel: true, host: 'localhost', port: 9000, logPrefix: "Frontend_Devil" };
      
      







HTMLをまとめる


HTMLアセンブリのタスクを作成しましょう。



 gulp.task('html:build', function () { gulp.src(path.src.html) //     .pipe(rigger()) //  rigger .pipe(gulp.dest(path.build.html)) //    build .pipe(reload({stream: true})); //      });
      
      





リガーは、この設計を使用してファイルをインポートできるプラグインです。



 //= template/footer.html
      
      





実際に使用してみましょう!

src / template / folderに、次の内容のheader.htmlおよびfooter.htmlファイルを作成します



header.html

 <section class="header"> Header </section>
      
      







footer.html

 <section class="header"> Footer </section>
      
      







index.htmlファイルを次のように変更します。

 <!DOCTYPE html> <html> <head lang="ru"> <meta charset="UTF-8"> <title>     </title> </head> <body> //= template/header.html <section class="content"> Content </section> //= template/footer.html </body> </html>
      
      







コンソールに移動し、次のコマンドを使用してタスクを実行します。



 gulp html:build
      
      





動作した後、buildフォルダーに移動して、そこにあるindex.htmlファイルを確認します。



 <!DOCTYPE html> <html> <head lang="ru"> <meta charset="UTF-8"> <title>     </title> </head> <body> <section class="header"> Header </section> <section class="content"> Content </section> <section class="footer"> Footer </section> </body> </html>
      
      





すごい!



レイアウトされたすべてのページに目を通し、それらのページで繰り返される一部に変更を加えるのはどれほど多くの不便さを覚えていました。 現在、これは1か所で便利に行われています。



JavaScriptをビルドする


スクリプトアセンブリタスクは次のようになります。



 gulp.task('js:build', function () { gulp.src(path.src.js) //  main  .pipe(rigger()) //  rigger .pipe(sourcemaps.init()) // sourcemap .pipe(uglify()) //  js .pipe(sourcemaps.write()) //  .pipe(gulp.dest(path.build.js)) //    build .pipe(reload({stream: true})); //   });
      
      





main.jsファイルを覚えていますか?

ここでの全体的なアイデアは、リガーを使用して、必要なすべてのjsファイルを必要な順序で含めることです。 接続順序を制御するためです-すべての* .jsファイルを見つけてそれらを接着するようにgulpに依頼するのではなく、この方法で行います。



多くの場合、エラーの場所を検索するとき、問題の場所を特定するために、アセンブリからいくつかのファイルを順番にオフにします。 すべての.jsを不注意に接着すると、デバッグが複雑になります。



main.jsに入力します。



 /* * Third party */ //= ../../bower_components/jquery/dist/jquery.js /* * Custom */ //= partials/app.js
      
      





これはまさに私が戦闘プロジェクトで行うことです。 このファイルの一番上は常に依存関係の接続であり、自分のスクリプトの接続の下にあります。



ちなみに、bowerパッケージはgulp-bowerなどのプラグインを介して接続できます。 しかし、繰り返しますが、何を、どこで、どのように接続するかを独立して決定したいので、私はこれを行いません。



次のコマンドを使用して、コンソールからタスクを起動するだけです。



 gulp js:build
      
      





そして、build / jsフォルダーに、コンパイルおよび圧縮されたファイルが表示されます。



スタイルを収集します



SCSSを構築するタスクを作成しましょう。



 gulp.task('style:build', function () { gulp.src(path.src.style) //  main.scss .pipe(sourcemaps.init()) //      js .pipe(sass()) // .pipe(prefixer()) //   .pipe(cssmin()) // .pipe(sourcemaps.write()) .pipe(gulp.dest(path.build.css)) //  build .pipe(reload({stream: true})); });
      
      





ここではすべてが簡単ですが、自動修正の設定に興味があるかもしれません。 デフォルトでは、ブラウザの最後の2つのバージョンに必要なプレフィックスを書き込みます。 私の場合、これで十分ですが、他の設定が必要な場合は、 ここで見つけることができます。



スタイルについては、jsと同じですが、リガーの代わりに、SCSSに組み込まれたインポートを使用します。

UPD(2015年3月13日):一部の人々は、CSSファイルをインラインでインポートする際に問題を抱えています。 判明したように、gulp-sassはこれを行う方法を知らず、出力は単純なCSSインポートを提供します。 しかし、gulp-minify-cssプラグインはこの問題を解決し、CSSインポートをファイルのコンテンツに置き換えます。

main.scssは次のようになります。

 /* * Third Party */ @import "../../bower_components/normalize.css/normalize.css"; /* * Custom */ @import "partials/app";
      
      





これにより、スタイルの接続方法を簡単に制御できます。

実行してタスクを確認しましょう
 gulp style:build
      
      







写真を集める



写真のタスクは次のようになります。



 gulp.task('image:build', function () { gulp.src(path.src.img) //   .pipe(imagemin({ //  progressive: true, svgoPlugins: [{removeViewBox: false}], use: [pngquant()], interlaced: true })) .pipe(gulp.dest(path.build.img)) //   build .pipe(reload({stream: true})); });
      
      





インターレースを除き、デフォルトのimagemin設定を使用します。 このプラグインのAPIの詳細については、 こちらをご覧ください



さて、src / imgに画像を入れてコマンドを実行すると:



 gulp image:build
      
      





最適化されたイメージがビルドで表示されます。 また、gulpはコンソールに、サイトのユーザー用にどれだけのスペースを節約したかを親切に書き込みます。



フォント



通常、フォントを操作する必要はありませんが、「src /で作業し、build /で組み立てる」というパラダイムを破壊しないように、src / fontsからファイルをコピーし、build / fontsに貼り付けます。 タスクは次のとおりです。



 gulp.task('fonts:build', function() { gulp.src(path.src.fonts) .pipe(gulp.dest(path.build.fonts)) });
      
      







ここで、「build」というタスクを定義しましょう。これは、あなたと私がここにアップロードしたすべてを実行します。



 gulp.task('build', [ 'html:build', 'js:build', 'style:build', 'fonts:build', 'image:build' ]);
      
      







ファイルの変更



常にコンソールに登らないように、ファイルを変更するたびに必要なタスクを実行するようにgulpに依頼しましょう。 これを行うために、彼はそのようなタスクを書きます:



 gulp.task('watch', function(){ watch([path.watch.html], function(event, cb) { gulp.start('html:build'); }); watch([path.watch.style], function(event, cb) { gulp.start('style:build'); }); watch([path.watch.js], function(event, cb) { gulp.start('js:build'); }); watch([path.watch.img], function(event, cb) { gulp.start('image:build'); }); watch([path.watch.fonts], function(event, cb) { gulp.start('fonts:build'); }); });
      
      





理解すれば問題はないはずです。 パス変数で定義されたパスに沿って移動し、ファイルが変更されたときに呼び出される関数で、必要なタスクを実行するように求めます。



コンソールで実行してみてください:



 gulp watch
      
      





そして、異なるファイルを交換します。

まあ、クールじゃないですか?



Webサーバー



livereloadの奇跡を楽しむには、自分用のローカルWebサーバーを作成する必要があります。 これを行うには、次の簡単なタスクを記述します。



 gulp.task('webserver', function () { browserSync(config); });
      
      





コメントすることすらありません。 configオブジェクトで定義した設定でlivereloadサーバーを起動するだけです。 さらに、gulpはプロジェクトをブラウザーで丁寧に開き、コンソールでローカルサーバーとトンネルへのリンクを書き込みます。このリンクは、デモのためにお客様にドロップできます。



クリーニング



画像を追加する場合、image:buildタスクを実行してから画像を削除します-画像はbuildフォルダーに残ります。 そのため、定期的にクリーニングすると便利です。 このための簡単なタスクを作成しましょう。



 gulp.task('clean', function (cb) { rimraf(path.clean, cb); });
      
      





コマンドを実行すると

 gulp clean
      
      





ビルドフォルダーのみが削除されます。



最終和音



最後に、アセンブリ全体を実行するデフォルトタスクを決定します。



 gulp.task('default', ['build', 'webserver', 'watch']);
      
      







最後に、gulpfile.jsは次のようになります。

コンソールで実行します

 gulp
      
      





そして出来上がり。 プロジェクトの準備が整い、あなたを待っています。



結論にいくつかの言葉



この記事は、フロントエンドプロジェクトのアセンブルの微妙さをもう一度刷新し、この経験を新しい開発者に簡単に移転する方法として考案されました。 プロジェクトでこのようなアセンブリオプションを使用する必要はありません。 ほとんどすべてのニーズに合ったジェネレーターが見つかるyeoman.ioがあります。

このコレクターを作成した理由は3つあります。

-HTMLコードでリガーを使用したい

-出会ったほとんどすべてのアセンブリでは、アセンブリの中間結果を記録するために一時フォルダー(通常は.tmp /)が使用されます。 私はこのアプローチが好きではないので、一時フォルダーを削除したかったのです。

「そして、これらすべてが私の箱から出ることを願っています。」



コレクターの作業バージョンをgithubからダウンロードできます。



この記事がお役に立てば幸いです。



PSすべてのエラー、短所、および妨害について-個人的に書いてください。



All Articles