Webpack-React-Typescriptボイラープレート

2020/06/21
React

どいつもこいつも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.jsonscriptsbuildwatchを叩けるようにしておきます。

{
  ...
  "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.jsoncompilerOptions.jsxreactに指定して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-pluginhtml-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箇所変更箇所があるのが嫌なところですね。
いい方法を知っていたら教えてください。

© 2019-2022 hassakulab.com, built with Gatsby