脳内メモリ使わず初期設定（create-react-app）その2

その1
https://qiita.com/DaisukeNishi/items/c8982546c803d2c5dc99

その３
https://qiita.com/DaisukeNishi/items/78bdb0ec6af9aea204d2

※もう自分用`boilerPlate`作ればいいじゃん`git clone`一発だよと思うじゃないですか。
一応、写経なども兼ねて反芻してるです。


##stylusのプラグインを使ってみた
`styled-jsx-plugin-stylus`を入れて動かしてみた
###結論：エラーがでて動かない。
うーん、`pug`も`stylus`も、片方だけで試したが、上手く行かないですね。
`jsx`と`sass`でしか動かん。もうあきらめよう。

っていうか`create-react-app`をあきらめたい
ドコが間違ってるのか教えて欲しい・・・

##環境構築を反芻して覚える。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/216132/fa00a26d-d52f-fde8-5306-81ca2f5ce167.png)

##グローバルインストール（初回のみ）

```
npm i -g create-react-app
sudo npm install eslint -g
sudo npm i -g eslint-plugin-react
```
##プロジェクト(名前例)`react_1231`を作る。

```shell
create-react-app react_`date '+%m%d'`
cd react_`date '+%m%d'`
```
##`git`初期化

```
git init
open .gitignore
```
##セーブポイント除外。

```
.history
```
##yarnで必要なもの一通り

```
yarn add react-app-rewired customize-cra styled-jsx styled-jsx-plugin-stylus stylus stylus-loader axios immer react-app-polyfill react-router-dom react-transition-group react-redux redux redux-devtools redux-thunk
```
##空ディレクトリ作成　

```
mkdir -p src/components/common/common src/components/common/home src/components/common/list src/components/common/detail src/components/pc/common src/components/pc/home src/components/pc/list src/components/pc/detail src/components/sp/common src/components/sp/home src/components/sp/list src/components/sp/detail src/assets/img src/scss src/views src/components/pc/notfound src/components/sp/notfound src/components/pc/about src/components/sp/about src/components/pc/company src/components/sp/company src/components/pc/policy src/components/sp/policy src/components/pc/terms src/components/sp/terms src/components/pc/contact src/components/sp/contact src/store
```
##空ファイル作成

```
touch config-overrides.js .babelrc.json src/Template.js src/components/common/common/Header.js src/components/common/common/Menu.js src/components/common/common/Footer.js src/store/index.js src/store/actions.js src/store/reducer.js
```

##テンプレート作成
```
open src/Template.js
```
```src/Template.js
import React,{Fragment} from 'react'
import { connect } from 'react-redux'

const render = () => {
  return (
  <Fragment>
    <div className="">

    </div>
    <style jsx>{`

    `}</style>
  </Fragment>
  )
}

const mapState = (state) =>{
  return {

  }
}

const mapDispatch = (dispatch) => {
  return {

  }
}

export default connect(mapState, mapDispatch)(render)
```
##テンプレート配置

```
cd src
find . -name "*" -type d -exec cp Template.js {} \;
cd ../
rm src/App.css src/scss/Template.js src/assets/Template.js src/assets/img/Template.js src/components/Template.js src/components/common/Template.js src/components/pc/Template.js src/components/sp/Template.js src/store/Template.js
```
##CRA設定ファイル編集

```
open config-overrides.js
```
```config-overrides.js
const { override,useBabelRc,useEslintRc,disableEsLint} = require("customize-cra");
module.exports = override(
  useBabelRc(".babelrc.json"),
  useEslintRc(".eslintrc.json"),
  //disableEsLint()
);
```
##package.json編集

```
open package.json
```
```package.json
  "scripts": {
    "start": "react-app-rewired start",
    "build": "react-app-rewired build",
    "test": "react-app-rewired test",
    "eject": "react-app-rewired eject"
  },
```
```package.json
"browserslist": {
    "production": [
      ">0.2%",
      "not dead",
      "not ie <= 10",   //←追加
      "not op_mini all"
    ],
```


##babel設定編集

```
open .babelrc.json
```
```.babelrc.json
{
  "presets": [
    "react-app"
  ],
  "plugins": [
    ["styled-jsx/babel",
      { "plugins": ["styled-jsx-plugin-stylus"] }
    ]
  ]
}
```
##eslint初期設定

```
eslint --init

>To check syntax and find problems
>JavaScript modules (import/export) 
>React
Typescript? N
Where code run?
◎ Browser
◎ Node
What format?
>JSON
eslint@latest install? Y
```
```
open .eslintrc.json
```
```
"extends": [
    "react-app"
],
```

##redux用ファイル編集

```
open src/store/index.js
```
```src/store/index.js
import { createStore, applyMiddleware, compose } from 'redux'
import reducer from './reducer'
import * as actions from './actions'
import thunk from 'redux-thunk'

const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose

const store = createStore(
  reducer,
  composeEnhancers(applyMiddleware(thunk))
)
export default store
export { reducer, actions }
```
```
open src/store/actions.js
```
```src/store/actions.js
import axios from 'axios'

export const showSide = () => ({
  type: 'showSide'
})

export const hideSide = () => ({
  type: 'hideSide'
})

export const changeL = () => ({
  type: 'changeL'
})

export const showLR = (val) =>({
  type: 'showLR',
  val
})
```
```
open src/store/reducer.js
```
```src/store/reducer.js
import produce from "immer"
import { combineReducers } from 'redux'

const defaultState = {
  sideBar: false,
  blurStyle: {},
  cover: false
}

const mutations = {
  showSide (state, action) {
    return produce(state, (state) => {
      state.sideBar = true
      state.cover = true
      state.blurStyle = {transform: 'translateX(15rem)', filter: 'blur(3px)'}
    })
  },
  hideSide (state, action) {
    return produce(state, (state) => {
      if (state.LR) {
        state.LR = false
      } else {
        state.sideBar = false
      }
      state.cover = false
      state.blurStyle = {}
    })
  }
}

const store = (state = defaultState, action) => {
  if (mutations[action.type]) {
    return mutations[action.type](state, action)
  }
  return state
}

export default combineReducers({
  store
})
```
```
open src/index.js
```
```src/index.js
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import * as serviceWorker from './serviceWorker';
import store from './store'
import { Provider } from 'react-redux'

ReactDOM.render(<Provider store={store}><App /></Provider>, document.getElementById('root'))
serviceWorker.unregister();
```
##コンポーネント編集
```
open src/components/common/common/Header.js
```
```src/components/common/common/Header.js
import React, {Fragment} from 'react'
import { connect } from 'react-redux'
import { Link } from 'react-router-dom'
import { actions } from '../../../store'

const render = (props) => {
  return (
    <Fragment>
      <div className="header">
        <span className="button" onClick={props.showSide}>
          ≡
        </span>
        <Link to='/'>
          <span className="title">react-app</span>
        </Link>
      </div>
      <style jsx>{`
        .header{
          position fixed
          top 0
          right 0
          left 0
          z-index 5
          background-color #fff
          box-shadow 0 3px 15px 0px #0001
          vertical-align middle
          color #02b3e4

          .button{
            height 4rem
            line-height 4rem
            display inline-block
            padding 0 1rem
            text-align center
            font-weight 800
            font-size 1.2rem
          }

          .title{
            font-size 1.4rem
            font-weigh bold
            margin-left 1.5%
            height 3rem
            line-height 3rem
          }
        }
      `}</style>
    </Fragment>
  )
}

const mapState = (state) =>{
  return {
  }
}

const mapDispatch = (dispatch) => {
  return {
    showSide() {
      dispatch(actions.showSide())
    }
  }
}

export default connect(mapState, mapDispatch)(render)
```
```
open src/components/common/common/Menu.js
```
```src/components/common/common/Menu.js
import React, {Fragment} from 'react'
import { connect } from 'react-redux'
import { Link } from 'react-router-dom'
import { actions } from '../../../store'

const render = (props) => {
  return (
    <Fragment>
      <div className="bar">
        <div className="btn-wrapper">
          <Link to="/">
            <span type="button" className="btn btn-light" onClick={props.hideSide}>閉じる</span>
          </Link>
        </div>
      </div>

      <style jsx>{`
        .bar{
          position fixed
          top 0
          bottom 0
          left 0
          width 15rem
          background-color #fff
          padding-top 2rem
          box-shadow 0px 2px 20px #0003
          z-index 6

          .btn-wrapper{
            height 4.5rem
            line-height 4.5rem
            text-align center
          }
        }
      `}</style>
    </Fragment>
  )
}

const mapState = (state) =>{
  return {
  }
}

const mapDispatch = (dispatch) => {
  return {
    hideSide () {
      dispatch(actions.hideSide())
    }
  }
}

export default connect(mapState, mapDispatch)(render)
```
```
open src/components/common/common/Footer.js
```
```src/components/common/common/Footer.js
import React,{Fragment} from 'react'
import { connect } from 'react-redux'

const Footer = () => {
  return (
    <Fragment>
      <div className="footer">
        Copyright@XXX-XXX co,Ltd.
      </div>
      <style jsx>{`
        .footer{
          color #777
          margin-top 0rem
          height 4rem
          line-height 4rem
          text-align center
          background-color #efefef
        }
      `}</style>
    </Fragment>
  )
}

export default connect(null, null)(Footer)
```
```
open src/App.js
```
```src/App.js
import React, { Fragment } from 'react';
import { connect } from 'react-redux'
import logo from './logo.svg';

import { BrowserRouter }  from 'react-router-dom'
import { actions } from './store'

import Header from './components/common/common/Header'
import Footer from './components/common/common/Footer'
import Menu from './components/common/common/Menu'

import { CSSTransition } from 'react-transition-group'

function App( props ) {

  return (
    <BrowserRouter>
      <div className="App">
        <Header></Header>
        <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>
        <Footer></Footer>
        <CSSTransition in={props.sideBar} timeout={300} classNames="fade" unmountOnExit>
          <Menu />
        </CSSTransition>
        <style jsx>{`
          .App
            text-align center

          .App-logo
            height 40vmin
            pointer-events none

          @media (prefers-reduced-motion: no-preference)
            .App-logo 
              animation App-logo-spin infinite 20s linear

          .App-header
            background-color #282c34
            min-height 100vh
            display flex
            flex-direction column
            align-items center
            justify-content center
            font-size calc(10px + 2vmin)
            color white

          .App-link
            color #61dafb

          @keyframes App-logo-spin
            from 
              transform rotate(0deg)
            to 
              transform rotate(360deg)
        `}</style>
      </div>
    </BrowserRouter>
  );
}

const mapState = (state) =>{
  return {
    sideBar: state.store.sideBar,
  }
}

const mapDispatch = (dispatch) => {
  return {
    hideSide () {
      dispatch(actions.hideSide())
    }
  }
}

export default connect(mapState, mapDispatch)(App)
```