脳内メモリ使わずに環境構築（react）その1

`pug`や`stylus`を使う目標は叶いそうな気がするが、
もはや`create-react-app`でもない上に`Typescript`になっております。

```
mkdir react_`date '+%m%d'`
cd react_`date '+%m%d'`
git init
```
```
yarn add react react-dom styled-jsx axios immer react-app-polyfill react-router-dom react-transition-group react-redux redux redux-devtools redux-thunk node-sass styled-jsx-plugin-sass stylus stylus-loader style-loader css-loader sass-loader extract-text-webpack-plugin@4.0.0-beta.0 pug pug-loader webpack webpack-cli html-webpack-plugin babel-loader @babel/core @babel/preset-env @babel/register @babel/preset-react svg-url-loader svg-transform-loader url-loader json-loader awesome-typescript-loader @babel/cli
babel-plugin-transform-react-jsx babel-plugin-transform-react-pug @babel/preset-typescript typescript @babel/plugin-transform-typescript
```
```
yarn add @types/react @types/react-dom @types/react-redux @types/react-router-dom
```

```
touch src/App.styl
open src/App.styl
```
```src/App.styl
h1
  color: red
p
  font-size: 1.5rem
```
```
touch src/App.tsx
open src/App.tsx
```
```src/App.tsx
import React from "react"
import {render} from "react-dom"
import './App.styl'
class App extends React.Component {
  render() {
    return(
      <p> Hello React!</p>
    )
  }
}

render(
  <App/>,
  document.getElementById('app')
);
```

```
touch src/index.pug
open src/index.pug
```
```src/index.pug
doctype html
html
  head
    title React + pug + stylus
  body(style="margin:0;")
    #app
```
```
touch webpack.config.js
open webpack.config.js
```
```
require("@babel/register");
module.exports = require('./development');
```

```
touch .babelrc
open .babelrc
```
```.babelrc
{
  "presets": [
    "@babel/preset-env",
    "@babel/preset-react",
    "@babel/preset-typescript"
  ],
  "plugins": [
    "transform-react-pug",
    "transform-react-jsx",
    "@babel/plugin-transform-typescript"
  ]
}
```
```
touch development.js
open development.js
```
```development.js
import path from 'path'
import HtmlWebpackPlugin from 'html-webpack-plugin'
const ast = path.resolve(__dirname, 'src')
const pub = path.resolve(__dirname, 'public')
export default {
  mode: 'development',
  entry: `${ast}/App.jsx`,
  output: {
    path: pub,
    filename: 'js/bundle.js'
  },
  module: {
    rules: [
      {
        test: /\.js(x?)$/,
        exclude: /node_modules/,
        loader: 'babel-loader'
      },
      {
        test: /\.tsx?$/,
        use: [
            {
                loader: 'babel-loader',
            },
            {
                loader: 'awesome-typescript-loader'
            }
        ],
        exclude: /node_modules/,
      },
      {
        test: /\.pug$/,
        loader: 'pug-loader'
      },
      {
        test: /\.scss$/,
        include: path.appSrc,
        exclude: /node_modules/,
        use: ExtractTextPlugin.extract({
          fallback: require.resolve('style-loader'),
          use:[
            {loader: require.resolve('css-loader'),
              options: {
                importLoaders: 1,
                sourceMap: true,
                modules: true,
              }
            },
            {loader: require.resolve('sass-loader'),
              options: {
                sourceMap: true
              }
            }
          ]
        })
      },
    ]
  },
  resolve: {
    extensions: ['.js','.jsx','.tsx','.styl','.scss'],
  },
  plugins: [
    new HtmlWebpackPlugin({
      template: `${ast}/index.pug`,
      filename: 'index.html'})
  ],
  devServer: {
    stats: {
      builtAt: false,
      children: false,
      modules: false,
      version: false
    }
  },
}
```
```
touch ts.config.json
open ts.config.json
```
```ts.config.json
{
  "compilerOptions": {
    "target": "es5",
    "lib": [
      "dom",
      "dom.iterable",
      "esnext"
    ],
    "allowJs": true,
    "skipLibCheck": true,
    "esModuleInterop": true,
    "allowSyntheticDefaultImports": true,
    "strict": true,
    "forceConsistentCasingInFileNames": true,
    "module": "esnext",
    "moduleResolution": "node",
    "resolveJsonModule": true,
    "isolatedModules": true,
    "noEmit": true,
    "jsx": "react"
  },
  "include": [
    "src"
  ]
}
```
```
touch react-app-env.d.ts
open react-app-env.d.ts
```
```react-app-env.d.ts
/// <reference types="react-scripts" />
```
```
touch src/custom.d.ts
open src/custom.d.ts
```
```src/custom.d.ts
declare module "*.svg" {
  const content: string;
  export default content;
}
```

```
open src/App.tsx
```
```src/App.tsx
import React,{Fragment} from "react"
import { connect } from 'react-redux'
import logo from './logo.svg';
import {render} from "react-dom"
import { BrowserRouter }  from 'react-router-dom'
import { actions } from './store'
import './App.styl'

class App extends React.Component {
  render() {
    return(
      <Fragment>
        <BrowserRouter>
          <header className="App-header">
            <img src={logo} className="App-logo" alt="logo" />
            <p>
              Edit <code>src/App.tsx</code> and save to reload.
            </p>
            <a
              className="App-link"
              href="https://reactjs.org"
              target="_blank"
              rel="noopener noreferrer"
            >
              Learn React
            </a>
          </header>
        </BrowserRouter>
      </Fragment>
    )
  }
}

render(
  <App/>,
  document.getElementById('app')
);
```
pugを使う場合は

```src/App.tsx
/* eslint-disable import/first */
declare const pug: any;
//（中略）
render(){
  return pug`
  `;
```


package.jsonを見直す

```
open package.json
```
```package.json
{
  "name": "react_0306",
  "version": "0.1.0",
  "private": true,
  "dependencies": {
    "@babel/cli": "^7.8.4",
    "@babel/core": "^7.8.7",
    "@babel/plugin-transform-typescript": "^7.8.7",
    "@babel/preset-env": "^7.8.7",
    "@babel/preset-react": "^7.8.3",
    "@babel/preset-typescript": "^7.8.3",
    "@babel/register": "^7.8.6",
    "@types/react": "^16.9.23",
    "@types/react-dom": "^16.9.5",
    "@types/react-redux": "^7.1.7",
    "@types/react-router-dom": "^5.1.3",
    "awesome-typescript-loader": "^5.2.1",
    "axios": "^0.19.2",
    "babel-loader": "^8.0.6",
    "babel-plugin-transform-react-jsx": "^6.24.1",
    "babel-plugin-transform-react-pug": "^7.0.1",
    "babel-preset-env": "^1.7.0",
    "babel-preset-react": "^6.24.1",
    "css-loader": "^3.4.2",
    "extract-text-webpack-plugin": "4.0.0-beta.0",
    "html-webpack-plugin": "^3.2.0",
    "immer": "^6.0.1",
    "json-loader": "^0.5.7",
    "node-sass": "^4.13.1",
    "pug": "^2.0.4",
    "pug-loader": "^2.4.0",
    "react": "^16.13.0",
    "react-app-polyfill": "^1.0.6",
    "react-dom": "^16.13.0",
    "react-redux": "^7.2.0",
    "react-router-dom": "^5.1.2",
    "react-transition-group": "^4.3.0",
    "redux": "^4.0.5",
    "redux-devtools": "^3.5.0",
    "redux-thunk": "^2.3.0",
    "sass-loader": "^8.0.2",
    "style-loader": "^1.1.3",
    "styled-jsx": "^3.2.4",
    "styled-jsx-plugin-sass": "^1.0.0",
    "stylus": "^0.54.7",
    "stylus-loader": "^3.0.2",
    "svg-transform-loader": "^2.0.8",
    "svg-url-loader": "^4.0.0",
    "typescript": "^3.8.3",
    "url-loader": "^3.0.0",
    "webpack": "^4.42.0",
    "webpack-cli": "^3.3.11",
    "webpack-dev-server": "^3.10.3"
  },
  "scripts": {
    "start": "webpack-dev-server",
    "build": "webpack",
    "test": "",
    "transpile": "babel src/App.tsx --out-file App.js"
  }
}
```
```
yarn start
```
####参考資料
https://qiita.com/0ceanMoo/items/da61364a9719de1d3436
https://qiita.com/tathuhi10/items/c908f890939797e6bcf3
https://qiita.com/TakuyaHara/items/f560d34aaa7857b32c82
https://stackoverflow.com/questions/44717164/unable-to-import-svg-files-in-typescript
https://qiita.com/markey/items/134386ee98b277f181f7