JavaScript
es6
reactjs
redux

【自分専用】よく使うReact開発環境をコピペで構築

ローカル環境を構築したいときに考えながら環境作りたくないけどgithubに上げるほどでもないものをまとめました。
npmで引っ張れるやつはいいけど、フォルダやファイルをひとつひとつ作るの面倒なので、コピペで作ります。

React + BABEL + Webpack

ライブラリ

React

- react
- react-dom
- react-router-dom
yarn add react react-dom react-router-dom

Redux + React-Redux

- redux
- react-redux
- redux-actions
yarn add redux react-redux redux-actions

開発環境

build

package.json

"scripts": {
  "start": "webpack && webpack-dev-server"
}

Webpack

webpack
webpack-cli
webpack-dev-server
yarn add --dev webpack webpack-cli webpack-dev-server

BABEL

- babel-loader
- babel-core
- babel-preset-env
- babel-plugin-transform-runtime
yarn add --dev babel-loader babel-core babel-preset-env babel-plugin-transform-runtime 

React plugin

- babel-plugin-transform-react-jsx
- babel-preset-react
yarn add --dev babel-preset-react babel-plugin-transform-react-jsx

Redux-devtools

- redux-logger
yarn add --dev redux-logger

ディレクトリの作成

JavaScript

mkdir -p src/js/actions src/js/components src/js/containers src/js/reducers src/js/configureStore

Sass

mkdir -p src/sass/base src/sass/layout src/sass/module src/sass/state

ファイルの作成

JavaScript

touch src/js/app.js src/js/actions/index.js src/js/components/index.js src/js/configureStore/index.js src/js/containers/index.js src/js/reducers/index.js index.html webpack.config.js

Sass

touch src/sass/base/base.scss src/sass/layout/layout.scss src/sass/module/module.scss src/sass/state/state.scss src/sass/style.scss

ファイルにコピペ

webpack.config.js

webpack.config.js
const fs = require('fs');
const path = require('path');
const webpack = require('webpack');

const paths = {
  entry: path.join(process.cwd(), 'src', 'js'),
  output: path.join(process.cwd(), 'dist', 'js'),
};

const entry = {
  app: path.join(paths.entry, 'app.js'),
};

module.exports = {
  mode: 'development',
  entry,
  output: {
    path: paths.output,
    filename: '[name].js',
    publicPath: './',
  },
  module: {
    rules: [
      {
        test: /\.jsx$/,
        loader: 'babel-loader',
        exclude: /node_modules/,
        query: {
          plugins: ['transform-react-jsx', 'transform-runtime'],
          presets: [
            ['env', {'modules': false}],
            'react',
          ]
        }
      }
    ]
  },
  resolve: {
    modules: [
      'node_modules',
    ],
    extensions: ['json', '.jsx', '.js'],
  }
};

index.html

index.html
<!DOCTYPE html>
<html>
  <head>
    <meta charset='utf-8'>
    <title>any title</title>
    <meta name="viewport" content="width=device-width,initial-scale=1">
  </head>
  <body>
    <div id='content'></div>
  </body>
  <script src='./dist/js/app.js'></script>
</html>

app.js

app.js
import React from 'react'
import { render } from 'react-dom'
import { BrowserRouter } from 'react-router-dom'
import { Provider } from 'react-redux'
import Router from './router'
import configureStore from './configureStore'

const preloadedState = {}
const store = configureStore(preloadedState)

render(
  <Provider store={store}>
    <BrowserRouter>
      <Router />
    </BrowserRouter>
  </Provider>,
  document.getElementById('content')
)

router.js

router.js
import React from 'react'
import { Route } from 'react-router-dom'
import Awesome from './containers'

const router = () => {
  return (
    <div>
      <Route exact={true} path="/" component={Awesome}/>
    </div>
  )
}

export default router

actions

index.js
import { createAction } from 'redux-actions';

export const AWESOME_EVENT = 'AWESOME_EVENT';
export const awesomeEvent = createAction(AWESOME_EVENT);

components

index.js
import React, { Component } from 'react'

class AwesomeComponent extends Component {
  constructor(props) {
    super(props);
  }

  render() {
    return (
      <div onClick={this.props.onClickHandler}>Awesome Project</div>
    )
  }
}

export default AwesomeComponent

configureStores

index.js
import { createStore, applyMiddleware } from 'redux'
import { createLogger } from 'redux-logger'
import reducers from '../reducers'

export default function configureStore(initialState) {
  const store = createStore(
    reducers,
    initialState,
    applyMiddleware(
      createLogger()
    )
  )
  return store
}

containers

index.js
import React from 'react'
import { connect } from 'react-redux'
import AwesomeComponent from '../components'
import { awesomeEvent } from '../actions'

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

const mapDispatchToProps = (dispatch) => {
  return {
    onClickHandler: () => {
      dispatch(awesomeEvent())
    }
  }
}

const AwesomeContainer = connect(
  mapStateToProps,
  mapDispatchToProps
)(AwesomeComponent)

export default AwesomeContainer

reducers

index.js
import { combineReducers } from 'redux'
import { AWESOME_EVENT } from '../actions/'

const sampleReducer = (state = false, action) => {
  switch (action.type) {
    case AWESOME_EVENT:
      return state = !state
      break;
    default:
      return state
  }
};

const reducers = combineReducers({
  sampleReducer
});

export default reducers

Result

├── index.html
├── package.json
├── node_modules
├── src
│   └── js
│       ├── app.js
│       ├── actions
│       │   └── index.js
│       ├── components
│       │   └── index.js
│       ├── configureStore
│       │   └── index.js
│       ├── containers
│       │   └── index.js
│       └── reducers
│           └── index.js
└── webpack.config.js

build

npm start

まとめ

demoやtestしたいときにサクッと試せるので以外と便利だったりします。
あと動く最低限なので、勉強したい人にもオススメです!