React & Sass の環境構築のために、webpackのテンプレ組んでみました。

## やりたい事 - webpack -

`Sass → { Bundle + Minify　+ Build } → bundle.css`
`Jsx → { Bundle + Babel(React) + Minify } → bundle.js`

これらをWatchするために **webpack-dev-server** をリバースプロキシで立ち上げておいて、
指定したフォルダ内で .scss, .jsx, .js, .html ファイルの変更があった瞬間に
JavaScript&Sassのビルドを自動実行させて、ブラウザを **LiveReload** させたい。


という事で、やりたい事全部まとまってる最新ノートがなかったので組んでみました。
webpack初めて触るので作成大変でしたが、ちゃんと動作して感動です！！

## webpack.config.js
```webpack.config.js

/** ------------------------------------------------------------
 * [Webpack config]

    ※この構成を組んだ際の各モジュールのバージョン

    "devDependencies": {
        "webpack": "^3.11.0",
        "webpack-dev-server": "^2.11.1",
        "extract-text-webpack-plugin": "^3.0.2",
        "node-sass": "^4.7.2",
        "sass-loader": "^6.0.6",
        "style-loader": "^0.20.2",
        "css-loader": "^0.28.10",
        "babel-core": "^6.26.0",
        "babel-eslint": "^8.2.2",
        "babel-loader": "^7.1.2",
        "babel-preset-es2015": "^6.24.1",
        "babel-preset-react": "^6.24.1",
        "babel-preset-react-hmre": "^1.1.1",
    },
    "scripts": {
        "webpack": "webpack --progress",
        "webpack_watch": "webpack-dev-server --progress",
    }

    [npm run webpack] コンバート処理をして、bundleファイルに出力する。
    [npm run webpack_watch] リバースプロキシサーバーを起動して、js[x],scssを監視する。
                            変換はバッファ上のみでファイル出力はされない。
 * ------------------------------------------------------------ */

const path    = require('path');
const webpack = require('webpack');
const ExtractTextPlugin = require('extract-text-webpack-plugin');

/* Convert import,export Path */
const importJsDirPath    = path.join(__dirname, '/src/js');     // ← 入力フォルダ。watch対象になる。
const importJsFileName   = './main.jsx';                        // ← 入力フォルダ内の、変換で起点になるファイル。
const importScssDirPath  = path.join(__dirname, '/src/scss');   // ← 入力フォルダ。watch対象になる。
const importScssFileName = './style.scss';                      // ← 入力フォルダ内の、変換で起点になるファイル。
const exportJsDirPath    = path.join(__dirname, '/public/js');  // ← 出力フォルダ。
const exportCssDirPath   = path.join(__dirname, '/public/css'); // ← 出力フォルダ。

/* Watch対象にしたい静的フォルダ・ファイルパス群 */
const watchDirPath = [
    path.join(__dirname, './app/views/'),
];

/* Reverse Proxy */
const proxyReverse  = 'http://localhost:3000';
const proxyIntoHost = 'localhost';
const proxyIntoPort = '8080';


const config = {

    /**
     * JavaScript Convert Config
     * Bundle + Babel + Minify
     */
    JavaScript: {
        context: importJsDirPath,
        entry  : {
            bundle: importJsFileName,
        },
        output: {
            path    : exportJsDirPath,
            filename: '[name].js',      // [name]には、entryのkey(ここでは'bundle')が入る
        },
        module: {
            rules: [
                {
                    loader : 'babel-loader',
                    test   : /\.js[x]?$/,
                    exclude: /node_modules/,
                    options: {
                        presets: ['es2015', 'react'],
                    },
                },
            ],
        },
        plugins: [
            new webpack.optimize.UglifyJsPlugin(),  // minify
            new webpack.optimize.AggressiveMergingPlugin(),  // もっとminify
        ],
        resolve: {
            extensions: ['.js', '.jsx'],
        },

        /* watch用 dev-server 定義 */
        devServer: {
            host : proxyIntoHost,
            port : proxyIntoPort,
            proxy: {
                '/': {
                    target: proxyReverse,
                },
            },
            watchContentBase: true,
            contentBase     : watchDirPath,
        },
    },

    /**
     * SCSS Convert Config
     * Bundle + SCSS into CSS + Minify
     */
    Sass: {
        context: importScssDirPath,
        entry  : {
            bundle: importScssFileName,
        },
        output: {
            path    : exportCssDirPath,
            filename: '[name].css',     // *ここと
        },
        module: {
            rules: [
                {
                    test: /\.scss$/,
                    use : ExtractTextPlugin.extract({
                        fallback: 'style-loader',
                        use     : [
                            {
                                loader : 'css-loader',
                                options: {
                                    minimize: true, // minify
                                },
                            },
                            {
                                loader: 'sass-loader',
                            },
                        ],
                    }),
                },
            ],
        },
        plugins: [
            new ExtractTextPlugin('[name].css'),    // *ここが同じファイル名になるように。
        ],
    },
};

module.exports = [config.JavaScript, config.Sass];
```

これでReactに挑戦する準備が整いました！楽しみです！