webpackでes6+React+Redux+Sassの環境を構築してみる(sourceMap,uglify,minimizeも)


## 前提とか構成
・MacOS 10.11.6で試してます。
・nodeが入っていること。（試したバージョンは4.5）
・gulp等はつかいません。
・構成は以下の通り

```構成
- webpack-sample
    - asset (npm runを実行するフォルダ)
        - js (コンパイル元のjs)
          + app.js
          + sub.js
        - sass　(コンパイル元のsass)
          + app.scss
          + sub.scss
        + package.json
        + webpack.config.js (開発用のconfig)
        + webpack.production.config.js (本番用のconfig)
    + js (jsのコンパイル先のフォルダ)
    + css (sassのコンパイル先のフォルダ)
```

webpack.config.jsの内容ですが、
開発用はjsのsourceMap、uglifyはしていません。（watchしたときに遅くなったため）本番用はしてます。
sassは開発用、本番用ともにsourceMap、minimizeをしてます。
そこらへんは必要に応じて。

監視やビルドはnpm runでしますのでpackage.jsonに記述します。
npm run watchで開発用として監視
npm run buildで本番用としてコンパイルします。


## 手順
1.package.json作成


```bash
mkdir webpack-sample
cd webpack-sample
npm init
// あとはとりあえずEnter

```

2.reactとreduxをインストール

```bash
npm install --save react react-dom redux react-redux
```

3.webpackのインストール

```bash
npm install --save-dev webpack
```

4.babelとプリセットのインストール

```bash
npm install --save-dev babel-loader babel-core babel-preset-react babel-preset-es2015
```

4.sass関係のインストール

```bash
npm install extract-text-webpack-plugin css-loader sass-loader style-loader node-sass --save-dev
```

5.webpack.config.jsの作成
以下webpack.config.jsの内容

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

module.exports = [
    {
        context: path.join(__dirname, 'js'),
        entry: {
            app: './app.js',
            sub: './sub.js'
        },
        output: {
            path: '../js',
            filename: '[name].js'
        },
        module: {
            loaders: [
                {
                    test: /\.js[x]?$/,
                    exclude: /node_modules/,
                    loader: "babel",
                    query:{
                        presets: ['react', 'es2015']
                    }
                }
            ]
        },
        resolve: {
            extensions: ['', '.js', '.jsx']
        }
    },
    {
        context: path.join(__dirname, 'sass'),
        entry: {
            app: './app.scss',
            sub: './sub.scss'
        },
        output: {
            path: '../css',
            filename: '[name].css'
        },
        module: {
            loaders: [
                {
                    test: /\.scss$/,
                    loader: ExtractTextPlugin.extract('style-loader', 'css-loader?-url&sourceMap&minimize!sass-loader?outputStyle=expanded&sourceMap=true&sourceMapContents=true')
                }
            ]
        },
        plugins: [
            new ExtractTextPlugin('[name].css')
        ],
        devtool: 'source-map'
    }
];

```

6.webpack.production.config.jsの作成
基本的にはwebpack.config.jsと同じですが、jsのsourceMap、uglifyをつけています。

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

module.exports = [
    {
        context: path.join(__dirname, 'js'),
        entry: {
            app: './app.js',
            sub: './sub.js'
        },
        output: {
            path: '../js',
            filename: '[name].js'
        },
        plugins: [
            new webpack.DefinePlugin({
                'process.env.NODE_ENV': JSON.stringify('production')
            }),
            new webpack.optimize.DedupePlugin(),
            new webpack.optimize.UglifyJsPlugin({
                compress: {
                    warnings: false,
                    screw_ie8: true
                },
                comments: false
            }),
            new webpack.optimize.OccurenceOrderPlugin(),
            new webpack.optimize.AggressiveMergingPlugin()
        ],
        module: {
            loaders: [
                {
                    test: /\.js[x]?$/,
                    exclude: /node_modules/,
                    loader: "babel",
                    query:{
                        presets: ['react', 'es2015']
                    }
                }
            ]
        },
        devtool: 'source-map',
        resolve: {
            extensions: ['', '.js', '.jsx']
        }
    },
    {
        context: path.join(__dirname, 'sass'),
        entry: {
            app: './app.scss',
            sub: './sub.scss'
        },
        output: {
            path: '../css',
            filename: '[name].css'
        },
        module: {
            loaders: [
                {
                    test: /\.scss$/,
                    loader: ExtractTextPlugin.extract('style-loader', 'css-loader?-url&sourceMap&minimize!sass-loader?outputStyle=expanded&sourceMap=true&sourceMapContents=true')
                }
            ]
        },
        plugins: [
            new ExtractTextPlugin('[name].css')
        ],
        devtool: 'source-map'
    }
];

```

7.package.jsonにscriptsを記述
以下package.jsonの内容

```package.json
{
  "name": "webpack-sample",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "watch": "webpack --watch --progress",
    "build": "webpack --config webpack.production.config.js --progress"
  },
  "author": "",
  "license": "ISC",
  "dependencies": {
    "react": "^15.3.2",
    "react-dom": "^15.3.2",
    "react-redux": "^4.4.5",
    "redux": "^3.6.0"
  },
  "devDependencies": {
    "babel-core": "^6.17.0",
    "babel-loader": "^6.2.5",
    "babel-preset-es2015": "^6.16.0",
    "babel-preset-react": "^6.16.0",
    "css-loader": "^0.25.0",
    "extract-text-webpack-plugin": "^1.0.1",
    "node-sass": "^3.10.1",
    "sass-loader": "^4.0.2",
    "style-loader": "^0.13.1",
    "webpack": "^1.13.2"
  }
}

```

8.assetフォルダでnpm run watchもしくはnpm run buildを実行

## 感想
思ったよりシンプルな感じがします。
import先を変えてもコンパイルがはしるのでいい感じ。
（他のビルドツールもそうなのかな）

## 追記
- 2016/10/18
loader: ExtractTextPlugin.extract('style-loader', 'css-loader?sourceMap&minimize!sass-loader?outputStyle=expanded&sourceMap=true&sourceMapContents=true')
のcss-loader?の後ろに-url&を追加
- bourbonなどのincludePathsの設定は右記URLが参考になりそう
http://qiita.com/cotto89/items/ddd12a24cd40fac5c419