通常のHTMLファイルに単一コンポーネントVue.jsを組み込む方法

## 前置き
しばらく前に下記のようなことができるVueCLIの導入をして勉強していたのですが、
この開発ツールで作成した単一ファイルコンポーネント(.vueファイル)をそのまま、
普通のHTMLファイルに組み込む方法が意外とぐぐっても情報が少なかったので、
改めてまとめてみたいと思います。

### VueCLIでできること
- プロジェクトのテンプレートの作成
- 複数のjsファイルを一つにまとめる
- .vueファイルを.jsに変換する
- トランスパイル
- JavaScriptの構文チェック
- テストツールの導入など

### 単一ファイルコンポーネントとは
その前に、Vue.jsの単一ファイルコンポーネントファイルについて改めて復習します。
単一ファイルコンポーネントファイルとは、以下のように、template, script, styleの
3つがセットになった拡張子vueのファイルです。

```vue
<template>
  <p>{{ greeting }} World!</p>
</template>

<script>
module.exports = {
  data: function() {
    return {
      greeting: "Hello"
    };
  }
};
</script>

<style scoped>
p {
  font-size: 2em;
  text-align: center;
}
</style>
```

templateが表示部分、scriptがロジックや内部データ、styleはそのままCSSですね。
この1セットで一つの機能、コンポーネントになっています。

### 拡張子vueファイルについて
上述の単一ファイルコンポーネントは拡張子vueというファイルになっています。
VueCLI環境では、この拡張子vueファイルのまま開発が行えます。
これは前述のVueCLIでできることの中に、「.vueファイルを.jsに変換する機能」が組み込まれているからです。

拡張子vueファイルを扱えるのは、あくまでVueCLIという環境の中での話なので、通常のHTMLファイルに
そのまま組み込むことはできません。

### Webpackについて
拡張子vueファイルを通常のHTMLファイルに組み込むためには、VueCLIにも含まれていた
「.vueファイルを.jsに変換する機能」が必要です。それを行ってくれるのがWebpackです。
Webpackはモジュールバンドラと呼ばれるツールで、複数のファイルを１つにまとめる(バンドル)
機能を持ちます。HTMLファイルに組み込む前に、このWebpackを用いて、Vue.jsと自作した
拡張子vueファイルをまとめて1つのjsファイルにすることで、通常のHTMLファイルに
単一コンポーネントファイル(拡張子vueファイル)を組み込める状態になります。

## 組み込み方法
それでは、以降で具体的な手順を記載します。 
作業環境のOSはdebian系を利用します。
(最後にdockerファイル共有します)

### VueおよびWebpackのインストール
適当な作業ディレクトリを作りそこで作業します。

```bash
$ mkdir ~/scf_test
$ cd ~/scf_test
```

各種必要なものをインストールしていきます。

```bash
# yarnのインストール
$ apt-get install -y yarn
# vue関連のインストール
$ yarn add --dev vue vue-loader vue-template-compiler
# webpackのインストール
$ yarn add webpack webpack-cli 
```

### Webpack用の設定ファイル作成
Webpackを実行するために必要な設定ファイルを作成します。
この設定ファイルを用意することで、拡張子vueファイルに対してwebpackによるVue.jsと
自分が作った単一コンポーネントファイルを結合し、1つのjsファイル(下記の設定ではbundle.jsというファイル)
にバンドルすることができるようになります。

```js:./webpack.config.js
// output.pathに絶対パスを指定する必要があるため、pathモジュールを読み込んでおく
const path = require('path');
const { VueLoaderPlugin } = require("vue-loader");

module.exports = {
    // モードの設定、v4系以降はmodeを指定しないと、webpack実行時に警告が出る
    mode: 'development',
    // エントリーポイントの設定
    entry: './src/js/app.js',
    // 出力の設定
    output: {
        // 出力するファイル名
        filename: 'bundle.js',
        // 出力先のパス（絶対パスを指定する必要がある）
        path: path.join(__dirname, 'public/js')
    },
    module:{
        rules: [
            // .vue ファイルを組み込むためのモジュール
            {
                test: /\.vue$/,
                loader: 'vue-loader'
            },
        ]
    },
    resolve: {
        extensions: ['.js', '.vue'],
        modules: [
            "node_modules"
        ],
        alias: {
            // vue.js のビルドを指定する
            vue: 'vue/dist/vue.common.js'
        }
    },
    plugins: [new VueLoaderPlugin()]
};
```

### サンプルの単一コンポーネントファイル作成
バンドルしたいサンプルの単一コンポーネントファイルを作っておきます。
上記のwebpackの設定内で、「エントリーポイントの設定」があると思います。
そこが、自分が作成する単一コンポーネントを呼び出す起点のjsファイルになります。
まずはそれの作成です。

```js:./src/js/app.js
import Vue from 'vue';
import HelloWorld from './components/hello-world.vue';

new Vue({
    el: '#app',
    components: {
        'hello-wold': HelloWorld,
    },
});
```

次に単一コンポーネントファイルを作成します。

```vue:./src/js/components/hello-world.vue
<template>
  <div>{{msg}}</div>
</template>

<script>
export default {
  name: 'HelloWorld',
  props: {
    msg: String
  }
}
</script>

<style scoped>
</style>
```

### Webpackによるバンドル処理
続いて、上記で作成したファイルを元にwebpackでバンドル処理を行います。
webpackコマンドは`./node_modules/.bin/webpack`にあります。

```bash
$ ./node_modules/.bin/webpack
```

成功すると、`public/js/bundle.js`というファイルが作成されているはずです。
これがバンドルされたファイルです。

## バンドルされたファイルを通常のHTMLファイルに組み込む
これは単純にHTMLファイルからさきほど作成したbundle.jsを読み込むだけです。
以下のようなHTMLファイルになります。

```html
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>scf tutorial</title>
</head>
<body>
<h1>scf test</h1>
<div id="app">
    <hello-wold msg="sayHello"></hello-wold>
</div>

<script src="public/js/bundle.js"></script>
</body>
</html>
```

上記のHTMLファイルをブラウザで開き、`sayHello`と表示されていれば成功です。
なお、単一コンポーネントファイルを修正した場合は、webpackコマンドによる
バンドル処理を行い、bundle.jsを作り直す必要があります。

## dockerファイル共有
上記の環境を整え済みのdockerファイルを共有しておきますので、お試し下さい。

```bash
$ git clone https://github.com/jcong7495/vuejs_scf.git
$ cd vuejs_scf
$ docker-compose up -d
$ docker-compose exec nginx bash
$ cd /usr/share/nginx/html/scf_test/
$ yarn install
$ ./node_modules/.bin/webpack
```
上記実行後、`http://localhost/scf_test/`にアクセスして`sayHello`と表示されれば成功です。