create-react-appからpugまで(その3)

その１
https://qiita.com/DaisukeNishi/items/dae74d5dcf5ddb171b3d
その２
https://qiita.com/DaisukeNishi/items/e93a3448668f65df7a91
その4
https://qiita.com/DaisukeNishi/items/801e1b1e02487e26e905
その5
https://qiita.com/DaisukeNishi/items/ca7d80c104ca7a792f9d
その6
https://qiita.com/DaisukeNishi/items/c8982546c803d2c5dc99

※同じ事を何回も書き直してます。

##pugで書きたい。
`create-react-app`で、めちゃ簡単に`React`で書けるようになってる。
しかし`pug`使おうとしたらいきなり難しかったので反芻して覚える。

##1.create-react-appする
```
$ npm install -g create-react-app
$ create-react-app example
$ cd example
$ yarn start
```
これで`localhost:3000`ができちゃう。
しかし、フォルダの中を見ても`.babelrc`と`.eslintrc`が見当たらない。
`babel`の設定などは、最初の段階では`react-scripts`の中に良い感じに書いてある。今回も`yarn eject`などは使わず、なるべくそのままの形を保っていく。

##２．`babel`の設定を変更できるようにする。
デフォルトでは`.babelrc`を作っても変更できないので、上書きしていく。

```
$ yarn add react-app-rewired
$ yarn add customize-cra
$ touch config-overrides.js
```

`react-scripts`だった所を書き換えます。

```package.json
  "scripts": {
    "start": "react-app-rewired start",
    "build": "react-app-rewired build",
    "test": "react-app-rewired test --env=jsdom",
    "eject": "react-app-rewired eject"
  },
```

オーバーライドするツールで有名なのは`react-app-rewired`らしいですが
`react-app-rewired`が2にバージョンアップしちゃって、
`injectBabelPlugin`という関数が、使えなくなったよ。と警告が出ます。

なので`customize-cra`を使います。
`react-app-rewired`が、
設定ファイルとして使用する`config.overrides.js`の中で、
`customize-cra`を呼び出して使います。

　↓

```config.overrides.js
const { override,
  addBabelPlugins,
  useEslintRc,
  //disableEsLint
} = require("customize-cra");

module.exports = override(
  ...addBabelPlugins(         //←babelの設定を変更できます。
    "babel-plugin-transform-react-pug",
    // ["babel-plugin-transform-react-pug",{"classAttribute": "styleName"}],
    ["babel-plugin-react-css-modules",
      {
        "context"            : "./src",
        "generateScopedName" : "[name]_[local]__[hash:base64:5]",
      }
    ],
    "babel-plugin-transform-react-jsx"
  ),
  useEslintRc(".eslintrc"), //←.eslintrcが有効になります。
  // disableEsLint()        //←.eslintをオフにします。
);
```

設定で`pug`を`jsx`に変換してくれる書き方なので、必ず`pug`の方を上にかかないとダメみたいです。
コメントアウトしてるのですが`disableEsLint()`を有効にすると、
ESLintが動かなくなります。これでbabelかeslintどっちの設定ミスなのか
判別できます。


##3.babel-plugin-transform-react-pugを入れる

```
$ yarn add babel-plugin-transform-react-pug
$ yarn add babel-plugin-transform-react-jsx
$ yarn add babel-plugin-react-css-modules
```
コンフィグの中で指定した3個を入れる。※多分`-D`を付ける。



##4.ESLintを入れる。

```
$ yarn add eslint
$ yarn add eslint-plugin-react-pug
$ yarn add eslint-plugin-css-modules
```

`eslint`本体は`create-react-app`の時に自動で入っているかも。

`.eslintrc`を作り、そこに`package.json`にあった`eslintConfig`を移します。ます。

```
$ touch .eslintrc
```

`package.json`の中のこれは今回は上書きされるので、特に触りませんでした。

```package.json
"eslintConfig": {
  "extends": "react-app"
},
```

↓こちらを下記のように`.eslintrc`に書きます。

```.eslintrc.json
{
  "parser": "babel-eslint",
  "parserOptions": {
    "ecmaVersion": 6,
    "allowImportExportEverywhere": true
  },
  "env": {
    "browser": true,
    "es6": true,
    "node": true,
    "jquery": true
  },
  "plugins": [
    "react-pug"
  ],
  "extends": [
    "react-app",
    "plugin:react-pug/all"
  ],
  "rules": {
    "import/no-named-as-default": 0
  }
}
```

`eslint`のコンフィグはちょっと自信がないので、
オススメされている設定を拾って来て、それに追記すると良いと思います。


##5.App.jsを書き換える。
初期表示のロゴマークくるくるは、`App.js`に書いてあります。

```App.js
function App() {
  return (
    <div className="App">
      <header className="App-header">
        <img src={logo} className="App-logo" alt="logo" />
        <p>
          Edit <code>src/App.js</code> and save to reload.
        </p>
        <a
          className="App-link"
          href="https://reactjs.org"
          target="_blank"
          rel="noopener noreferrer"
        >
          Learn React
        </a>
      </header>
    </div>
  );
}

export default App;
```

↓`pug`に打ち替えてみて、動くか確認します。

```App.js
function App() {
  return pug`
    div(className="App")
    header(className="App-header")
      img(src=logo className="App-logo" alt="logo")
      p
        | Edit 
        code src/App.js
        |  and save to reload.

      a(className="App-link" href="https://reactjs.org" target="_blank" rel="noOpener noReferrer")
        | Learn React
  `;
}

export default App;
```

`styleName`を有効にしておきます。

```config-overrides.js
...addBabelPlugins(
  //"babel-plugin-transform-react-pug",
  // ↑デフォ設定で「className」に変換される方をコメントアウトします。
  ["babel-plugin-transform-react-pug",{"classAttribute": "styleName"}],
  // ↑こちらの「styleName」に変換される方をコメントアウトをはずす。
```

そしてさらに`pug`っぽい感じに、書きかえます。

```App.jsx
import React from 'react';
import logo from './logo.svg';
import './App.module.scss';
import './App.css';

function App() {
  return pug`
    div.App
    header.App-header
      img.App-logo(src=logo alt="logo")
      p
        | Edit 
        code src/App.js
        |  and save to reload.

      a.App-link(href="https://reactjs.org" target="_blank" rel="noOpener noReferrer")
        | Learn React
  `;
}

export default App;

```
（あれ？？？これstyleName、、動いてるっけ？？？？）
でもコレあともう一歩で`vue.js`とそんなに変わらん感じになりそうな気がする
##6.もう一回ブラウザで確認する
```
$ yarn start
```

ちゃんと表示されました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/216132/4b183c45-838b-593d-6732-524d14c8c684.png)

##7.調べてて思った事
Reactは環境構築でハマりやすい。
外国人は、新しいパッケージを作ってはすぐに捨てるので公式のReadmeですら
更新が間に合ってない事がある。
特にreact-pugや、stylus、styleNameに関する記述は少ない気がする。

以上です。

###参考記事
https://github.com/timarney/react-app-rewired
https://github.com/gajus/babel-plugin-react-css-modules/issues/41
https://qiita.com/yikeda6616/items/0e31a920d533d70c0bd9
https://github.com/webpack-contrib/css-loader/issues/877
https://github.com/webpack/webpack/issues/8973
https://github.com/facebook/create-react-app/issues/5113
https://laracasts.com/discuss/channels/elixir/babel-plugin-react-css-modules-not-transforming-stylename-in-react
https://github.com/arackaf/customize-cra#with-webpack
https://github.com/timarney/react-app-rewired/issues/348
https://github.com/pugjs/babel-plugin-transform-react-pug#classattribute
https://github.com/timarney/react-app-rewired

ーーーー
http://www.beguru.work/2019/01/06/create-react-app-%E3%81%A7-babelrc%E3%82%92%E5%88%A9%E7%94%A8%E3%81%99%E3%82%8B/
https://kic-yuuki.hatenablog.com/entry/2019/09/08/111817
https://github.com/facebook/create-react-app

https://stackoverflow.com/questions/56513346/how-to-use-pug-templating-engine-with-reactjs
https://qiita.com/TakuyaHara/items/f560d34aaa7857b32c82
https://www.npmjs.com/package/babel-plugin-transform-react-pug
https://github.com/pugjs/babel-plugin-transform-react-pug#eslint-integration
https://github.com/ezhlobo/eslint-plugin-react-pug
https://html2pug.now.sh/