npm i –save-devの “–save-dev”とは?

–save-dev は、ローカルインストール
-g がグローバルインストール
-gをつけないと、ローカルインストールになる

ローカルインストールの場合は、node_modulesにパッケージがインストールされる
ローカルに入れると、package.jsonのdevDependenciesに追記される

babel + webpack

webpack.config.js

const webpack = require('webpack');

module.exports = {
    target: 'node',
    entry: `./entry.js`,

    output: {
        path: `${__dirname}/output/`,
        filename: "main.js"
    },
    module: {
        rules: [
            {
                test: /\.js$/,
                exclude: /node_modules/,
                loader: "babel-loader",
            }
        ]
    }
};

[vagrant@localhost front]$ npm run build

> @ build /home/vagrant/front
> webpack

Hash: eb8d6365b20e87793006
Version: webpack 4.41.2
Time: 421ms
Built at: 2019-11-20 13:15:11
1 asset
Entrypoint main = main.js
[0] ./entry.js 2 KiB {0} [built] [failed] [1 error]

WARNING in configuration
The ‘mode’ option has not been set, webpack will fallback to ‘production’ for this value. Set ‘mode’ option to ‘development’ or ‘production’ to enable defaults for each environment.
You can also set it to ‘none’ to disable any default behavior. Learn more: https://webpack.js.org/configuration/mode/

ERROR in ./entry.js
Module build failed (from ./node_modules/babel-loader/lib/index.js):
TypeError: /home/vagrant/front/entry.js: Cannot read property ‘bindings’ of null
at Scope.moveBindingTo (/home/vagrant/front/node_modules/@babel/traverse/lib/scope/index.js:822:13)
at BlockScoping.updateScopeInfo (/home/vagrant/front/node_modules/babel-plugin-transform-es2015-block-scoping/lib/index.js:364:17)
at BlockScoping.run (/home/vagrant/front/node_modules/babel-plugin-transform-es2015-block-scoping/lib/index.js:330:12)
at PluginPass.BlockStatementSwitchStatementProgram (/home/vagrant/front/node_modules/babel-plugin-transform-es2015-block-scoping/lib/index.js:70:24)
at newFn (/home/vagrant/front/node_modules/@babel/traverse/lib/visitors.js:179:21)
at NodePath._call (/home/vagrant/front/node_modules/@babel/traverse/lib/path/context.js:55:20)
at NodePath.call (/home/vagrant/front/node_modules/@babel/traverse/lib/path/context.js:42:17)
at NodePath.visit (/home/vagrant/front/node_modules/@babel/traverse/lib/path/context.js:90:31)
at TraversalContext.visitQueue (/home/vagrant/front/node_modules/@babel/traverse/lib/context.js:112:16)
at TraversalContext.visitSingle (/home/vagrant/front/node_modules/@babel/traverse/lib/context.js:84:19)
at TraversalContext.visit (/home/vagrant/front/node_modules/@babel/traverse/lib/context.js:140:19)
at Function.traverse.node (/home/vagrant/front/node_modules/@babel/traverse/lib/index.js:84:17)
at traverse (/home/vagrant/front/node_modules/@babel/traverse/lib/index.js:66:12)
at transformFile (/home/vagrant/front/node_modules/@babel/core/lib/transformation/index.js:119:29)
at runSync (/home/vagrant/front/node_modules/@babel/core/lib/transformation/index.js:48:5)
at runAsync (/home/vagrant/front/node_modules/@babel/core/lib/transformation/index.js:35:14)
at process.nextTick (/home/vagrant/front/node_modules/@babel/core/lib/transform.js:34:34)
at processTicksAndRejections (internal/process/task_queues.js:79:9)
npm ERR! code ELIFECYCLE
npm ERR! errno 2
npm ERR! @ build: `webpack`
npm ERR! Exit status 2
npm ERR!
npm ERR! Failed at the @ build script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.

npm ERR! A complete log of this run can be found in:
npm ERR! /home/vagrant/.npm/_logs/2019-11-20T04_15_11_600Z-debug.log

webconfigで書くのはわかったけど、なんか上手くいかんな。。

babelとは?

ブラウザにまだサポートされていないようなJSの次世代標準機能をブラウザで使えるようにするNode.jsトランスパイラ
ES6, ES7など(ECMAScript)
Bableを使う際に書くのはAltJSではなく、純粋なJavaScript

Bable ES6の構文サポート
– Class, Template Strings, Arrow Function, Default Parameter, Rest Parameter, Property Literals, Modules

class Code {
    constructor(item){
        this.item = item;
    }
    showItem(){
        console.log(`you are buying ${this.item}`);
    }
}

class Sec extends Code {
    constructor(item = 'コロプラ'){
        super(item);
    }
}

var app = new Sec();
app.showItem();

[vagrant@localhost front]$ node entry.js
you are buying コロプラ

では、早速Babelをインストールしましょう。
$ npm install -g babel-cli
$ babel entry.js –out-file output.js

あれ、全然変わってない?
presetをインストールして、.babelrcを書く必要がある??
$ npm install –save-dev babel-preset-env

.babelrc

{
   "presets": ["env"]
}

再度実行
$ babel entry.js –out-file output.js

output.js

'use strict';

var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props&#91;i&#93;; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();

function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }

function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

var Code = function () {
    function Code(item) {
        _classCallCheck(this, Code);

        this.item = item;
    }

    _createClass(Code, &#91;{
        key: 'showItem',
        value: function showItem() {
            console.log('you are buying ' + this.item);
        }
    }&#93;);

    return Code;
}();

var Sec = function (_Code) {
    _inherits(Sec, _Code);

    function Sec() {
        var item = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'コロプラ';

        _classCallCheck(this, Sec);

        return _possibleConstructorReturn(this, (Sec.__proto__ || Object.getPrototypeOf(Sec)).call(this, item));
    }

    return Sec;
}(Code);

var app = new Sec();
app.showItem();

なるほど、OK!
ES5への変換は、babel-preset-envが必要ってことね。
そんで、これ、webpackとどう連携するの?

webpack

import { increment } from './modules/increment';

console.log('before:', 0);
console.log('**increment**');
console.log('after', increment(0));

[vagrant@localhost front]$ npm run build && node ./output/main.js

> @ build /home/vagrant/front
> webpack

Hash: bd6e844b721278940d6c
Version: webpack 4.41.2
Time: 147ms
Built at: 2019-11-20 01:08:18
Asset Size Chunks Chunk Names
main.js 1.01 KiB 0 [emitted] main
Entrypoint main = main.js
[0] ./entry.js + 1 modules 193 bytes {0} [built]
| ./entry.js 143 bytes [built]
| ./modules/increment.js 50 bytes [built]

WARNING in configuration
The ‘mode’ option has not been set, webpack will fallback to ‘production’ for this value. Set ‘mode’ option to ‘development’ or ‘production’ to enable defaults for each environment.
You can also set it to ‘none’ to disable any default behavior. Learn more: https://webpack.js.org/configuration/mode/
before: 0
**increment**
after 2

使い方わかってきた^^

webpack.config.js

webpack.config.js

module.exports = {
    entry: `./src/index.js`,

    output: {
        path: `${__dirname}`,
        filename: "main.js"
    }
}

[vagrant@localhost front]$ npm run build

> @ build /home/vagrant/front
> webpack

Hash: e4eb3bfa6713e19351bb
Version: webpack 4.41.2
Time: 92ms
Built at: 2019-11-20 00:02:50
Asset Size Chunks Chunk Names
main.js 982 bytes 0 [emitted] main
Entrypoint main = main.js
[0] ./src/index.js + 1 modules 104 bytes {0} [built]
| ./src/index.js 41 bytes [built]
| ./src/sub.js 63 bytes [built]

WARNING in configuration
The ‘mode’ option has not been set, webpack will fallback to ‘production’ for this value. Set ‘mode’ option to ‘development’ or ‘production’ to enable defaults for each environment.
You can also set it to ‘none’ to disable any default behavior. Learn more: https://webpack.js.org/configuration/mode/

おおおおおおおおおおおおおおお
なるほど、webpackも必須やな

npx webpackとnpm run build

こう書けば良い
package.json

{
  "scripts": {
    "build": "webpack"
  },
  "devDependencies": {
    "webpack": "^4.41.2",
    "webpack-cli": "^3.3.10"
  }
}

すると、npx webpackと同じことがnpm run buildでできる。

[vagrant@localhost front]$ npm run build

> @ build /home/vagrant/front
> webpack

Hash: e9a08af5f50ea936c82f
Version: webpack 4.41.2
Time: 95ms
Built at: 2019-11-19 23:58:48
Asset Size Chunks Chunk Names
main.js 982 bytes 0 [emitted] main
Entrypoint main = main.js
[0] ./src/index.js + 1 modules 104 bytes {0} [built]
| ./src/index.js 41 bytes [built]
| ./src/sub.js 63 bytes [built]

WARNING in configuration
The ‘mode’ option has not been set, webpack will fallback to ‘production’ for this value. Set ‘mode’ option to ‘development’ or ‘production’ to enable defaults for each environment.
You can also set it to ‘none’ to disable any default behavior. Learn more: https://webpack.js.org/configuration/mode/

webpackとは?

WebpackはNode.jsでサーバーサイドで動かすモジュールハンドラー
-npmはJSライブラリのバージョン管理
-Bowerはフロントエンドのライブラリ管理
-Gulp:タスクランナー
-webpackはJSファイルのコーディングで手助け(JS,CSSのバンドリング)
https://webpack.js.org/

ん?npmとは違うのね。
Webpackもlessやsassのコンパイラツールのようなもの。
え?それなら、gulpはいらない??
gulpはsassのコンパイル

webpackは自分で書いたJSとライブラリのjsを一つにまとめる
JSで読み込むライブラリもまとめる
JS, CSS、画像ファイルをDataURI(base64)で一つのjsにまとめる

うん、なんかイマイチよくわからない。
複数のJSファイルをまとめられる、ってことはわかった。
Babelも用いる

とりあえず、npm initから
[vagrant@localhost front]$ npm init -y
Wrote to /home/vagrant/front/package.json:

{
“name”: “front”,
“version”: “1.0.0”,
“description”: “”,
“main”: “index.js”,
“scripts”: {
“test”: “echo \”Error: no test specified\” && exit 1″
},
“keywords”: [],
“author”: “”,
“license”: “ISC”
}

# インストール
$ npm i -D webpack webpack-cli

main.js

import { hello } from "./sub";

hello();

sub/sub.js

export function hello(){
    alert("hello method exection");
}

[vagrant@localhost front]$ npx webpack
Hash: e9a08af5f50ea936c82f
Version: webpack 4.41.2
Time: 163ms
Built at: 2019-11-19 23:43:38
Asset Size Chunks Chunk Names
main.js 982 bytes 0 [emitted] main
Entrypoint main = main.js
[0] ./src/index.js + 1 modules 104 bytes {0} [built]
| ./src/index.js 41 bytes [built]
| ./src/sub.js 63 bytes [built]

WARNING in configuration
The ‘mode’ option has not been set, webpack will fallback to ‘production’ for this value. Set ‘mode’ option to ‘development’ or ‘production’ to enable defaults for each environment.
You can also set it to ‘none’ to disable any default behavior. Learn more: https://webpack.js.org/configuration/mode/

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <script src="main.js"></script>
</head>
<body>

</body>
</html>

なんだこりゃ、あーこれか。webpackで書かれてたのか。なるほどねー
main.js

!function(e){var t={};function r(n){if(t[n])return t[n].exports;var o=t[n]={i:n,l:!1,exports:{}};return e[n].call(o.exports,o,o.exports,r),o.l=!0,o.exports}r.m=e,r.c=t,r.d=function(e,t,n){r.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:n})},r.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},r.t=function(e,t){if(1&t&&(e=r(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var n=Object.create(null);if(r.r(n),Object.defineProperty(n,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)r.d(n,o,function(t){return e[t]}.bind(null,o));return n},r.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return r.d(t,"a",t),t},r.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},r.p="",r(r.s=0)}([function(e,t,r){"use strict";r.r(t),alert("hello method exection")}]);

React.jsでカレンダー機能を作りたい

カレンダー機能の要件
– 大画面で表示用
– formのカレンダーはdate pickerを使用する

react-calendarというlibraryがあるので、これをまず試したい
https://github.com/wojtekmaj/react-calendar

Installation
Add React-Calendar to your project by executing npm install react-calendar or yarn add react-calendar.

# npmでインストール
の前に、

[vagrant@localhost calendar]$ npm -v
1.3.6
[vagrant@localhost calendar]$ node -v
v0.10.48

その前にnodeとnpmをアップグレードしたい
[vagrant@localhost calendar]$ ll /etc/yum.repos.d/ | grep node
-rw-r–r–. 1 root root 464 9月 19 14:20 2014 nodesource-el.repo
[vagrant@localhost calendar]$ cat /etc/yum.repos.d/nodesource-el.repo
[nodesource]
name=Node.js Packages for Enterprise Linux 6 – $basearch
baseurl=https://rpm.nodesource.com/pub/el/6/$basearch

removeして最新を入れたい
$ sudo yum -y remove nodejs
$ sudo rm /etc/yum.repos.d/nodesource-el.repo

$ sudo yum install https://rpm.nodesource.com/pub_11.x/el/7/x86_64/nodesource-release-el7-1.noarch.rpm
$ ls -1 /etc/yum.repos.d
$ sudo yum install nodejs -y

[vagrant@localhost calendar]$ node -v
v11.15.0
[vagrant@localhost calendar]$ npm -v
6.7.0

react-calendarインストール
npm install react-calendar

あれ、その前にもう一回React.jsとwebpackを学ばないといかんやん。
ぎゃーーーーーーー

React.js 8

function TodoHeader(props){
            const remaining = props.todos.filter(todo => {
                return !todo.isDone;
        });
            return (
                <h1>
                    My Todos
                    <span>({remaining.length}/{props.todos.length})</span>
                </h1>
            );
    }
<script type="text/babel">
        (() => {

        const todos = [];

        function TodoHeader(props) {
        const remaining = props.todos.filter(todo => {
          return !todo.isDone;
        });
            return (
                <h1>
                    <button onClick={props.purge}>Purge</button>
                    My Todos
                    <span>({remaining.length}/{props.todos.length})</span>
                </h1>
            );
    }

        function TodoItem(props){
            return (
                <li key={props.todo.id}>
                    <label>
                    <input type="checkbox"
                        checked={props.todo.isDone}
                        onChange={() => props.checkTodo(props.todo)}
                    />
                    <span className={props.todo.isDone ? 'done' : ''}>
                    {props.todo.title}
                    </span>
                    </label>
                    <span className="cmd" onClick={() => props.deleteTodo(props.todo)}>[x]</span>
                </li>
            );
    }

        function TodoList(props){
            const todos = props.todos.map(todo => {
                return(
                    <TodoItem
                        key={todo.id}
                        todo={todo}
                        checkTodo={props.checkTodo}
                        deleteTodo={props.deleteTodo}
                    />

                );
        });
            return (
                <ul>
                    {props.todos.length ? todos: <li>nothing to do</li>}
                </ul>
            );
    }
        function TodoForm(props){
            return (
                <form onSubmit={props.addTodo}>
                        <input type="text" value={props.item} onChange={props.updateItem}/>
                        <input type="submit" value="Add"/>
                </form>
            );
    }

        function getUniqueId(){
            return new Date().getTime().toString(36) + '-' + Math.random().toString(36);
    }


        class App extends React.Component {
            constructor(){
                super();
                this.state = {
                todos: todos,
                item: ''
            };
            this.checkTodo = this.checkTodo.bind(this);
            this.deleteTodo = this.deleteTodo.bind(this);
            this.updateItem = this.updateItem.bind(this);
            this.addTodo = this.addTodo.bind(this);
            this.purge = this.purge.bind(this);
        }

         purge() {
          if (!confirm('are you sure?')) {
            return;
          }

          const todos = this.state.todos.filter(todo => {
            return !todo.isDone;
          });
          this.setState({
            todos: todos
          });
        }

        addTodo(e){
            e.preventDefault();

            if(this.state.item.trim()===''){
            return;
        }

            const item = {
                id: getUniqueId(),
                title: this.state.item,
                isDone: false
        };

        const todos = this.state.todos.slice();
        todos.push(item);
        this.setState({
            todos: todos,
            item: ''
    });
    }

        deleteTodo(todo){
            if (!confirm('are you sure?')) {
                return;
        }

            const todos = this.state.todos.slice();
            const pos = this.state.todos.indexOf(todo);

            todos.splice(pos, 1);
            this.setState({
            todos: todos
        });
    }

        checkTodo(todo){
            const todos = this.state.todos.map(todo => {
            return {id: todo.id, title: todo.title, isDone: todo.isDone};
        });

        const pos = this.state.todos.map(todo=>{
            return todo.id;
    }).indexOf(todo.id);

    todos[pos].isDone = !todos[pos].isDone;
    this.setState({
        todos: todos
});
    }


            updateItem(e){
                this.setState({
                item: e.target.value
            })
        }

            componentDidUpdate(){
                localStorage.setItem('todos', JSON.stringify(this.state.todos));
        }

        componentDidMount(){
                this.setState({
                    todos: JSON.parse(localStorage.getItem('todos')) || []
            });
        }

            render(){
             return (
                <div className="container">
                    <TodoHeader
                        todos={this.state.todos}
                        purge={this.purge}
                    />
                    <TodoList
                    todos={this.state.todos}
                    checkTodo={this.checkTodo}
                    deleteTodo={this.deleteTodo}
                     />
                    <TodoForm
                        item={this.state.item}
                        updateItem={this.updateItem}
                        addTodo={this.addTodo}
                    />
                </div>
             );
        }

    }
        ReactDOM.render(
            <App/>,
            document.getElementById('root')
        );
    })();
    </script>

React.js 7

<script type="text/babel">
        (() => {

        const todos = [
            {id: 0, title: 'Task 0', isDone: false},
            {id: 1, title: 'Task 1', isDone: false},
            {id: 2, title: 'Task 2', isDone: true}
        ];

        function TodoItem(props){
            return (
                <li key={props.todo.id}>
                    <label>
                    <input type="checkbox"
                        checked={props.todo.isDone}
                        onChange={() => props.checkTodo(props.todo)}
                    />
                    <span className={props.todo.isDone ? 'done' : ''}>
                    {props.todo.title}
                    </span>
                    </label>
                </li>
            );
    }

        function TodoList(props){
            const todos = props.todos.map(todo => {
                return(
                    <TodoItem
                        key={todo.id}
                        todo={todo}
                        checkTodo={props.checkTodo}
                    />

                );
        });
            return (
                <ul>
                    {todos}
                </ul>
            );
    }


        class App extends React.Component {
            constructor(){
                super();
                this.state = {
                todos: todos
            };
            this.checkTodo = this.checkTodo.bind(this);
        }

        checkTodo(todo){
            const todos = this.state.todos.map(todo => {
            return {id: todo.id, title: todo.title, isDone: todo.isDone};
        });

        const pos = this.state.todos.map(todo=>{
            return todo.id;
    }).indexOf(todo.id);

    todos[pos].isDone = !todos[pos].isDone;
    this.setState({
        todos: todos
});
    }

            render(){
             return (
                <div>
                    <h1>My Todo</h1>
                    <TodoList
                    todos={this.state.todos}
                    checkTodo={this.checkTodo}
                     />
                </div>
             );
        }

    }
        ReactDOM.render(
            <App/>,
            document.getElementById('root')
        );
    })();
    </script>
<script type="text/babel">
        (() => {

        const todos = [
            {id: 0, title: 'Task 0', isDone: false},
            {id: 1, title: 'Task 1', isDone: false},
            {id: 2, title: 'Task 2', isDone: true}
        ];

        function TodoItem(props){
            return (
                <li key={props.todo.id}>
                    <label>
                    <input type="checkbox"
                        checked={props.todo.isDone}
                        onChange={() => props.checkTodo(props.todo)}
                    />
                    <span className={props.todo.isDone ? 'done' : ''}>
                    {props.todo.title}
                    </span>
                    </label>
                    <span className="cmd" onClick={() => props.deleteTodo(props.todo)}>[x]</span>
                </li>
            );
    }

        function TodoList(props){
            const todos = props.todos.map(todo => {
                return(
                    <TodoItem
                        key={todo.id}
                        todo={todo}
                        checkTodo={props.checkTodo}
                        deleteTodo={props.deleteTodo}
                    />

                );
        });
            return (
                <ul>
                    {todos}
                </ul>
            );
    }


        class App extends React.Component {
            constructor(){
                super();
                this.state = {
                todos: todos
            };
            this.checkTodo = this.checkTodo.bind(this);
            this.deleteTodo = this.deleteTodo.bind(this);
        }

        checkTodo(todo){
            const todos = this.state.todos.map(todo => {
            return {id: todo.id, title: todo.title, isDone: todo.isDone};
        });

        const pos = this.state.todos.map(todo=>{
            return todo.id;
    }).indexOf(todo.id);

    todos[pos].isDone = !todos[pos].isDone;
    this.setState({
        todos: todos
});
    }

            render(){
             return (
                <div className="container">
                    <h1>My Todo</h1>
                    <TodoList
                    todos={this.state.todos}
                    checkTodo={this.checkTodo}
                    deleteTodo={this.deleteTodo}
                     />
                </div>
             );
        }

    }
        ReactDOM.render(
            <App/>,
            document.getElementById('root')
        );
    })();
    </script>
function TodoList(props){
            const todos = props.todos.map(todo => {
                return(
                    <TodoItem
                        key={todo.id}
                        todo={todo}
                        checkTodo={props.checkTodo}
                        deleteTodo={props.deleteTodo}
                    />

                );
        });
            return (
                <ul>
                    {props.todos.length ? todos: <li>nothing to do</li>}
                </ul>
            );
    }


        class App extends React.Component {
            constructor(){
                super();
                this.state = {
                todos: todos
            };
            this.checkTodo = this.checkTodo.bind(this);
            this.deleteTodo = this.deleteTodo.bind(this);
        }

        deleteTodo(todo){
            if (!confirm('are you sure?')) {
                return;
        }

            const todos = this.state.todos.slice();
            const pos = this.state.todos.indexOf(todo);

            todos.splice(pos, 1);
            this.setState({
            todos: todos
        });
    }
function TodoItem(props){
            return (
                <li key={props.todo.id}>
                    <label>
                    <input type="checkbox"
                        checked={props.todo.isDone}
                        onChange={() => props.checkTodo(props.todo)}
                    />
                    <span className={props.todo.isDone ? 'done' : ''}>
                    {props.todo.title}
                    </span>
                    </label>
                    <span className="cmd" onClick={() => props.deleteTodo(props.todo)}>[x]</span>
                </li>
            );
    }

        function TodoList(props){
            const todos = props.todos.map(todo => {
                return(
                    <TodoItem
                        key={todo.id}
                        todo={todo}
                        checkTodo={props.checkTodo}
                        deleteTodo={props.deleteTodo}
                    />

                );
        });
            return (
                <ul>
                    {props.todos.length ? todos: <li>nothing to do</li>}
                </ul>
            );
    }
        function TodoForm(props){
            return (
                <form>
                        <input type="text" value={props.item} onChange={props.updateItem}/>
                        <input type="submit" value="Add"/>
                </form>
            );
    }


        class App extends React.Component {
            constructor(){
                super();
                this.state = {
                todos: todos,
                item: ''
            };
            this.checkTodo = this.checkTodo.bind(this);
            this.deleteTodo = this.deleteTodo.bind(this);
            this.updateItem = this.updateItem.bind(this);
        }

        deleteTodo(todo){
            if (!confirm('are you sure?')) {
                return;
        }

            const todos = this.state.todos.slice();
            const pos = this.state.todos.indexOf(todo);

            todos.splice(pos, 1);
            this.setState({
            todos: todos
        });
    }

        checkTodo(todo){
            const todos = this.state.todos.map(todo => {
            return {id: todo.id, title: todo.title, isDone: todo.isDone};
        });

        const pos = this.state.todos.map(todo=>{
            return todo.id;
    }).indexOf(todo.id);

    todos[pos].isDone = !todos[pos].isDone;
    this.setState({
        todos: todos
});
    }


            updateItem(e){
                this.setState({
                item: e.target.value
            })
        }

            render(){
             return (
                <div className="container">
                    <h1>My Todo</h1>
                    <TodoList
                    todos={this.state.todos}
                    checkTodo={this.checkTodo}
                    deleteTodo={this.deleteTodo}
                     />
                    <TodoForm
                        item={this.state.item}
                        updateItem={this.updateItem}
                    />
                </div>
             );
        }

    }
<script type="text/babel">
        (() => {

        const todos = [];

        function TodoItem(props){
            return (
                <li key={props.todo.id}>
                    <label>
                    <input type="checkbox"
                        checked={props.todo.isDone}
                        onChange={() => props.checkTodo(props.todo)}
                    />
                    <span className={props.todo.isDone ? 'done' : ''}>
                    {props.todo.title}
                    </span>
                    </label>
                    <span className="cmd" onClick={() => props.deleteTodo(props.todo)}>[x]</span>
                </li>
            );
    }

        function TodoList(props){
            const todos = props.todos.map(todo => {
                return(
                    <TodoItem
                        key={todo.id}
                        todo={todo}
                        checkTodo={props.checkTodo}
                        deleteTodo={props.deleteTodo}
                    />

                );
        });
            return (
                <ul>
                    {props.todos.length ? todos: <li>nothing to do</li>}
                </ul>
            );
    }
        function TodoForm(props){
            return (
                <form onSubmit={props.addTodo}>
                        <input type="text" value={props.item} onChange={props.updateItem}/>
                        <input type="submit" value="Add"/>
                </form>
            );
    }

        function getUniqueId(){
            return new Date().getTime().toString(36) + '-' + Math.random().toString(36);
    }


        class App extends React.Component {
            constructor(){
                super();
                this.state = {
                todos: todos,
                item: ''
            };
            this.checkTodo = this.checkTodo.bind(this);
            this.deleteTodo = this.deleteTodo.bind(this);
            this.updateItem = this.updateItem.bind(this);
            this.addTodo = this.addTodo.bind(this);
        }

        addTodo(e){
            e.preventDefault();

            if(this.state.item.trim()===''){
            return;
        }

            const item = {
                id: getUniqueId(),
                title: this.state.item,
                isDone: false
        };

        const todos = this.state.todos.slice();
        todos.push(item);
        this.setState({
            todos: todos,
            item: ''
    });
    }

        deleteTodo(todo){
            if (!confirm('are you sure?')) {
                return;
        }

            const todos = this.state.todos.slice();
            const pos = this.state.todos.indexOf(todo);

            todos.splice(pos, 1);
            this.setState({
            todos: todos
        });
    }

        checkTodo(todo){
            const todos = this.state.todos.map(todo => {
            return {id: todo.id, title: todo.title, isDone: todo.isDone};
        });

        const pos = this.state.todos.map(todo=>{
            return todo.id;
    }).indexOf(todo.id);

    todos[pos].isDone = !todos[pos].isDone;
    this.setState({
        todos: todos
});
    }


            updateItem(e){
                this.setState({
                item: e.target.value
            })
        }

            render(){
             return (
                <div className="container">
                    <h1>My Todo</h1>
                    <TodoList
                    todos={this.state.todos}
                    checkTodo={this.checkTodo}
                    deleteTodo={this.deleteTodo}
                     />
                    <TodoForm
                        item={this.state.item}
                        updateItem={this.updateItem}
                        addTodo={this.addTodo}
                    />
                </div>
             );
        }

    }
        ReactDOM.render(
            <App/>,
            document.getElementById('root')
        );
    })();
    </script>

各パーツをそれぞれコンポートネントとして切り分ける。