LoginSignup
1
1

More than 3 years have passed since last update.

webpack / react / typescriptを使ったフロント環境をgithub-pagesに公開するまで

Posted at

目的

自分の携わっているサービスでreactに触れる機会があり、そこで得た知見を少しずつまとめようと思いました。どんなものを作成していたのか後で振り返りやすいようにgithub-pagesで公開して、web上から触れる設定を作ることを考えています。

この記事では、そのためのベースとするWebpack/React/TypeScript を設定して行きます。
記事のゴールとしては、React/TypeScriptを利用して書いたコードを、webpackでコンパイルしたものを出力してgithub-pagesに公開できることを目指します。

環境/前提条件

今回利用する主要なツールのバージョンは下記の通りです。
筆者はmacOSでvagrant+dockerの環境で作業しています。
vagrant+dockerの環境構築に関してはこちら

ツール名 バージョンなど
react 17.0.1
typescript 4.1.3
webpack 5.12.2

すでにnpmのインストールまでが済んでいることが前提となります。
筆者のnpm/nodeのバージョンはそれぞれ 6.14.10 / v14.15.4 を利用しました。

流れ

  • npm initでpackage.jsonを作成する
  • npmでwebpack/React/TypeScriptをインストール
  • webpack用の設定
  • TypeScript用の設定
  • index.htmlとReactを使ったsrcファイルの作成
  • webpack-dev-serverの起動とwebpackのbuildの実行
  • github-pagesへの公開

ディレクトリ構成

今回作成するファイル群のディレクトリ構成は下記となります。

root --- docs ※1
      |   ├- index.html
      |   └- index.js
      ├- src
      |   └- typescripts ※2
      |       └- main.tsx
      ├- node_modules
      ├- package.json
      ├- package-lock.json
      ├- index.html ※3
      ├- tsconfig.json
      ├- webpack.common.js
      ├- webpack.dev.js
      ├- webpack.prod.js

※1 webpackのファイルの出力先、本来ならdistとするがgithub-pagesではサブディレクトリとして利用できるのがdocsだけだったので、docsで設定
※2 今後に自分が利用する際にこの階層にstylesheetsなども配置するためこの構成としています。
※3 このファイルはindex.htmlのテンプレートファイルです。webpackから出力されたindex.htmlはこれを基に作られます。

内容

npm initでpackage.jsonを作成する

npmでwebpack/React/TypeScriptをインストール

下記のコマンドで必要なツール/プラグインをインストールします。

npm i -D webpack webpack-cli clean-webpack-plugin webpack-dev-server html-webpack-plugin typescript ts-loader

オプションの-D--save-devのエイリアスらしく、開発環境内へのインストールとして扱われます。
インストールする内容に関して簡易的な説明としては下記となります。

ツール名 バージョンなど
webpack webpackの本体です。作成したReact/TypeScriptのコードをまとめるモジュールバンドラです。
webpack-cli webpackの操作をするためのコマンドセットです。
clean-webpack-plugin webpackをbuildして出力ファイルを作った際に古いファイルや使ってないファイルを削除するプラグインです。
webpack-dev-server ローカル上でwebpackを使って開発をする際に利用する開発環境向けのwebサーバーです。
html-webpack-plugin webpackでのbuild時にindexとなるhtmlファイルも出力するためのプラグインです。これがない場合には出力ファイルはjsのみとなりページとして表示できません
typescript TypeScriptの本体です。
ts-loader webpackでtypescriptをコンパイルするために必要なloaderです。

次に下記のコマンドでインストールを実行します。

npm i -S react react-dom @types/react @types/react-dom
ツール名 バージョンなど
react Reactの本体です。
react-dom ReactでのDOM操作に利用され基本的にはreactとペアでインストールを行います。
@types/react、@types/react-dom 上記2件のTypeScriptの型定義ファイルです。

webpack用の設定

まず、webpack用のjsファイルを作成します。
ローカル上ではwebpack-dev-serverを行い、本番サーバーやgithub-pagesではコンパイル後のファイルだけあればいいので、それぞれの環境によって設定が異なります。そのため、下記の三つにファイルを分割して作成をします。

ツール名 バージョンなど
webpack.common.js 共通設定の記載用のファイル
webpack.dev.js 開発環境用のファイル、webpack-dev-serverの設定が入ります。
webpack.prod.js 本番環境用のファイル、productionという設定を入れるだけですが、デフォルトの動きでコードの圧縮などを行うようになります。

下記ではそれぞれのファイルの内容の説明をした後に

webpack.common.js

下記の内容で作成します。

const path = require('path');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin')

const htmlPlugin = new HtmlWebpackPlugin({
  template: "./index.html",
  filename: "index.html"
});

module.exports = {
  entry: './src/typescripts/index.tsx',
  plugins: [
    new CleanWebpackPlugin(),
    htmlPlugin,
  ],
  module: {
    rules: [
      {
        test: /\.tsx?$|\.ts?$/,
        use: [{
          loader: 'ts-loader',
        }],
      },
      {
        test: /\.js$/,
        exclude: /node_modules/,
        loader: 'babel-loader',
      },
    ],
  },
  resolve: {
    modules: [
      'node_modules',
      path.resolve('./src/typescripts'),
    ],
    alias: {
      tsRoot: path.resolve('./src/typescripts'),
    },
    extensions: ['.js', '.jsx', '.ts', '.tsx'],
  },
  output: {
    path: path.resolve(__dirname, './docs'),
    filename: 'index.js',
  },
};
設定項目
entry エントリーポイントの設定です。ここで設定したファイルを起点にwebpackがコンパイルをします
plugins 追加するプラグインです。
modules コンパイルする対象のファイルごとにコンパイルに利用するローダーを設定します。
resolve コンパイルの対象の設定などを行います。今回の作業の中では利用しませんが、エイリアスの設定も行って、React/Typescriptの中で絶対パスのような記載をするために利用します。
output コンパイルしたファイルの出力先の設定

webpack.dev.js

const merge = require('webpack-merge');
const common = require('./webpack.common.js');

module.exports = merge(common, {
  mode: 'development',
  devtool: 'inline-source-map',
  devServer: {
    host: '0.0.0.0',
    port: 8000,
    disableHostCheck: true,
    historyApiFallback: true,
    contentBase: './docs'
  }
});

webpack.prod.js

const merge = require('webpack-merge');
const common = require('./webpack.common.js');

module.exports = merge(common, {
  mode: 'production',
});

package.jsonにscriptを追加する

webpack-dev-serverの起動とbuildのために下記のscriptsをpackage.jsonに追記します。

watchとbuildを追記

"scripts": {
  "test": "echo \"Error: no test specified\" && exit 1",
  "watch": "webpack serve --open --config webpack.dev.js",
  "build": "webpack --config webpack.prod.js"
},

TypeScript用の設定

下記のファイルを作成します。
デフォルトの構成まではコマンドラインからも作成可能です。

outDirやBaseUrl,pathsなどをこれまでの他の設定に合わせて修正します。

{
  "compilerOptions": {
    /* Basic Options */
    "target": "es6",      /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', or 'ESNEXT'. */
    "module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */
    "jsx": "react",       /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */
    "sourceMap": true,    /* Generates corresponding '.map' file. */
    "outDir": "docs",  /* Redirect output structure to the directory. */

    /* Strict Type-Checking Options */
    "strict": true,        /* Enable all strict type-checking options. */
    "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */

    /* Module Resolution Options */
    "moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */
    "baseUrl": "./",            /* Base directory to resolve non-absolute module names. */
    "paths": {                  /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */
      "tsRoot/*": ["./src/typescripts/*"],
      "tsRoot": ["./src/typescripts"],
    },
    "esModuleInterop": true, /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */

    /* Advanced Options */
    "forceConsistentCasingInFileNames": true  /* Disallow inconsistently-cased references to the same file. */
  }
}

index.htmlとReactを使ったsrcファイルの作成

下記のファイルをそれぞれ作成します。

  • root > index.html
<!doctype html>
<html>
  <head>
    <meta charset="utf-8">
    <title>Front Component Sample ver1.0</title>
    <meta name="viewport" content="width=device-width,initial-scale=1">
  </head>

  <body>
    <div id='app'></div>
  </body>
</html>
  • root > typescripts > index.tsx
/** imports */
import * as React from 'react'
import * as ReactDOM from 'react-dom'

/** DOMへのrender */
// <div id='app'/> のコンポーネントが必要なことに注意
ReactDOM.render(
  <>render test</>,
  document.getElementById('app')
);

index.htmlファイルの <div id='app'></div> の部分にreactで書いた「render test」の文字を表示するだけのファイルです。
このファイルを使ってwebpack-dev-serverとwebpackのbuildの確認をします。

webpack-dev-serverの起動とwebpackのbuildの実行

webpack-dev-server

rootディレクトリにcdコマンドで移動して下記のコマンドを実行します

npm run watch

package.jsonに登録されたscriptが実行され、webpack-dev-serverが立ち上がります。
ブラウザで http://localhost:8000/index.htmlにアクセスして「render testと表示されるか確認して表示されればOKです。

webpackのbuild

rootディレクトリにcdコマンドで移動して下記のコマンドを実行します

mkdir docs
npm run build

root以下のdocsディレクトリにindex.htmlとindex.jsが作られていればOKです。

github-pagesへの公開

作成した内容をgithubにpushした後に、github-pagesの設定をします。

リポジトリにアクセスして下記の画面に遷移します。

settings > options

下の方にGithub Pagesの項目があるのでそこのSourceで対象のブランチとフォルダをdocsに設定します。
更新後にGithub Pagesの項目を見るとURLが発行されているので、アクセスして画面が表示されればOKです。

github-pagesにアクセスするまでに多少時間がかかるようなので注意してください。

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1