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

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

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で書くのはわかったけど、なんか上手くいかんな。。

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")}]);