React.jsでカレンダーを作ろう 5

webpack.config.jsでは、moduleの前に、outputファイルを書くらしい。

context:path.join(__dirname, "src"),
	entry: "./js/client.js",
	output: {
		path: __dirname + "/src/",
		filename: "client.min.js"
	},
	module: {
		rules: [
			{
				test: /\.css$/i,
	        	use: ['style-loader', 'css-loader'],
			},
			{
			test: /\.jsx?$/,
				exclude: /(node_modules|bower_components)/,
				use: [{
					loader: 'babel-loader',
					options: {
						presets: ['@babel/preset-react', '@babel/preset-env']
					}
				}]
		}]
	},

$ npm start

きたーーーーーーーーーーーーーーーーーーーー
stylingはmoduleのCalendar.cssを編集すれば良さそうですね。
OK、とりあえず、Caledarはこれで良し^^

React.jsでカレンダーを作ろう 4

>You may need an appropriate loader to handle this file type

githubのissueを見ると、wojtekmaj が、style-loaderを入れろ、って言ってますね。

https://github.com/wojtekmaj/react-calendar/issues/97

$ npm install –save-dev css-loader
$ npm install –save-dev style-loader

で、入れたので、
$ npm start

> .react-calendar {
| width: 350px;
| max-width: 100%;
@ ../node_modules/react-calendar/dist/entry.js 48:0-25
@ ./js/client.js

あ、webpack.config.jsに追加するのね。

rules: [
			{
				test: /\.css$/i,
	        	use: ['style-loader', 'css-loader'],
			},
			{
			test: /\.jsx?$/,
				exclude: /(node_modules|bower_components)/,
				use: [{
					loader: 'babel-loader',
					options: {
						presets: ['@babel/preset-react', '@babel/preset-env']
					}
				}]
		}]

で、再度npm start

+ 66 hidden modules
ℹ 「wdm」: Compiled successfully.

OK。あれ、何も表示されない。
なぜえええええええええええええええええええええ

React.jsでカレンダーを作ろう 3

Add @babel/plugin-proposal-class-properties (https://git.io/vb4SL) to the ‘plugins’
と出ているので、インストールします

[vagrant@localhost react]$ npm install –save-dev @babel/plugin-proposal-class-properties


.babelrcに以下を追加

{
	"plugins": [
		"@babel/plugin-proposal-class-properties"
	]
}

$ npm start

RROR in ../node_modules/react-calendar/dist/Calendar.css 1:0
Module parse failed: Unexpected token (1:0)
You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders
> .react-calendar {
| width: 350px;
| max-width: 100%;
@ ../node_modules/react-calendar/dist/entry.js 48:0-25
@ ./js/client.js
ℹ 「wdm」: Failed to compile.

何いいいいいいいいいい
諦めんぞ、俺は。

React.jsでカレンダーを作ろう 2

さて、React.js + webpack + babelの環境ができたので、カレンダーを作っていきます。

# react-calendar のインストール
$ npm install react-calendar

jsはこうかな。

import React, { Component } from "react";
import ReactDOM from "react-dom";
import Calendar from 'react-calendar';

class Layout extends Component {
	state = {
		date: new Date(),
	}

	onChange = date => this.setState({ date })

	render(){
		return (
			<div>
				<Calendar
					onChange={this.onChange}
					value={this.state.date}
				/>
			</div>
		);
	}
}

const app = document.getElementById('app');
ReactDOM.render(<Layout/>, app);

$ npm start

ERROR in ./js/client.js
Module build failed (from ../node_modules/babel-loader/lib/index.js):
SyntaxError: /home/vagrant/react/src/js/client.js: Support for the experimental syntax ‘classProperties’ isn’t currently enabled (6:8):

4 |
5 | class Layout extends React.Component {
> 6 | state = {
| ^
7 | date: new Date(),
8 | }
9 |
Add @babel/plugin-proposal-class-properties (https://git.io/vb4SL) to the ‘plugins’ section of your Babel config to enable transformation

ん? これが必要?

vagrantでwebpack-dev-server

built-in serverがwebpackにある??

[vagrant@localhost react]$ ./node_modules/webpack-dev-server/bin/webpack-dev-server.js –content-base src –mode development
ℹ 「wds」: Project is running at http://0.0.0.0:8080/
ℹ 「wds」: webpack output is served from /
ℹ 「wds」: Content not from webpack is served from /home/vagrant/react/src
ℹ 「wdm」: Hash: f58893047107846a01ed
Version: webpack 4.41.2
Time: 1464ms
Built at: 2019-11-20 18:36:59
Asset Size Chunks Chunk Names
client.min.js 1.43 MiB main [emitted] main
Entrypoint main = client.min.js
[0] multi ../node_modules/webpack-dev-server/client?http://0.0.0.0:8080 ./js/client.js 40 bytes {main} [built]
[../node_modules/ansi-html/index.js] 4.16 KiB {main} [built]
[../node_modules/html-entities/index.js] 231 bytes {main} [built]
[../node_modules/react-dom/index.js] 1.33 KiB {main} [built]
[../node_modules/react/index.js] 190 bytes {main} [built]
[../node_modules/webpack-dev-server/client/index.js?http://0.0.0.0:8080] ../node_modules/webpack-dev-server/client?http://0.0.0.0:8080 4.29 KiB {main} [built]
[../node_modules/webpack-dev-server/client/overlay.js] 3.51 KiB {main} [built]
[../node_modules/webpack-dev-server/client/socket.js] 1.53 KiB {main} [built]
[../node_modules/webpack-dev-server/client/utils/createSocketUrl.js] 2.89 KiB {main} [built]
[../node_modules/webpack-dev-server/client/utils/log.js] 964 bytes {main} [built]
[../node_modules/webpack-dev-server/client/utils/reloadApp.js] 1.59 KiB {main} [built]
[../node_modules/webpack-dev-server/client/utils/sendMessage.js] 402 bytes {main} [built]
[../node_modules/webpack-dev-server/node_modules/strip-ansi/index.js] 161 bytes {main} [built]
[../node_modules/webpack/hot sync ^\.\/log$] ../node_modules/webpack/hot sync nonrecursive ^\.\/log$ 170 bytes {main} [built]
[./js/client.js] 2.69 KiB {main} [built]
+ 29 hidden modules
ℹ 「wdm」: Compiled successfully.

あれ、vagrantでポートフォワーディングしているipを叩いても、ダメだ。
192.168.34.10:8080
なぜ?

webpack.config.jsに以下を追加

devServer: {
    contentBase: __dirname + '/public',
    host: "0.0.0.0"
	},

phpのビルトインより楽そうですね^^

npmでReact.jsの環境を作る

react-calendarがnpmなので、npmで環境を作ります。

$ npm init
$ npm install –save-dev webpack webpack-cli webpack-dev-server
$ npm install –save-dev @babel/core @babel/preset-env @babel/preset-react babel-loader

ここまでは、これまでやってきた通り

$ npm install –save-dev react react-dom
npm ERR! code ENOSELF
npm ERR! Refusing to install package with name “react” under a package

?? package.jsonのnameがreactで同じだからインストールできないとのこと
“name”: “react1” に変更して、再度実行

$ npm install –save-dev react react-dom

続いてwebpackの設定

var debug = process.env.NODE_ENV !== "production";
var webpack = require('webpack');
var path = require('path');

module.exports = {
	context:math.josin(__dirname, "src"),
	entry: "./js/client.js",
	module: {
		rules: [{
			text: /\.jsx?$/,
				exclude: /(node_modules|bower_components)/,
				use: [{
					loader: 'babel-loader',
					options: {
						presents: ['@babel/preset-react', '@babel/preset-env']
					}
				}]
		}]
	},
	output: {
		path: __dirname + "/src/",
		filename: "client.min.js"
	},
	plugins: debug ? [] : [
		new webpack.optimize.OccurrenceOrderPlugin(),
		new webpack.optimize.UglifyJsPlugin({ mangle: false, sourcemap: false}),
	]
};

./src/index.html

<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>React</title>
	<link href="https://maxcdn.bootstrapcdn.com/bootswatch/3.3.6/cosmo/bootstrap.min.css" type="text/css" rel="stylesheet"/>
</head>
<body>
	<div id="app"></div>
	<script src="client.min.js"></script>
</body>
</html>

ここまでで、Reactの環境構築完了!?

import React from "react"
import ReactDOM from "react-dom"

class Layout extends React.Component {
	render(){
		return (
			<h1>Welcome</h1>
		);
	}
}

const app = document.getElementById('app');
ReactDOM.render(<Layout/>, app);

[vagrant@localhost react]$ webpack –mode development
Hash: 12eaf7dc67869ad64caf
Version: webpack 4.41.2
Time: 1874ms
Built at: 2019-11-20 15:39:17
Asset Size Chunks Chunk Names
client.min.js 1.08 MiB main [emitted] main
Entrypoint main = client.min.js
[./js/client.js] 2.69 KiB {main} [built]
+ 11 hidden modules

何言いいいいいいいいいいいいいい

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

使い方わかってきた^^