Webpack4でReactの環境構築。Create react appを使わずにReactアプリを作る。- 4- json-server、修正 、ESLint, Prettierの設定-
【所要時間】
8時間(2019年2月14日)
【概要】
- Webpack 4 で環境構築ができたが、よくわからってなさそうだった部分の再確認。
- json-serverとaxiosでデータベースとの通信。
- ESLint, Prettierの設定。
【要約・学んだこと】
HtmlWebpackPlugin
htmlファイルを作ってくれるプラグイン。htmlテンプレートいらないのでは?と思ったけど、Reactを読み込む <div id=”root”></div>がないとだめなので必要。HTMLにtitleをすでに書いていると、webpack.configで設定しても上書きされない。シンプルにbundle.jsを挿入するようにすればよさそう。
// public/index.html<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Build by webpack 4</title>
</head>
<body>
<p>これはHTMLで書かれている。この下にReactが表示される</p>
<div id="root"></div>
</body>
</html>
webpackの設定はtemplateファイルの場所、出力されるファイル名のみ指定すればよさそう。filenameはデフォルトと変わらないが、明示しておいたほうがわかりやすいと思うのでそのまま書く。
const HtmlWebpackPlugin = require('html-webpack-plugin');
const path = require('path');
const webpack = require('webpack');const htmlPlugin = new HtmlWebpackPlugin({
template: './public/index.html',
filename: './index.html'
});module.exports = {
mode: 'production',
entry: './src/index.js',
output: {
filename: 'bundle.js',
path: path.resolve(__dirname, 'public')
},
module: {
rules: [
...
plugins: [htmlPlugin, new webpack.HotModuleReplacementPlugin()]
};
Web-dev-server-, React-hot-loaderの設定確認
RHLがドキュメントに書かれたとおりにstateが維持されないことがあるので確認する。
が、これは解決できなかったので今回は気にしない。
json-serverのインストール・設定
実際のSPAではサーバーからデータを取得して表示することが多々あると思われる。ローカルポートからデータの取得ができるjson-serverをインストールする。
yarn add -D json-server
インストールしたらサーバーファイルを作成
// db.json{
"posts": [
{ "id": 1, "title": "json-server", "author": "typicode" },
{ "id": 2, "title": "json-bbb", "author": "aaaa" }
],
"comments": [
{ "id": 1, "body": "some ssss", "postId": 1 },
{ "id": 2, "body": "some dddd", "postId": 2 }
],
"profile": { "name": "typicode", "type": "jiji" }
}
実行する。yarn startで同時に起動できるようにscriptを修正する。json-serverを先に書いた方がいい気がするが、そうするとターミナル上でwatchが出来ないので後に書いた。支障が出てきたらscriptをわければいい。
// package.json...
"scripts": {
"start": "webpack-dev-server --hot --mode development --open | json-server --watch db.json ",
"build": "webpack --config webpack.config.js",
"eslint": "eslint \"src/**/*.{js,jsx}\"",
"stylelint": "stylelint src/**/*.*"
},...
http://localhost:3000/postsにアクセスすると下記のようになっている。
- axiosの導入
サーバーデータを取得するのにaxiosを使う。
yarn add axios
データを取得するコードを書く
// src/components/counter.jsimport React from 'react';
import axios from 'axios';// import { hot } from 'react-hot-loader';class Counter extends React.Component {
constructor(props) {
super(props);
this.state = {
number: 1,
text: []
};this.clickHandler = this.clickHandler.bind(this);
}async componentDidMount() {
try {
const getData = await axios.get('http://localhost:3000/posts');
const data = await getData.data;
this.setState({
text: data
});
} catch {
throw new Error("We couldn't get any data!!!!!");
}
}
clickHandler(e) {
const increment = this.state.number + 1;
const decrement = this.state.number - 1;
if (e.target.name === 'increment') {
this.setState({
number: increment
});
return;
}
this.setState({
number: decrement
});
}render() {
return (
<div>
<h3>{this.state.number}</h3>
<button type="button" name="increment" onClick={this.clickHandler}>
+
</button>
<button type="button" name="decrement" onClick={this.clickHandler}>
-
</button>
<ul>
{this.state.text.map(text => (
<li key={text.id}>{text.title}</li>
))}
</ul>
</div>
);
}
}export default Counter;
// export default hot(module)(Counter);
実行するとasyncに関するエラーが出た。
これによるとbabel-preset/envが問題らしい。とりあえず外してみる。
// .babelrc{
"presets": [
// "@babel/preset-env",
"@babel/preset-react"
],
"plugins": ["react-hot-loader/babel"]
}
データが取得できたが、他に影響は出ないか気になるが、そもそもreact用のプリセットをセットしているので、不要だと思われる。
元のコードの場所がわかるようにする。
console.logがcounter.jsの28行目と表示されるが、実際は21行目である。
webpack.config.jsでsource-mapのオプションを加える。
// webpack.config.js...
performance: {
hints: false
},
devtool: 'source-map',
plugins: [htmlPlugin, new webpack.HotModuleReplacementPlugin()]
};
21行目になっている。
エラーがあった場合表示しないようにする。
現在エラーがあってもdevツールにしか警告が出ない。なんかあったらすぐ気が付きたいので、ブラウザ上に表示したい。
webpack.configを修正
// webpack.config.js...devtool: 'source-map',
devServer: {
overlay: true
},
plugins: [htmlPlugin, new webpack.HotModuleReplacementPlugin()]
};
表示が黒いけどできた。
ESLintについて
問題ありそうな気がしていたが、コミットする前に全てチェックされているはずなので問題ないはず。
prettierとの設定の競合はこのコマンドで確認できる。すごい。
./node_modules/.bin/eslint --print-config . | ./node_modules/.bin/eslint-config-prettier-check
.eslintrcのplugin: prettier/recommendedを取り除くと
たくさん出てきた。
設定をairbnbスタイルにする。ついでglobalsも警告が出ないものは削除。
// .eslintrc.jsmodule.exports = {
extends: [
'airbnb',
// 'eslint:recommended',
// 'plugin:react/recommended',
'plugin:prettier/recommended',
'prettier/react'
],
parser: 'babel-eslint',
globals: {
// module: true,
document: true
// require: true,
// __dirname: true
},
plugins: ['prettier'],
rules: {
'prettier/prettier': ['error', { trailingComma: 'es5' }],
}
};
修正点であったのは
- jsではなくjsxにせよ。(jsでjsxの書式を使うな。)
→jsxに修正。それに伴いwebpackの設定も変更。 - destructing state assignmentを使え。
- imgにはaltをつけろ。
といったところ。それらを修正
webpack.config.js...devtool: 'source-map',
devServer: {
overlay: true
},
resolve: {
extensions: ['.jsx', '.js']
},
plugins: [htmlPlugin, new webpack.HotModuleReplacementPlugin()]
};
その他まとめて修正
<img src={boy} width={300} height={300} alt="boy" />this.state.number, this.state.text
→ const { number, text } = this.state;
末尾のコンマはあった方がコピペの時に楽なのでつけるようにする。
これで完成!また何かあったら随時追加、修正していこう。
【わからなかったこと】
- React-Hot-Loaderの設定。これは間違っている点もなさそうなので、おそらくバージョンアップを待つしかなさそう。現状stateを保存したいという気持ちはほぼないので問題なし。
【感想】
一通りできた感がある。よかった。create-react-appが如何に偉大かよくわかった。
最後に、ejectしたcreate-react-appのdependencies
とんでもない量のdependenciesだった。