Docker で　angular2　の　 DEVELOPERS GUIDE Webpack: an introduction を試してみた。

# 概要
Angular2の[Webpack an introduction ][link1]をDockerを使って試す。

環境は以下の通り
 
 - OS:Windows10
 - VirtualBox: 5.0.22
 - Vagrant: 1.8.4

# フォルダ構成

```Windows上のテスト用ディレクトリ以下.
- Vagrantfile
- share
　- angular2
　  - index.html
　  - main.ts
　  - polyfills.ts
　  - vendor.ts
    - app
      - app.component.ts
      - app.component.html
      - app.component.css
      - app.component.spec.ts
    - public
      - css
        - styles.css
      - images
        - angular.png
  - gulp
    - tasks
      - task.js
  - Docker
    - angular2
      - Dockerfile
      - package.json
      - webpack.config.js
      - tsconfig.json
      - typing.json
      - config
        - helpers.js
        - karma.config.js
        - karma.test-shim.js
        - webpack.common.js
        - webpack.dev.js
        - webpack.prod.js
        - webpack.test.js
    - shell
      - angular.sh
      - env.conf
```

# 各ファイルの設定

以下のファイルは[Webpack an introduction][link1]の通り

```
      - webpack.config.js
      - tsconfig.json
      - typing.json
      - package.json
      - config
        - helpers.js
        - karma.config.js
        - karma.test-shim.js
        - webpack.common.js
        - webpack.prod.js
        - webpack.test.js
- share
　- angular2
　  - index.html
　  - main.ts
　  - polyfills.ts
　  - vendor.ts
    - app
      - app.component.ts
      - app.component.html
      - app.component.css
      - app.component.spec.ts
 ```

以下のファイルは適当に作る。
今回はquickstartのstyles.cssとアングラーの画像を使用。

```
    - public
      - css
        - styles.css
      - images
        - angular.png
```

以下のファイルは　「[Dockerでangular2のquickstartを試してみた][link2]　」の内容と同じなので割愛。

```Windows上のテスト用ディレクトリ以下.
- Vagrantfile

    - shell
      - env.conf
```

8080ポートをポートフォワーディングする設定に。

```shell:Docker/shell/angular.sh
#!/bin/bash 

source "/vagrant/Docker/shell/env.conf"

imageName="hibo/angular2"
containerName="angular2"
host_src_dir="/vagrant/share"
container_src_dir="/home/vagrant/share"
docker_dir="${path_Dockerfile_dir}/angular2"

# -t: docker側の標準出力をホストの標準出力につなげる。
# -i: ホスト側のキーボードで打った文字をコンテナに送る
# -p:ポートフォワディング ホスト側：コンテナ側
# -e:環境変数
# -u:user
# -v: ディレクトリ共有
# -w: ワークディレクトリ
run(){
  docker run --name $containerName --rm -it \
             -p 8080:8080 \
             -m "300M" --memory-swap "512M" \
             -e "NODE_ENV=production" \
             -v $host_src_dir:$container_src_dir \
             $imageName 
}

run_d(){
  docker run --name $containerName -d -i \
             -p 8080:8080 \
             -m "300M" --memory-swap "512M" \
             -e "NODE_ENV=development" \
             -v $host_src_dir:$container_src_dir \
             $imageName
}

checkBeforeContainer $containerName
default $#

while getopts brdi opt
do
  main ${opt} $docker_dir $imageName $containerName
done
```

webpackが立てるテストサーバのURLをvagrantで動かすように変更する。
vagrantを通してブラウザで画面が見れるよう```host:"0.0.0.0"```の設定をdevServerに記述。

```
var webpackMerge = require('webpack-merge');
var ExtractTextPlugin = require('extract-text-webpack-plugin');
var commonConfig = require('./webpack.common.js');
var helpers = require('./helpers');

module.exports = webpackMerge(commonConfig, {
  devtool: 'cheap-module-eval-source-map',

  output: {
    path: helpers.root('dist'),
    publicPath: 'http://192.168.50.12:8080/',
    filename: '[name].js',
    chunkFilename: '[id].chunk.js'
  },

  plugins: [
    new ExtractTextPlugin('[name].css')
  ],

  devServer: {
    historyApiFallback: true,
    stats: 'minimal',
    host: "0.0.0.0"
  }
});
```

Dockerfileは以下。
`angular2-template-loader`がpackage.jsonにないのでここで追加。
`npm run postinstall`でTypescriptの設定を行う。


```ruby:Dockerfile
FROM node:4.4.7

# Add our user and group first to make sure their IDs get assigned consistently
RUN groupadd -r vagrant && useradd -r -g vagrant vagrant 

ENV DOCKER_FILE_DIR=/vagrant/Docker/angular2
ENV WORK_DIR=/home/vagrant/angular2-quickstart

# ======================================================================
#タスクランナーインストール
ENV GULP_DIR=/home/vagrant/gulp
RUN mkdir -p ${GULP_DIR}
WORKDIR ${GULP_DIR}

# package.jsonを書き出し
# nameをgulpにするとエラーとなる
RUN echo '{ "name": "my_gulp",  "scripts": { "gulp":"gulp" }}' > package.json

# install
RUN npm install -g gulp 
RUN npm install --save-dev gulp 
RUN npm install --save-dev require-dir 
RUN npm install --save-dev gulp-if 

#gulpfileを書き出し
RUN echo "var requireDir = require('require-dir'); requireDir('/home/vagrant/share/gulp/tasks/', { recurse: true }); " > gulpfile.js 

# ======================================================================

RUN mkdir -p ${WORK_DIR}
WORKDIR ${WORK_DIR}

# COPY命令では../のように親ディレクトリは指定できない。
# 構築時にコンテクストのディレクトリ以下をDockerデーモンに送るため
COPY package.json $WORK_DIR/package.json
RUN npm install

# loaderが足りない
RUN npm install --save-dev angular2-template-loader

# typescript設定
COPY tsconfig.json ${WORK_DIR}/tsconfig.json
COPY typings.json ${WORK_DIR}/typings.json
RUN npm run postinstall

# 各種設定ファイル用意
COPY webpack.config.js ${WORK_DIR}/webpack.config.js
COPY config ${WORK_DIR}/config


RUN mkdir src
RUN mkdir public

# ======================================================================
ENV SHARE_DIR=/home/vagrant/share
RUN mkdir -p ${SHARE_DIR}
# ======================================================================

WORKDIR ${GULP_DIR}
CMD ["npm", "run", "gulp" ]
```

gulp用の設定ファイルを記述.

```js:share/gulp/task.js
var gulp = require('/home/vagrant/gulp/node_modules/gulp');
var spawn = require('child_process').spawn;

var angular2_dir = "/home/vagrant/angular2-quickstart";

gulp.task('default', ['copy','watch', 'angular2']);

gulp.task('copy',function(){
    var base_dir = "/home/vagrant/share/angular2",
        dist_dir = angular2_dir + "/src",
        public_base_dir = base_dir + "/public",
        public_dist_dir = angular2_dir + "/public";

    gulp.src(
        [ public_base_dir + '/images/*', public_base_dir + '/css/*' ],
        { "base": public_base_dir }
    )
    .pipe( gulp.dest( public_dist_dir ) );

    return gulp.src(
        [ base_dir + '/*', base_dir + '/app/*' ],
        { "base": base_dir }
    )
    .pipe( gulp.dest( dist_dir ) );
});

gulp.task('angular2',['copy'], function(){
  spawn('npm',['start'], { cwd:angular2_dir,
    stdio: ['pipe', process.stdout, process.stderr]});
});

gulp.task('watch',['copy'],function(){
  gulp.watch(['/home/vagrant/share/angular2/**', '/home/vagrant/share/public'], ['copy']);
});

```

ファイルをすべて準備できたら、ssh接続.
できたら、仮想環境で以下を実行。

```
/vagrant/Docker/shell/angular.sh -b
/vagrant/Docker/shell/angular.sh
```

Dockerが立ち上がったら、ブラウザで192.168.50.12:8080にアクセスすると
angular2のquickstartの画面が見えるはず。

#参考資料
[Webpack an introduction ][link1]
[Dockerでangular2のquickstartを試してみた][link2]

[link1]:https://angular.io/docs/ts/latest/guide/webpack.html

[link2]:http://qiita.com/hibohiboo/items/48082fea83f2a04470ef
[link3]:http://stackoverflow.com/questions/33332394/angular-2-typescript-cant-find-names