Laravel5.4 ＋ React + Webpack2 と Rails5 + React + Webpack2

たまには更新を行おうかなと思い何がいいか考えた結果

最近触る率が高いLaravelにwebpack＋reactを導入してもくもくしてみようかなと思い立ってやってみた結果の手順を書いてみる。


漁れども漁れでもJSをごりごり書いている人ならすんなりって感じの内容で初歩的な内容が少なくて困った挙句初歩的なやり方で行いました。

あくまでjsxファイルをbuildしブラウザ側で読み込むまでのお話。

Laravel、Railsの順に手順を書きます。

## Laravel Projectの作成と下準備

```shell
composer create-project laravel/laravel some_app_name --prefer-dist
// webpackのconfig fileを作成
touch webpack.config.js
// 後々buildしたfileの出力先としてpublicを指定するためにpermissionの変更
chmod 777 public/
```

ひとまずこれでコマンドラインからの下準備は完了です。

※permissionの問題が気にくわないので何かいい方法あれば教えて下さい。

### Laravel5.4からwebpack

なぜか知らないけどもLaravel5.4からwebpackがデフォで入っていてversionも2系、おまけにvueも入っている。

package.jsonには記載ないんだよね。

```shell
npm list | grep webpack
```
で一応確認した。

```js
// webpack.config.js
var path = require('path');


module.exports = {
  devtool: 'inline-source-map',
  entry: {
    app: './resources/assets/js/index.jsx',
  },
  output: {
    path: path.join(__dirname, 'public/js'),
    filename: 'bundle.js'
  },
  module: {
    rules: [
      {
        test: /\.jsx$/,
        loader: 'babel-loader',
        exclude: /node_modules/,
        query: {
          presets: ["react", "es2015"],
        }
      },
    ]
  }, 
}
```

だけです。現状。


**resource/assets/js/**以下に **index.jsx**を作成し以下のように記述

```js
import React from 'react';
import { render } from 'react-dom';

class App extends React.Component {
  render() {
    return (
      <div>Hello, {this.props.name}.</div>
    );
  }
}

render(
  <App name="webpack" />,
  document.getElementById('content')
);
```

これであとは、npm scriptsに記載ある内容を実行するだけ
ただデフォルトの記述ではなく以下のように書き換えて実行した。

```json

"scripts": {
    "test": "eslint resources/assets/js --ext=js,vue && mocha --compilers js:babel-register --require resources/assets/js/tests/helper.js resources/assets/js/tests/**/*Test.js",
    "dev": "cross-env NODE_ENV=development node_modules/webpack/bin/webpack.js --progress --hide-modules",
    "watch": "cross-env NODE_ENV=development node_modules/webpack/bin/webpack.js --watch --progress --hide-modules",
    "hot": "cross-env NODE_ENV=development node_modules/webpack-dev-server/bin/webpack-dev-server.js --inline --hot",
    "build": "cross-env NODE_ENV=production node_modules/webpack/bin/webpack.js --progress --hide-modules"    
  },

```

上記のような内容になります。
いずれも不要なものに関しては、削除して問題ないです。

出力するview側の編集もします
今回は、デフォルトであるwelcome.blade.phpを編集してあげるです

```php
// 省略
	<div class="title m-b-md" id="content"> // 真ん中らへんにある id属性を追加
	</div>
// 省略
	<script src="{{ asset('js/bundle.js') }}"></script> // 追加忘れずに
</body>
```

さっそく試す。

```shell
npm run build
php artisan serve
```

welcome laravel => Hello, webpack
に変わったことが確認できれば問題ないかなと思う。


今後は、これを元にLaravelをAPIとしてのSPAと管理画面は、通常のLaravelで何か作成しようかなと考えている。


## Rails Projectの作成

```shell
rails new some_app_name --skip-bundle && cd some_app_name
bundle exec rails make contoller Top index
touch Procfile
mkdir client && cd client
yarn init
yarn add react react-dom
yarn add babel-core babel-loader babel-preset-es2015 babel-preset-react webpack -D
touch webpack.config.js index.jsx
```

ひとまずは、上記コマンドで必要なものの準備は完了。
npmを利用している人は、yarnをnpmに置き換えてください。

```js
// ./client/webpack.config.js

module.exports = {
  devtool: 'inline-source-map',
  entry: {
    app: './index.jsx',
  },
  output: {
    path: '../app/assets/javascripts/webpack',
    filename: 'bundle.js'
  },
  module: {
    rules: [
      {
        test: /\.jsx$/,
        loader: 'babel-loader',
        exclude: /node_modules/,
        query: {
          presets: ["react", "es2015"],
        }
      },
    ]
  }, 
}
```


```json
// client/package.json
"scripts": {
    "webpack-build": "webpack --config webpack.config.js",
    "webpack-watch": "webpack -w --config webpack.config.js"
  },
```

```js

// ./client/index.jsx
import React from 'react';
import React from 'react';
import { render } from 'react-dom';

class App extends React.Component {
  render() {
    return (
      <div>Hello, {this.props.name}.</div>
    );
  }
}

document.addEventListener('DOMContentLoaded', () => {
  render(
    <App name="webpack" />,
    document.getElementById('content')
  );
});
```

JSの読み込みをbodyタグ前に持ってきている場合は、
document~内のrenderメソッドのみで問題ない。


```erb
# app/views/top/index.html.erb
<div id="content"></div>

```

この段階で動きますな

```shell
npm run webpack-build
bundle exec rails s

```

ブラウザで確認することができるかと思う。

ただなんか二回もコマンド実行するのがめんどいのとbuildは、watchしたいかも！
って感じなんで以下を行う


```Gemfile
gem 'foreman' #追記
```

```shell
bundle install -path vendor/bundle
```



```procfile

rails: bundle exec rails server
webpack: npm --prefix client run webpack-watch

```

記述後以下のコマンドを実行

```shell
bundle exec foreman start
```

うむすっきりっす。


### まとめ

今回異なるフレームワークにてReactとwebpackを使用してみたが
今だにベストプラティクスなものが見当たらない。

JS界隈の動きもだいぶ落ち着きそろそろちゃんと学習を行わなければと考えてみたものの

書き方に統一性が見出せなかったりなどがありまだまだ知識、スキルが低いなと感じる日々ですな。

それとReactやってみたけどVueが気になるのとReduxがどうなんだろう。。。って思う。

シンプルじゃない。

ってことだけなんだけどね。

Reduxについて知らなすぎるから言及できないけど。