Webpack-React-Typescriptボイラープレート
どいつもこいつもcreate-react-app
しやがって...
実際のところcreate-react-app
を叩いて0からReactアプリを作る機会があんまりないので、最小構成を作っておいて、応用する形で使えるようにしておく備忘録です。
- node 12.2.0
- webpack 4.43.0
- react 16.13.1
- typescript 3.9.5
webpack, react, typescriptをそれぞれインストールします。 typescriptでreactを扱うので型定義とtypescriptをwebpackでパッキングするためのts-loaderも必要です。
npm install --save-dev webpack webpack-cli
npm install --save-dev typescript
npm install --save-dev ts-loader
npm install react react-dom @types/react @types/react-dom
package.json
のscripts
でbuild
とwatch
を叩けるようにしておきます。
{
...
"scripts": {
"build": "webpack",
"watch": "webpack -w"
},
...
}
webpack.config.js
を書きます。
webpack-scaffoldってのもありますが、これを使うのはcreate-react-app
使うのと本質的に同じなので、手動で書きます。
module.exports = {
mode: "development",
entry: "./src/index.tsx",
output: {
path: `${__dirname}/dist`,
filename: "index.js"
},
module: {
rules: [
{
test: /\.tsx?$/,
use: "ts-loader"
}
]
},
resolve: {
extensions: [".ts", ".tsx", ".js", ".jsx"]
}
};
tsconfig.json
を作成します。
npx tsc --init
tsconfig.json
のcompilerOptions.jsx
をreact
に指定してjsx内のReact構文を解釈できるようにしておきます。
{
"compilerOptions":{
...
"jsx": "react",
...
}
}
あとは適当にtsxを書くとnpm run build
でビルド可能です。
import { Component } from "react";
import React from "react";
import ReactDOM from "react-dom";
class Index extends Component{
public render(): JSX.Element{
return(
<div>Hello !!</div>
);
}
}
const app = document.createElement('div');
document.body.appendChild(app);
ReactDOM.render(<Index />, app);
+マルチページアプリケーション
ReactといえばSPAみたいなところありますが、わりとマルチページなReactアプリを構築する機会が多いので、マルチページ用のボイラープレートも追加しておきます。
webpackでhtmlをバンドルする必要があるので、html-webpack-plugin
とhtml-loader
をインストールします。
npm install --save-dev html-webpack-plugin html-loader
エントリポイントに対応するhtmlを出力するようにwebpack.config.js
を書き換えます。
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
mode: "development",
entry:{
"index": "./src/index.tsx",
"page1": "./src/page1.tsx",
},
output: {
path: `${__dirname}/dist`,
filename: "[name].js"
},
module: {
rules: [
{
test: /\.tsx?$/,
use: "ts-loader"
},
{
test: /\.html$/,
loader: "html-loader"
}
]
},
plugins:[
new HtmlWebpackPlugin({
chunks: ["index"],
filename: "index.html",
}),
new HtmlWebpackPlugin({
chunks: ["page1"],
filename: "page1.html",
}),
],
resolve: {
extensions: [".ts", ".tsx", ".js", ".jsx"]
}
};
ページが増えるたびに2箇所変更箇所があるのが嫌なところですね。
いい方法を知っていたら教えてください。