2017.2.24
2017.6.6

webpackで開発環境の構築

昨年(2016年)の9月にAngularJSの後継であるAngular2(正しくはAngular)が正式にリリースされました。ちょうどAngularJSのフレームワークを扱っていたこともあって注目していましたが、このたび、PHPで作成していた管理サイトがだいぶ古くなっていて、かつ、新しくなったフレームワークを試してみたいという思いもあったので、Angular2でそのサイトを作り直してみることにしました。

というわけで、まず最初にやることは開発環境の構築です。

なお、AngularJSは扱ったことがありますが、ビルドツールやタスクランナーは使ったことがなく、どれを使えばいいのか初めは分かりませんでしたが、こちらの記事(これを選んでおけば間違いない2016年流行りのCSS・JavaScript・タスクランナー - Qiita)を参考にしてwebpackを利用してみることにしましたので、以下はAngular2とwebpackを利用した場合の環境構築になります。

目次

  • プロジェクトの作成
  • webpackの利用
  • 環境構築をやってみた感想
  • 参考リンク

プロジェクトの作成

Angular用のプロジェクト作成ですが、なにぶん初めてのことなので公式サイトのQUICKSTARTを参考にしました。読み進めていくとQUICKSTART用に必要なファイル一式がセットにされているZIPファイルがあるのでこれをダウンロードします。

基本的なものはこのZIPファイルに含まれているので解凍した後、コマンドプロンプト起動して「package.json」ファイルがあるフォルダまで移動。移動後に「npm install」を実行すれば必要なものが自動でインストールされます。(Node.jsはインストールされている前提)


cd quickstart
npm install

また、公式サイトのQUICKSTART以外にこちら(angular2-webpack-starter)のようなものがあったのですが、最初から色々付きすぎていてさっぱり理解できず、入口としてのハードルがかなり高かったので諦めました。ただ、今回利用する予定のwebpackや開発と本番用での設定ファイルの切替など、あったら便利そうなものが最初からついているので、フレームワークに慣れたら使ってみてもいいかもしれません。

インストールが終わったら、コマンドプロンプトから以下のコマンドを実行するだけで、Webサーバーが起動して動作確認が行えます。


npm start

webpackの利用

上記のQUICKSTART用のプロジェクトではsystemjsが使用されていて、require()で呼び出すファイルはこのsystemjs用の設定ファイル(systemjs.config.js)で定義されています。

別にそのままでもよかったのですが、今回はindex.html以外のファイル(html、js、css、jpg、pngなど)は可能であればすべて一つのJSファイル(bundle.js)にまとめてみたいと思っていたので、systemjsの代わりのwebpackを利用することにしました。

こちらの記事(【意訳】Webpackの混乱ポイント - Qiita)に一度目を通すとよいかと思います。

webpackのインストールは以下の通り。


npm install --save-dev webpack                

インストール後、webpack用の設定ファイル(webpack.config.js)をプロジェクトフォルダ直下に作成します。他の記事でも紹介されているのでここでは詳しくは割愛しますが、以下のような感じになるかと思います。


module.exports = {
  // エントリポイント
  entry: './src/main.js',
  // 出力の指定
  output: {
    path: './dist',
    publicPath: '/',
    filename: 'bundle.js'
  },
  module: {
//    rules: [
//    ],
//    loaders: [
//    ]
  },
  resolve: {
    // require()する時の拡張子を省略可能
//    extensions: ['', '.js', '.css']
    extensions: ['.js', '.css']
  }
};

「entry:」でbundle.jsに含めるファイルの開始位置を指定。これを指定しておくだけで残りのファイルはrequire()で指定されているファイルを読み取って勝手にやってくれているっぽいです。

「output:」で出力先とファイル名を指定します。上記の設定では「dist」フォルダに「bundle.js」ファイルを出力する設定になっています。

「module:{rules:[], loaders:[]}」でwebpack実施時に読み込んだファイルに対しての操作を指定します(PostCSSのAutoprefixerを利用する場合など)。なお、preLoadersを使っている記事をいくつか見かけましたが、これはwebpack2.2?から削除されているようなので注意してください。preLoadersの代わりにrulesで指定するようです。

「resolve:{extensions:}」でrequire()で指定するファイルの拡張子を省力可能にします。多くの記事で空文字('')を含めた指定をしていて、逆に拡張子つきで読み込みたい場合に指定するようですが、私の環境ではビルド時に以下のようなエラーが出たので除外しました。


Invalid configuration object. Webpack has been initialised using a configuration object that does not match the API schema.
configuration.resolve.extensions[0] should not be empty.

次に「main.ts」を修正します。


// index.htmlで読み込んでいるsystemjs以外のファイル
require('./styles.css');
require('../node_modules/core-js/client/shim.min.js');
require('../node_modules/zone.js/dist/zone.js');

import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { AppModule } from './app/app.module';
platformBrowserDynamic().bootstrapModule(AppModule);                

main.tsとは別にentry.jsのようなエントリ用のJSファイルを別途作成してもよいです。作成する場合は以下のようにして、webpack.config.jsの「entry: main.js」を「entry: entry.js」に書き換えます。


// entry.js
require('./styles.css');
require('../node_modules/core-js/client/shim.min.js');
require('../node_modules/zone.js/dist/zone.js');

// 本番用
// var core_1 = require('@angular/core');
// core_1.enableProdMode();

require('./main.js');

enableProdMode()についてはこちら(enableProdMode - ts - API)を参照。

enableProdMode()を実行していない場合、ページをブラウザのデベロッパーツールで開くとConsoleに以下のようなログが出力されています。


Angular is running in the development mode. Call enableProdMode() to enable the production mode.            

次にdistフォルダ配下に「index.html」を作成します。


<!DOCTYPE html>
<html>

<head>
  <title>Angular QuickStart</title>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <base href="/">
</head>

<body>
  <my-app>Loading AppComponent content here ...</my-app>
  <script src="bundle.js"></script>
</body>

</html>

src/index.htmlから不要なファイル(「main.ts」または「entry.js」で呼び出しているファイルとsystemjs関連のscriptタグ)を削除したものになります。

注意点としてwebpackによって生成された「bundle.js」の読み込みは my-app タグの後に行ってください。my-appよりも前だと以下のようなエラーがブラウザのコンソールに出力されてページが表示されません。


EXCEPTION: Error in :0:0 caused by: The selector "my-app" did not match any elements
ORIGINAL EXCEPTION: The selector "my-app" did not match any elements

最後に「package.json」にwebpack用のコマンドの追加とstartコマンドの修正を行います。


  "scripts": {
    ...
    "webpack": "webpack -p",
    "webpack:watch": "webpack -p --watch",
    ...
    "start": "concurrently \"npm run build:watch\" \"npm run webpack:watch\" \"npm run serve\"",
    ...
  },

上記の対応後、「npm start」でwebpack実行後のページが表示されると思います。

環境構築をやってみた感想

QUICKSTARTのプロジェクトを利用するだけで必要なファイルを「npm install」で一括ダウンロードできたり、ファイル修正後のページへの反映を勝手にやってくれたりと、非常に使いやすい開発環境を手に入れることができますが、AngularやTypeScript、はたまたsystemjsやwebpackだったりと、初めて扱うフレームワークやライブラリが多かったので、ビルドツールやタスクランナーを利用せずに開発していたAngularJSよりも最初のハードルがかなり高く感じました。

また、事前に聞き及んでいた通り、Angular2はAngularJSとも完全に別物であるので、学習コストがこれまた高そうな代物であることは間違いなさそうです。

広く普及するのかどうなのか若干怪しい感じはしましたが、現在の時点では日本語の記事も多いのでおそらく大丈夫でしょう。

エディタはVisual Studio Codeを使っています。これもほとんど使ってなかった代物ですが、今回使ってみて、結構便利だと気づかされました。

とりあえず、一つサイトを作って色々試してみたいです。

参考リンク

Angular】関連記事