Master PG

プログラムし続ける...

【Polymer Starter Kit】プロジェクトのビルドを行う (開発環境構築まとめ)


目次


概要

ここまで以下の記事で開発環境の構築について説明してきました:

本記事ではこれらを全て統合し、最後にプロジェクトのビルドを行います。本ページで使用するプロジェクトはgithubにアップしてあります。ここからリポジトリを自身の環境へクローンしてください。

クローンを作成したら次のフォルダへ移動します:

cd /【任意のフォルダ】/polymer-starter-kits/projects/master


統合された開発環境を確認してみる


Starter Kitを起動する

プロジェクトルートに移動して、次の2つのコマンドを実行して必要なライブラリをローカルインストールします:

npm install
bower update

次のコマンドでStarter Kitを起動します:

gulp serve


起動したら、次のURLでStarter Kitのサイトが表示されることを確認してください:

  • http://localhost:5000
  • http://192.168.1.51:5000 (自身のマシンのアドレス)


動作確認

これまで個別の記事で説明してきた開発環境の設定を、本Starter Kitで1つにまとめました。「gulpfile.js」を見てみましょう:

【gulpfile.js】

/**
 * Browsersyncを起動します。
 */
gulp.task('serve', ['serve:mock', 'app', 'src', 'styles', 'sass', 'images'], function () {
  ...

  // 変更を監視するファイルを指定
  gulp.watch(['index.html'], ['app', reload]);
  gulp.watch(['src/**/{*.css,*.html,*.js}'], ['src', reload]);
  gulp.watch(['styles/**/{*.css,*.html}'], ['styles', reload]);
  gulp.watch(['{styles,src}/**/*.scss'], ['sass', reload]);
});

Browsersyncを起動する前 (serveタスクを実行する前) に、['serve:mock', 'app', 'src', 'styles', 'sass', 'images']配列で指定されたタスクを実行します。これによりStarter Kitが起動すると、プロジェクトルートの直下に「.tmp」フォルダが作成され、この配下に次のようなファイルが生成されます:

  • ベンダープレフィックスが付加されたcss, htmlファイル
  • 圧縮された画像ファイル

また、ファイルの変更監視の設定によって、変更を感知すると自動でファイルがコンパイルされ、「.tmp」フォルダ配下へファイル出力されます。その後、ブラウザが自動でリロードされます。

html, css, scss, js などのファイルを変更して、自動でコンパイルされること、またリロードされることを確認してみてください (jsはコンパイルは無くリロードのみ) 。

Note: ファイルを変更してもブラウザが自動でリロードされない場合は「Browsersyncの自動リロード機能の不具合」を参照ください。


ProxyするWEBサーバーを変更する

Note: Proxyについての詳細は「BrowsersyncでWEBサーバー環境を整える」を参照ください。

本Starter Kitのデフォルトでは、ProxyするWEBサーバーはAPIリクエストを検証するための「easymock」になっています。Starter Kitを動作確認する場合はこのままで構いませんが、実際の開発ではProxyするWEBサーバーを、本来アクセスすべきWEBサーバーに変更する必要があります。ここではその変更箇所を示します:

【gulpfile.js】

/**
 * Browsersyncを起動します。
 */
// 配列に指定されている'serve:mock'を削除する
// ↓ 
gulp.task('serve', ['serve:mock', 'app', 'src', 'styles', 'sass', 'images'], function () {
  // Browsersyncの設定
  browserSync({
    ...
    proxy: {
      // 本来アクセスすべきWEBサーバーを指定する
      // ↓
      target: 'localhost:5050',

まず、serveタスクの事前タスクに指定されている'serve:mock'を削除してください。

次に、proxytargetはデフォルトでeasymockのWEBサーバーが指定されています。ここを本来アクセスすべきWEBサーバーに書き換えてください。


Sassを使用する

本Starter Kitのデフォルトでは、Sassファイルを自動コンパイルするようになっていません。Sassを使用するにはインストールが必要なので、事前にインストール作業を行っておいてください (「Sassの環境を整える - Sassのインストール」を参照) 。

Sassファイルを自動コンパイルさせるには、USE_OF_SASStrueを設定してください:

【gulpfile.js】

/**
 * Sass使用の有無
 */
var USE_OF_SASS = true;

あとは「styles, src」フォルダ配下にscssファイルを配置し、Starter Kitを起動すれば、自動でscssファイルがコンパイルされるようになります。

Note: Compassを使用したい方は「Sassの環境を整える」を参照ください。


プロジェクトのビルドタスクを見てみる

ここではプロジェクトのビルドを行うタスクについて説明します。次はプロジェクトビルド本体のタスクです:

【gulpfile.js】

/**
 * プロジェクトのビルドを行います。
 */
gulp.task('build', ['clean:build'], function (cb) {
  // ビルドフラグをONにする
  _isBuild = true;
  // ビルド実行
  runSequence(
    ['app', 'src', 'styles', 'sass', 'images'],
    'copy-to-dist', 'set-base-path', 'polybuild',
    'rename-index', 'clean-dist',
    cb);
});

まずclean:buildタスクで、プロジェクトの環境をキレイにしてからビルドを開始します。

runSequence()は、タスクを順番に実行することができるプラグインです。配列に指定されたタスクは並列に実行されるので、パフォーマンス向上を図る意図があります。ただし「前のタスクが終わってからでないと実行できないタスク」も存在します。配列で囲われていないタスクがこれにあたり、これらのタスクは逐次実行されます。タスク実行が終了するとcbコールバックが呼び出され、gulpにタスク実行終了が通知されます。

通常、app, src, styles, sass, imagesタスクは、タスク実行の成果物を「.tmp」へ出力します。ただしプロジェクトのビルド作業は「dist」フォルダで行うため、ここに必要なリソースを集める必要があります。_isBuildtrueを設定すると「.tmp」ではなく「dist」フォルダに、タスク実行の成果物 (html, css, 画像ファイル) を出力するようになります。

これ以外のタスクについては順番に説明していきます。


copy-to-distタスク

プロジェクトビルドの作業ディレクトリであるdistに必要なリソースをコピーするタスクです:

【gulpfile.js】

/**
 * ビルドに必要なリソースをdistフォルダへコピーします。
 */
gulp.task('copy-to-dist', function () {
  // bower_componentsへのシンボリックリンクを作成
  var bower = gulp.src('bower_components')
    .pipe(symlink('dist/bower_components'));

  // libsへのシンボリックリンクを作成
  var libs = gulp.src('libs')
    .pipe(symlink('dist/libs'));

  // 自身のアプリケーションで作成したjsファイルをコピー
  var js = gulp.src('src/**/*.js')
    .pipe(gulp.dest('dist/src'));

  // ビルドに必要なリソースをコピー
  var resources = gulp.src([
    'favicon.ico',
    'manifest.json'
  ]).pipe(gulp.dest('dist'));

  return merge(bower, libs, js, resources);
});

bowerlibs変数に設定された関数は、distフォルダから外部ライブラリを参照するためのシンボリックリンクをsymlink()プラグインで作成します。

js変数に設定された関数は、自身のアプリケーションで作成したjsファイルをdistフォルダへコピーします。

resources変数に設定された関数は、ビルドに必要なリソースをdistフォルダへコピーします。

最後のmerge()プラグインで、これらの関数を並列に実行します。


set-base-pathタスク

開発中は、アプリケーションサイトへのアクセスは次のようなURLで行い、開発を行います:

  • http://localhost:5000/index.html

ただし、本番サーバーでは次のようなURLでアクセスすることになるかもしれません:

  • http://myserver.com/apps/starter-kit/index.html

本番サーバーでは、ドキュメントルート直下ではなく、いくつかの階層の下にアプリケーションを配置する必要があるかもしれません。このような場合、Starter Kitで使用しているpage.jsでは基準パスを設定する必要があります (page.jsを使用していないプロジェクトでは、このタスクは必要ありません) 。

Note: page.jsの基準パスについては「プロジェクトを作成してみよう - ページ遷移 - 基本設定」で説明してます。

このタスクは基準パスを設定するタスクになります:

【gulpfile.js】

// 基準パスを設定してください。
// パスの最後は「/」を付けてください。
var BASE_PATH = '/apps/starter-kit/';

...

/**
 * 基準パスの設定を行います。
 * BASE_PATHにパスを設定しておいてください。
 */
gulp.task('set-base-path', function () {
  // 左のようなタグが見つかると、右のように書き換えられる:
  // <base href="/work/" /> ⇒ <base href="/apps/starter-kit/" />
  var index = gulp.src(['dist/index.html'])
    .pipe(replace(new RegExp('<base[^>]href\s?=\s?([\"\'][^\"\']*[\"\'])[^>]*>'), function ($0, $1) {
      return $0.replace($1, '"' + BASE_PATH + '"');
    }))
    .pipe(gulp.dest('dist'));

  // 左のようなコーディングが見つかると、右のように書き換えられる:
  // page.base('/work') ⇒ page.base('/apps/starter-kit')
  var routing = gulp.src(['dist/src/app.js'])
    .pipe(replace(new RegExp('page.base\\(\\s*([\"\'][^\"\']*[\"\'])\\s*\\)'), function ($0, $1) {
      var basePath = BASE_PATH.substr(0, (BASE_PATH.length - 1));
      return $0.replace($1, '"' + basePath + '"');
    }))
    .pipe(gulp.dest('dist/src'));

  return merge(index, routing);
});

まずBASE_PATHには、本番サーバーに配置するアプリケーションのパスを設定してください。

コーディングの中にあるreplace()はファイルの内容を置き換えることができるプラグインです。これを使用して以下のパス設定を行います。

1つ目のパス設定ですが、「.tmp/index.html」ファイルの中にコメントで示しているような、基準パスを設定すべきタグが存在します。このタグを正規表現で検索し、BASE_PATHを検索されたタグに設定します。

2つ目のパス設定ですが、「.tmp/src/app.js」ファイルの中にコメントで示しているような、基準パスを設定すべきコーディングが存在します。このコーディングを正規表現で検索し、BASE_PATHの最後の「/」を削除したものを、検索されたコーディングに設定します。


polybuildタスク

polybuildとは、vulcanize、crisper、polyclean、を組み合わせたもので、Polymerアプリケーションのビルドをサポートしてくれるプラグインです。次にpolybuildに含まれるプラグインの概要を示します:

  • vulcanize:
    Polymerを使用するようなアプリケーションでは、様々なコンポーネントをHTMLのimportで読み込んで使用します。ただしコンポーネントの依存チェーンによりimportする量がどんどん増えてしまいます。これによりサーバーへ多くのリクエスト発生し、アプリケーションの初期表示に時間がかかってしまうことがあります。vulcanizeは、これらHTML のimportと<script>タグを、1つのファイルにまとめてくれます。

  • crisper:
    昨今のブラウザはCSP (Content Security Policy)が導入されており、このポリシーに従うことでクロスサイトスクリプティング (XSS) のような攻撃を防ぐことができます。CSPのポリシーでは、
    ・ 別ドメインのJavaScriptの読み込みは禁止
    ・ HTMLソースに記述した<script>...</script>のJavaScriptは禁止
    ・ イベント属性 (onclick="alert('hello')" や onclick="onClickFunc()" など) は禁止
    となっているため、HTMLに含まれているJavaScriptはjsファイルへ分離する必要があります。ただしvulcanizeはHTMLとJavaScriptを1つのhtmlファイルにまとめるため、CSPのポリシーに反することになります。crisperはこの1つにまとめられたhtmlファイルからJavaScriptを抜き出し、jsファイルへ分離してくれます。

    Note: crisperは、イベント属性 (onclick="alert('hello')" や onclick="onClickFunc()" など) をjsファイルへ分離してくれません。Polymerで開発する場合は「イベント」を参考にしてイベントリスナの設定を行うようにしてください。

  • polyclean:
    polycleanは、vulcanizeとcrisperによって生成されたhtmlとjsファイルのminifyを行ってくれます。

次はpolybuildタスクになります:

【gulpfile.js】

/**
 * Polymerプロジェクトのビルドを行います。
 */
gulp.task('polybuild', function () {
  return gulp.src('dist/index.html')
    .pipe(polybuild({maximumCrush: true}))
    .pipe(gulp.dest('dist'));
});

polybuildはアプリケーションの入り口となるメインファイルから処理を開始するので、gulp.src()の引数に'dist/index.html'を指定しています (dist/index.htmlはappタスクによって事前に生成されている) 。

polybuild(...)の引数にあるmaximumCrushは、minifyするかの有無を指定します。

このタスクでは、distフォルダに「index.build.html」と「index.build.js」が生成されます。


rename-indexタスク

上記で説明したpolybuildタスクでは「index.build.html」というファイルが生成されますが、このファイル名をrename()プラグインを使用して「index.html」へリネームします:

【gulpfile.js】

/**
 * ビルド成果物であるindex.build.htmlを、index.htmlへリネームします。
 */
gulp.task('rename-index', function () {
  return gulp.src('dist/index.build.html')
    .pipe(rename('index.html'))
    .pipe(gulp.dest('dist'));
});


clean-distタスク

ここまでのタスクでプロジェクトのビルド自体は終わっていますが、distフォルダにはリリースに必要ないリソースが残っています。このタスクではこのようなリソースを削除します:

【gulpfile.js】

/**
 * ビルド成果物として必要な物以外をクリーンします。
 */
gulp.task('clean-dist', function () {
  return del.sync([
    'dist/*',
    '!dist/index.html',
    '!dist/index.build.js',
    '!dist/favicon.ico',
    '!dist/manifest.json',
    '!dist/images'
  ]);
});


プロジェクトのビルドタスクを実行する

Note: Windowsでプロジェクトのビルドを行う際、コマンドプロンプト (cmd.exe) を管理者権限で実行してください。権限の関係でビルドが失敗することがあります。


簡易的に動作確認してみたい場合

ここでは、ビルドしたものが動作するかをとりあえず確認してみたい場合の手順を紹介します。

まず、BASE_PATH'/dist/'を設定します:

【gulpfile.js】

// 基準パスを設定してください。
// パスの最後は「/」を付けてください。
var BASE_PATH = '/dist/';

次にビルドを実行します。プロジェクトルートに移動し、次のコマンドを実行してください:

gulp build

ビルドが終わったら、プロジェクトルートの直下に「dist」フォルダが生成されていることを確認してください。

次にStarter Kitを起動します:

gulp serve

起動したら、次のURLでビルドしたStarter Kitの動作を確認することができます (URLが「/dist/index.html」であることに注意してください) :

  • http://localhost:5000/dist/index.html
  • http://192.168.1.51:5000/dist/index.html (自身のマシンのアドレス)


実際のWEBサーバーで動作確認してみたい場合

ここでは、ビルドしたプロジェクトを、実際のWEBサーバーで動作確認する場合の手順を紹介します。

まず、実際のWEBサーバーにプロジェクトを配置するパスをBASE_PATHに設定します :

【gulpfile.js】

// 基準パスを設定してください。
// パスの最後は「/」を付けてください。
var BASE_PATH = '/apps/starter-kit/';

次にビルドを実行します。プロジェクトルートに移動し、次のコマンドを実行してください:

gulp build

ビルドが終わったら、プロジェクトルートの直下に「dist」フォルダが生成されていることを確認してください。このフォルダを実際のWEBサーバーに配置します。この際フォルダ名をBASE_PATHに設定した最後のセグメント (ここでは「starter-kit」) にリネームして配置してください。

WEBサーバーに配置し終わったら、次のようなURLで動作を確認してみてください (URLは自身の環境に合わせて書き換えてください) :

  • http://myserver.com/apps/starter-kit/index.html