webpack で React, scss のコンパイルと ESLint を設定する方法

# webpackとは

http://webpack.github.io

webpackは依存関係のあるJSやCSSなどを、まとめてくれるビルドツールです。

webpackにはLoaderという仕組みがあり、ソースコードに適用する処理を柔軟に設定することができ、 そのLoaderを使うことで、scssやJSXなどで書かれたファイルを変換することができます。

ここでは、React (jsx) , scss のコンパイルと、JavaScriptの構文をチェックしてくれるツールの ESLint をwebpackで行えるように設定します。

# 構成

今回は、以下のようなディレクトリ構成を想定し、
src の中の React と scss ファイルをdestディレクトリ内に配置することを考えます。

```
src
 ├─ react
 └─ scss
dest
 ├─ js
 └─ css
package.json
node_modules
webpack.config.js
```

gitを使用する場合は、``` node_modules ``` をバージョン管理の対象外にしたいため、
src や dest と同じ階層に``` .gitignore ``` を作成し、下記を記載します。

```javascript
// .gitignore
node_modules/
```

# package.jsonの作成
まずはprojectのpackageを管理するためのファイルである、
package.json を作成するために以下のコマンドを実行します。

```sh
$ npm init -y
```

``` -y ``` オプションは聞かれる質問に全て yes でファイルを作成するというものです。
今回は全てyesで問題ないため、このオプションを実行します。

# webpackのインストール

次に今回ビルドツールとして使用する webpack をインストールします。

```sh
$ npm install -D webpack
```

``` -D ``` オプションは開発時にのみ必要なライブラリをインストールしつつ、
packpage.json に依存関係を記述してくれるオプションです。


# scssのコンパイル設定

続いて scss のコンパイルのための設定を行います。

## パッケージのインストール

```sh
$ npm install -D style-loader css-loader sass-loader node-sass extract-text-webpack-plugin
```

scssのコンパイルをcssファイルとして出力する場合には ``` extract-text-webpack-plugin ``` というプラグインが必要になります。

## webpack.config.js でビルド設定を書く

まずはwebpackの内容を記述するファイル ``` webpack.config.js ``` を作成し、
タスクを書いていきます。

``` javascript
// webpack.config.js
const ExtractTextPlugin = require('extract-text-webpack-plugin');

module.exports = {
  entry: {
    common: './src/scss/common.scss' // コンパイル対象ファイルのpath
  },
  output: {
    path: './dest/css/', // コンパイル後に出力するpath
    filename: '[name].css' // [name] には entry の key の値が入る（今回では common ）
  },
  module: {
    loaders: [
      { 
        test: /\.scss$/,
        loader: ExtractTextPlugin.extract("style-loader", "css-loader?minimize!sass-loader")
      }
    ]
  },
  plugins: [
    new ExtractTextPlugin('[name].css')
  ]
}
```

``` "css-loader?minimize!sass-loader" ``` の ``` ?minimize ```を外すと
ビルド結果がminifyされてない形で生成されます。


## コンパイル実行

これで ``` src/scss/common.scss ``` を作成し、

```sh
$ ./node_modules/.bin/webpack -w
```
を実行すれば ``` dest/css/common.css ``` にビルド結果が生成されます。


# Reactのコンパイル設定

続いて React (JSX) のコンパイルの設定を行います。

## babelのインストール
babelを使ってjsxファイルをトランスパイルします。

```sh
$ npm install -D babel-core babel-loader babel-preset-es2015 babel-preset-react
```
「babel-xxxxxx」というプラグインが多いですが、
babel-preset-xxxxx は、es2015 や JSX を変換するためのプリセットが babel 本体と分離しているので、個別にインストールする必要があります。


## Reactのインストール

実際に React をインストールします。

```sh
$ npm install -S react react-dom
```

``` -S ``` オプションは、アプリケーションに必要なライブラリを、 ``` packpage.json ``` に追加しつつインストールをします。


## webpack.config.js でビルド設定を書く

上で書いた ``` webpack.config.js ``` に React のビルドタスクを追加していきます。

``` javascript
// webpack.config.js
const ExtractTextPlugin = require('extract-text-webpack-plugin');

module.exports = [{
  // ここから React のコンパイルタスク
  entry: {
    app: './src/react/index.jsx',
  },
  output: {
    path: './dest/js/',
    filename: '[name].js'
  },
  module: {
    loaders: [
      { // babelの対象ファイルの指定
        test: /\.(js|jsx)$/,
        loader: 'babel',
        exclude: /node_modules/, // node_modules配下のファイルは対象外にする
        query: {
          presets: ["es2015", "react"],
        }
      },
    ]
  },
},{
  // ここから scss のコンパイルタスク
  entry: {
    common: './src/scss/common.scss'
  },
  output: {
    path: './dest/css/',
    filename: '[name].css'
  },
  module: {
    loaders: [
      { 
        test: /\.scss$/,
        loader: ExtractTextPlugin.extract("style-loader", "css-loader?minimize!sass-loader")
      }
    ]
  },
  plugins: [
    new ExtractTextPlugin('[name].css')
  ]
}]
```


## コンパイル実行

これで ``` src/react/index.jsx ``` を作成し、

```sh
$ ./node_modules/.bin/webpack -w
```

を実行すれば ``` dest/js/ ``` に JS のビルド結果が、
``` dest/css/ ``` に css のビルド結果が生成されます。


# ESLintを導入する

ESLintの設定方法についてはこちらに書いてあるので、参考にしてください。

[ReactでESLintを使う - Live in the moment](http://sottar.hatenablog.com/entry/2016/11/01/235417)


ここでは、ESLintの設定は完了していることを前提とし、
webpackでのビルド時にESLintを実行させる設定を行います。

## ライブラリのインストール

まずはwebpackでESLintを使用するためのnpmのライブラリをインストールします

```sh
$ npm install -D eslint-loader
```

## webpack.config.jsに記述

ESLintの組み込みもこれまでと同様に ``` webppack.config.js ``` 内に書いていきます。

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

module.exports = [{
  entry: {
    app: './assets/javascripts/app.jsx',
  },
  output: {
    path: '../app/assets/javascripts/',
    filename: '[name].js',
  },
  // ESLint の設定ファイルの読み込み
  eslint: {
    configFile: './.eslintrc.json',
  },
  module: {
    loaders: [
      {
        test: /\.(js|jsx)$/,
        loader: 'babel',
        exclude: /node_modules/,
        query: {
          presets: ["es2015", "react"],
        }
      },
      // ESLintの対象ファイルの指定
      {
        test: /\.(js|jsx)$/,
        loader: 'eslint',
        exclude: /node_modules/, // node_modules配下のファイルは対象外にする
      }
    ]
  },
},{
  .....

```

## 実行

実行コマンドはこれまでと同様、以下になります。

```sh
$ ./node_modules/.bin/webpack -w
```

Lint に引っかかった場合にはerrorログが表示されます。

# サンプル

今回のコードサンプルはこちらにあります。参考にしてください。
https://github.com/sottar/react_scss_compile_on_webpack_sample