create-react-appを使わずコピペ一発でReactの開発環境を整える

# 環境構築めんどくさすぎる...

Reactの環境構築をcreate-react-appを用いずに行う場合,ターミナルでコマンドと戯れながら環境を作っていくことになります.

また,webpackなどの設定もエディタを開いて逐次編集していく必要があり,まぁまぁ面倒です.
そこで各ファイルの作成と基本的な設定の記述,必要なモジュールのインストールをコピペ一発でできれば便利と思ったので,必要な手順とファイル作成・書き込みの処理を羅列したスクリプトを書きました.

以下に筆者の実行環境を記述します.
- macOS Mojave v10.14.5
- node v12.7.0
- npm 6.10.2

# はじめに

本記事は[こちらの記事](https://qiita.com/akirakudo/items/77c3cd49e2bf39da79dd)を非常に参考にさせていただきました.
ショートカットとしてコピペのみで環境構築をするのもアリですが,ゆっくり仕組みを理解するのも大切だと思いますので元記事様をぜひご参照ください.

# コマンド

以下のスクリプトで基本となる環境構築ができます.

実行する前に,まず作成するアプリケーションの名前を設定してください.
名前を変更しなくても良い方は以下をそのままコピペしてください(testAppという名前で作成されます).

ちなみにシェルで変数宣言する際は,'='の前後に空白があると正しく実行できないので注意してください.

APPNAMEを適切に設定したら以下の`APPNAME=testApp`より下の行をコピーしてターミナルにペーストしてください.
スクリプトの下に各コマンドの説明があるので,気になる方はまず下からみてみてください.
また記事後方にテストコードもあります.


```terminal.
APPNAME=testApp
mkdir $APPNAME
cd $APPNAME
git init
echo "node_modules" > .gitignore
npm init -y
mkdir src dist
npm i -D @babel/core babel-loader @babel/preset-env @babel/preset-react @babel/register
echo '{
  "presets": [
    "@babel/preset-env", "@babel/preset-react"
  ]
}' > .babelrc
npm i -D webpack webpack-cli
echo "require('@babel/register');
module.exports = require('./development');" > webpack.config.js
echo "import path from 'path'
import HtmlWebpackPlugin from 'html-webpack-plugin'

const src  = path.resolve(__dirname, 'src')
const dist = path.resolve(__dirname, 'dist')

export default {
  mode: 'development',
  entry: src + '/index.jsx',

  output: {
    path: dist,
    filename: 'bundle.js'
  },

  module: {
    rules: [
      {
        test: /\.jsx$/,
        exclude: /node_modules/,
        loader: 'babel-loader'
      }
    ]
  },

  resolve: {
    extensions: ['.js', '.jsx']
  },

  plugins: [
    new HtmlWebpackPlugin({
      template: src + '/index.html',
      filename: 'index.html'
    })
  ]
}
" > development.js
npm i -S react react-dom
npm i -D webpack-dev-server html-webpack-plugin

```

# コマンド解説
最初から解説していきます.

```terminal.
APPNAME=testApp
mkdir $APPNAME
cd $APPNAME
```
これは特に見る必要ないですね.ディレクトリを作ってそこに移動しているだけです.

```terminal.
git init
echo "node_modules" > .gitignore
```

ここではgitの初期設定を行い,.gitignoreというファイルを作成してそこに'node_modules'を書き込んでいます.

node_modulesをgitにpushすると(容量的に)悲惨なことになるので,初めから書き込んでおくこととします.


```terminal.
npm init -y
mkdir src dist
```

ここではnpmの初期化を-yオプションをつけて実行しています.
npm initは本来対話的に色々設定してくれるんですが,-yオプションをつけるとそれを全部エンターで飛ばしたのと同じになります.

さらにソースコードを格納するsrcディレクトリ,babelでバンドルした結果を格納するdistディレクトリを作成します.


```terminal.
npm i -D @babel/core babel-loader @babel/preset-env @babel/preset-react @babel/register
echo '{
  "presets": [
    "@babel/preset-env", "@babel/preset-react"
  ]
}' > .babelrc
```

ここではまずbabel関連の各種モジュールをインストールします.-D(つまり--save-dev)オプションをつけて,package.jsonに依存関係を記述しています.
その後babelの設定を.babelrcというファイルを作成してそこに書き込みます.

```terminal.
npm i -D webpack webpack-cli
echo "require('@babel/register');
module.exports = require('./development');" > webpack.config.js
```
babelをインストールできたら,次はwebpackをインストールしていきます.
babelと同様にpackage.jsonに依存関係を記述しつつ,webpack.config.jsに設定を記述します.

development.jsに具体的な設定を記述します.
以下がその記述内容です.

```terminal.
echo "import path from 'path'
import HtmlWebpackPlugin from 'html-webpack-plugin'

const src  = path.resolve(__dirname, 'src')
const dist = path.resolve(__dirname, 'dist')

export default {
  mode: 'development',
  entry: src + '/index.jsx',

  output: {
    path: dist,
    filename: 'bundle.js'
  },

  module: {
    rules: [
      {
        test: /\.jsx$/,
        exclude: /node_modules/,
        loader: 'babel-loader'
      }
    ]
  },

  resolve: {
    extensions: ['.js', '.jsx']
  },

  plugins: [
    new HtmlWebpackPlugin({
      template: src + '/index.html',
      filename: 'index.html'
    })
  ]
}
" > development.js
```
詳しい説明は省きますが,srcディレクトリのindex.jsxとindex.htmlをもとにバンドルされたファイルをbandle.jsとしてdistディレクトリに出力します.

最後に以下のコマンドを実行します.

```terminal.
npm i -S react react-dom
npm i -D webpack-dev-server html-webpack-plugin
```
このコマンドでreact等をインストールします.

以上で終わりです.

もしエラーが出たときは,node,npmのバージョンを確認してあげてみるなど,エラーメッセージをみながら対応してみてください.

作成後のディレクトリ構成はこんな感じです.

```terminal.
.
├── development.js
├── dist
├── package-lock.json
├── package.json
├── src
└── webpack.config.js

```


# 動作確認

[元記事様](https://qiita.com/akirakudo/items/77c3cd49e2bf39da79dd)のコードを参考に以下のテストコード作成用スクリプトも書きました.
srcディレクトリにindex.htmlとindex.jsxを作成してコードを書き込み,webpackでバンドルします.

```terminal.
echo 'import React from '"'react'"';
import {render} from '"'react-dom'"';

class App extends React.Component {
  render () {
    return <p> Hello React!</p>;
  }
}

render(<App/>, document.getElementById('"'app'"'));' > src/index.jsx
echo '<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>React Test</title>
  </head>
  <body>
    <div id="app" />
  </body>
</html>' > src/index.html
./node_modules/.bin/webpack
./node_modules/.bin/webpack-dev-server
```

コマンド実行後は
[http://localhost:8080/](http://localhost:8080/)にアクセスすることでローカルサーバー上での動作を確認できます.

ちなみに

```
./node_modules/.bin/webpack
./node_modules/.bin/webpack-dev-server
```

は

```
npx webpack
npx webpack-dev-server
```

でも実行できます.こっちの方が簡潔ですね.


# まとめ
[元記事様](https://qiita.com/akirakudo/items/77c3cd49e2bf39da79dd)のコードを大いに参考にさせて頂いていますので,ぜひそちらもご覧ください.