webpackでVueファイルとSCSS＋ExtractTextPluginをビルドする

Vue SCSS Bootstrap の開発環境。
Laravel Mix とかで簡単に構築できてしまうので、理解するためにも、一回自分でちゃんとwebpack設定してみようと思ったらすごく手間取った。
ので、忘れぬようにメモ。

# やりたいこと

- webpackでコンパイル（watchでファイル変更を監視する）
- Vue.jsを使いたい。（単一ファイルコンポーネントを使いたい）
- スタイルはScssで書く
- CSSは別ファイルに書き出したい
- 基本的なスタイルはBootstrapを使いたい

という感じのときの webpack.config.js 

## ファイル構成
<img width="210" alt="スクリーンショット 2017-11-08 17.32.54.png" src="https://qiita-image-store.s3.amazonaws.com/0/73833/fd0b51d4-0a17-5b66-8acd-ee90b215255a.png">
↓中身
<img width="215" alt="スクリーンショット 2017-11-08 17.30.58.png" src="https://qiita-image-store.s3.amazonaws.com/0/73833/4e7e045d-5bff-5eba-fc6d-7a3090e66bc0.png">

## 準備
```html:index.html
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <title>webpack test</title>
  <link rel="stylesheet" href="css/style.css">
</head>
<body>
  <main id="app">
    <div class="container">
      <div class="row">
        <div class="col-md-12">
          <test></test>
        </div>
      </div>
    </div>
  </main>
  <script src="js/bundle.js"></script>
</body>
</html>

```

## npmのインストール

```json:package.json
{

//
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "dev": "webpack",
    "watch:js": "watch 'npm run dev' src/js/",
    "watch:css": "watch 'npm run dev' src/scss/",
    "watch": "npm run watch:js & npm run watch:css"
  },
  "dependencies": {
    "bootstrap-sass": "^3.3.7",
    "vue": "^2.5.3"
  },
  "devDependencies": {
    "css-loader": "^0.28.7",
    "extract-text-webpack-plugin": "^3.0.2",
    "node-sass": "^4.6.0",
    "sass-loader": "^6.0.6",
    "style-loader": "^0.19.0",
    "vue-loader": "^13.0.4",
    "vue-template-compiler": "^2.4.2",
    "watch": "^1.0.2",
    "webpack": "^3.8.1"
  }
}
```
package.json  はこんな感じでした。
ひょっとしたら、いらないパッケージもあるかも？？
（scriptsのあたりは、おそらくもっとスマートな方法があると思います）


## 設定

```js:webpack.config.js
var ExtractTextPlugin = require('extract-text-webpack-plugin');

module.exports = {
  entry: './src/js/app.js', // jsファイル読み込み先
  output: {
    path: __dirname,
    filename: './public/js/bundle.js'　 // jsファイル出力先
  },
  resolve: {
    alias: {
      vue: 'vue/dist/vue.esm.js'
　　　　　　　　}
  },
  module: {
    rules: [
      {
        test: /\.vue$/,
        loader: 'vue-loader',
      },
      {
        test: /\.scss$/,
        use: ExtractTextPlugin.extract({
          fallback: 'style-loader',
          use: ['css-loader', 'sass-loader']
        })
      }
    ]
  },
  devtool: 'source-map',
  plugins: [
    new ExtractTextPlugin('./public/css/style.css') // CSSファイル出力先
  ]
};
```

## Bootstrapをつかう

```scss:style.scss
$icon-font-path: "bootstrap-sass/assets/fonts/bootstrap/";
@import "~bootstrap-sass/assets/stylesheets/bootstrap-sprockets";
@import "~bootstrap-sass/assets/stylesheets/bootstrap";

div{
    h1{
        //何か書く
    }
}

```

## Vueコンポーネント

```js:app.js
import Vue from 'vue';
import test from './components/Test.vue';  //コンポーネントファイル

//スタイル
require('../scss/style.scss');

const app = new Vue({
    el: '#app',
    components: {
    "test": test,
  },
});

```

```Vue.js:Test.vue
<template lang="html">
  <div>
    <h1>webpack</h1>
    <h2>のテストだよ</h2>
  </div>
</template>

<script>
export default {
}
</script>

<style lang="scss">

</style>
```

## ビルド（コンパイル）
`$ npm run dev`

監視するとき
`$ npm run watch`


で、なんとか出来たみたい。