ReactとTypeScriptで軽くクライアントを作ってみます。
コマンドをコピペして実行していけば5分程度で作れます。
下準備
ディレクトリの作成
mkdir sample_client
cd sample_client
Babel系ライブラリのインストール
トランスパイラーのライブラリを入れます。
$ yarn add -D @babel/core \
@babel/plugin-external-helpers \
@babel/plugin-proposal-class-properties \
@babel/plugin-proposal-object-rest-spread \
@babel/plugin-transform-runtime \
@babel/preset-env \
@babel/preset-react \
@babel/preset-typescript
Webpack系のライブラリのインストール
webpackやそれに関連するライブラリと各種基本的なローダー系ライブラリを入れます。
あとTypescriptとts-loaderも。
$ yarn add -D webpack \
webpack-cli \
webpack-dev-server \
webpack-hot-middleware \
html-webpack-plugin \
babel-loader \
style-loader \
css-loader \
source-map-loader \
typescript \
ts-loader
Reactのインストール
$ yarn add react \
react-dom \
@types/react \
@types/react-dom
ESLintとPrettierのインストール
$ yarn add -D eslint \
eslint-config-prettier \
eslint-plugin-prettier \
@typescript-eslint/eslint-plugin \
@typescript-eslint/parser \
prettier
webpackの設定
$ touch webpack.config.js
const path = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin')
module.exports = (env, { mode = 'development' }) => {
const config = {
mode,
entry: './src/Index.tsx',
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'bundle.js',
},
devtool: 'source-map',
resolve: { extensions: ['.js', '.jsx', '.ts', '.tsx'] },
module: {
rules: [
{
test: /\.(js|jsx|tsx|ts)$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
options: {
presets: [
'@babel/preset-env',
'@babel/preset-react',
'@babel/preset-typescript',
],
plugins: [
'@babel/plugin-transform-runtime',
'@babel/plugin-proposal-class-properties',
'@babel/plugin-proposal-object-rest-spread',
],
},
},
},
{
loader: 'source-map-loader',
test: /\.js$/,
exclude: /node_modules/,
enforce: 'pre',
},
{
test: /\.css/,
use: [
'style-loader',
{
loader: 'css-loader',
options: { url: false },
},
],
},
],
},
devServer: {
port: 3000,
},
plugins: [
new HtmlWebpackPlugin({
filename: path.resolve(__dirname, 'dist/index.html'),
template: path.resolve(__dirname, 'src/public', 'index.html'),
}),
],
}
return config
}
TypeScriptの設定
$ touch tsconfig.json
{
"extends": "./tsconfig.paths.json",
"compilerOptions": {
"outDir": "./dist/",
"sourceMap": true,
"noImplicitAny": true,
"module": "es6",
"target": "es2015",
"jsx": "react",
"strict": true,
"allowSyntheticDefaultImports": true,
"forceConsistentCasingInFileNames": true
},
"include": [
"./src/",
],
"exclude": [
"node_modules",
"dist",
],
}
extendsではエイリアスを定義することができ、別ファイルに分けて以下のように書ける(一応付け足しているが別に分けなくても良い)。
$ touch tsconfig.paths.json
{
"compilerOptions": {
"baseUrl": "./",
"paths": { "@public/*": ["./src/public/*"] }
}
}
これに加えて、webpack.config.jsを以下の部分を修正するとimportの方法を変えることができる。
module.exports = (env, { mode = 'development' }) => {
const config = {
.
.
.
resolve: {
extensions: ['.js', '.jsx', '.ts', '.tsx'],
alias: { '@public': path.resolve(__dirname, 'src/public') }, // 追加
},
.
.
.
}
}
以降./src/public
配下のファイルはimport SomeModule from '@public'
で参照することができる。
Reactコンポーネントの作成
まずReactをマウントするhtmlを作成する(webpack.config.jsのHtmlWebpackPluginのtemplateで参照するファイル)。
$ mkdir src
$ mkdir src/public
$ cd src/public
$ touch index.html
<html>
<head>
<title>SampleClient</title>
</head>
<body>
<div id='root'/>
</body>
</html>
次に、Reactのルートのファイルを作成する(webpack.config.jsのconfig.entryで指定するファイル)。
$ cd ../
$ touch Index.tsx
$ touch App.tsx
$ touch index.css
import React from 'react'
import ReactDOM from 'react-dom'
import App from './App'
ReactDOM.render(<App />, document.getElementById('root'))
Index.tsx
で読んでいるApp.tsx
を作成する。
import React from 'react'
import './index.css'
const App: React.FC = () => {
return <p>Hello, world</p>
}
export default App
body {
margin: 0px;
padding: 0px;
}
p {
color: #f05e5e;
}
あとはPresentational Component(見た目だけを扱うコンポーネント)とContainer Component(Reduxとのやり取りやロジックを扱うコンポーネント)でコンポーネントを分けて、うまい具合にApp.tsx
でReact-routerでルーティングしてあげるなど、好きに作っていきます。
ESLintとPrettierの設定
cd ../
touch .eslintrc.json
rules
のprettier/prettier
でprettierの設定を追加している。
{
"extends": [
"eslint:recommended",
"plugin:@typescript-eslint/recommended",
"plugin:@typescript-eslint/eslint-recommended",
"plugin:prettier/recommended",
"prettier/@typescript-eslint"
],
"plugins": [
"@typescript-eslint",
"prettier"
],
"parser": "@typescript-eslint/parser",
"env": { "browser": true, "node": true, "es6": true },
"parserOptions": {
"sourceType": "module"
},
"rules": {
"prettier/prettier": [
"error",
{
"trailingComma": "es5",
"tabWidth": 2,
"semi": false,
"singleQuote": true
}
],
"@typescript-eslint/explicit-function-return-type": "off",
"@typescript-eslint/array-type": [
"error",
{
"default": "array-simple"
}
],
"@typescript-eslint/no-var-requires": "off",
"@typescript-eslint/no-unused-vars": "off",
"@typescript-eslint/no-explicit-any": "off"
}
}
package.json
のscript
を追加する。
yarn start
・・・localhost:3000でクライアントを実行
yarn build
・・・dist
ディレクトリにbundle.js
を生成
format-autofix
・・・eslintとprettierでコードを整形
{
"scripts": {
"start": "webpack-dev-server --open --hot",
"build": "webpack --mode production",
"format-autofix": "eslint src --ext .ts,.tsx --fix"
},
.
.
.
}
おわり
ReduxやRedux-sagaを追加して非同期でAPI通信をしたり、
DotentやStyledComponentsを入れたりしてSPAを作っていきましょう
以下はソースコードサンプルです。
https://github.com/yutaro1204/sampleReactClient