Reactアプリを構築するための基本的なWebpackとBabel設定ガイド - CRA不要の初心者向けチュートリアル

Reactアプリを構築するための基本的なWebpackとBabel設定ガイド - CRA不要の初心者向けチュートリアル

本記事は、Create-React-App(CRA)を使用せずにReactアプリを構築する方法について初心者向けに説明します。

なお、ご注意いただきたい点として、この記事を読まれる方はすでにReact.jsに精通されていることが予想されます。

そのため、React.jsについての詳細な説明は行いません。

つまり、React.jsについてはすでに知識があることを前提としています。

ご理解いただけますよう、よろしくお願いします。

事前準備と条件

当ブログの記事ではWindowsとなります。

VS Codeを使用します。

Node.js

JavascriptおよびES6からES8の構文に関する基本的な知識

React.jsの基礎に精通している

まずWebpackとは何かを理解してもらわなければいけません。

詳しくはこちらで解説しておりますので、まずはWebpackBabelの基礎知識をある程度学びこの記事にお戻り下さい。

dev-k.hatenablog.com

それではwebpackとbabelを使ってReactプロジェクトをセットアップしていく方法を解説していきます。

プロジェクト作成

プロジェクトをご準備下さい。

mkdir webpack-react

cd webpack-react

このプロジェクトwebpack-reactフォルダの直下にまた新しくフォルダの作成をします。

フォルダ名は任意でも構いません。

下記フォルダ名とし、この中で管理していきます。

mkdir react_test

cd react_test

プロジェクトの初期化をします、プロジェクトフォルダを作成しnpmを使用してプロジェクトを初期化する必要があります。

npm initではいくつかの質問をされます、そのままEnterで流すかnpm init -yで質問をスキップさせます。

npm init -y

これにより、ルートフォルダにpackage.jsonが作成されます。

プロジェクトの初期化が完了したので、Reactプロジェクト内でいくつかの必要のあるパッケージをインストールします。

npm i  react react-dom --save

npm i --save-dev webpack webpack-cli html-webpack-plugin webpack-dev-server babel-loader @babel/core @babel/preset-env 

沢山インストールしましたがどれも欠かせないものとなります。

それぞれのパッケージを1つずつ説明致します。

npm i react react-dom  --save

Reactで開発の際に欠かせないものです、JSXコードを使用してReactを記述できます。

webpack webpack-cli

Webpack 4.0以降では、コマンドライン操作用のパッケージはwebpack-cliという別パッケージで提供されておりますのでこちらをインストールします

WebpackライブラリですべてのJavaScriptコードを単一にバンドルし、アプリケーションを構築するためのものです。

html-webpack-plugin

WebpackでバンドルされたJS、HTML、CSSを表示する為に自動で生成するプラグインとなります。

設定などで独自のHTMLファイルテンプレートを指定も可能となります。

webpack-dev-server

開発目的でのみローカルWebサーバーでアプリケーションを提供するために必要となっており、リロードする機能を備えたクライアント側サーバーです。

babel-loader

WebpackでBabelを使用するのに必要なモジュールをインストールします。 

ローダーは、webpack用に構築されたNodeベースのユーティリティであり、ソースコードの変換やモジュール化をするためのツールです。

@babel/core

Babel本体のモジュールとなります。

 @babel/preset-env 

BabelがES6、ES7、およびES8コードを(ブラウザが理解できるように)ES5にコンパイル(変換)するのに役立つプリセットとなります。

Babelでは複数のモジュールをインストールし組み合わせて扱います。

Webpack用のBabel loaderには@がありません。

先頭に@が付いてるのと付いていないのがあるので気をつけて下さい。

package.jsonの設定

まず、Reactアプリを構築する前に、package.jsonの設定を行う必要があります。

package.jsonの設定は、WebpackやBabelのようなビルドツールと連携するために必要な設定であり、Reactアプリの構築に必須です。

最低限の設定として、package.jsonのオブジェクト内のscriptsに、次のようなコードを追加します。

// package.json

"scripts": {
    "start": "webpack-dev-server --mode development",
    "build": "webpack --mode production"

  },

上記の設定では、npm startまたはnpm run startで実行されるスクリプトを定義しています。

このスクリプトは、Webpackの開発用ローカルサーバーをdevelopmentモードで実行するものです。

また、npm run buildで実行されるスクリプトを定義し、このスクリプトは、Webpackを使用してアプリケーションをバンドリングするものです。

この際には、--modeオプションでproductionモードを指定します。

--modeオプションは、Webpackに現在のモードを通知するために使用されます。

このオプションを指定しなかった場合、Webpackはデフォルトでproductionモードとして動作します。

なお、Webpackを実行する際には、必ずモードの設定をするようにしてください。

Reactアプリを構築する際には、これらの設定を行うことが必要不可欠です。

Webpackの設定

WebpackはJavaScriptベースのモジュールバンドラーであり、webpack.config.jsという名前の設定ファイルを使用して、エントリーポイント、モジュール、ローダー、プラグインなどを構成します。

webpack.config.jsは、ファイル拡張子が.jsであるJavaScriptファイルであり、module.exportsオブジェクトにプロパティを定義して設定を行います。

一般的に、Webpack構成のためにwebpack.config.jsファイルをルートフォルダに追加します。

ファイル名は必ずしもこの名前である必要はありませんが、一般的にこの名前が使われます。

以下は、Webpack構成ファイルの例です。

// webpack.config.js

// pathモジュールをインポート
const path = require('path');

// HTMLファイルを生成するためのプラグインをインポート
const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
  // エントリーポイントのファイルパスを指定
  entry: path.resolve(__dirname, './src/index.js'),
  module: {
    rules: [
      // .jsまたは.jsxファイルをBabelでトランスパイルする
      {
        test: /\.(js|jsx)$/,
        exclude: /node_modules/,
        use: ['babel-loader'],
      },
    ],
  },
  // バンドルされたJavaScriptファイルの出力先を指定
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: 'bundle.js',
  },
  // 自動的に解決するファイル拡張子を指定
  resolve: {
    extensions: ['*', '.js', '.jsx'],
  },
  // HTMLを生成するためのプラグインを含む設定を行う
  plugins: [
    new HtmlWebpackPlugin({
      template: './src/index.html',
    }),
  ],
};

上記では、JavaScriptとJSXファイルをBabelローダーでトランスパイルし、バンドルされたJavaScriptファイルを「dist/bundle.js」に出力します。

さらに、HTMLファイルを生成するためにhtml-webpack-pluginを使用して、「./src/index.html」をテンプレートとして使用します。

では、これらの設定をそれぞれ個別に分割しながら、詳しく解説していきます。

// webpack.config.js

const path = require('path');

const path = require('path');は、Node.jsのpathモジュールをインポートしています。

pathモジュールは、ファイルパスを扱うための便利なメソッドを提供するために使用されます。

Webpack構成ファイルでpathモジュールを使用することで、ファイルのパスを正しく解決したり、絶対パスを取得したりすることができます。

// webpack.config.js

const HtmlWebpackPlugin = require('html-webpack-plugin');

上記のHtmlWebpackPluginはWebpackでバンドルされたJSなどを表示させるためにHTMLファイルを自動で生成させるプラグインです。

基本的にはrequire()を使用しプラグインhtml-webpack-pluginを読み込んであげます。

// webpack.config.js

entry: path.resolve(__dirname, './src/index.js'),

entryプロパティは、Webpackがバンドルする際に参照するエントリーポイントのファイルを指定するために使用されます。

上記の例では、path.resolve(__dirname, './src/index.js')を指定することで、「src/index.js」ファイルをエントリーポイントとして設定しています。

path.resolve()メソッドは、与えられたパスを絶対パスに解決するために使用されます。

__dirnameは、現在実行中のファイルが存在するディレクトリの絶対パスを表します。

つまり、path.resolve(__dirname, './src/index.js')は、「src/index.js」ファイルの絶対パスを取得して、それをWebpackのエントリーポイントとして使用しています。

Reactアプリケーションの最上位ファイルになり、アプリをDOMにレンダリングします。

ファイルは./src/index.jsを元にしてバンドルを行い、index.jsが別のJavaScriptファイルをインポートすると、それらも一緒にバンドルされます。

または任意のファイルを指定可能です。

Webpackは、エントリーポイントのファイルを読み込んで、依存するすべてのモジュールを解決し、1つのバンドルされたJavaScriptファイルにまとめます。

したがって、正しいエントリーポイントの指定は、正しいバンドルファイルの生成に重要です。

// webpack.config.js
module: {
  rules: [ 
    {
   
      test: /\.(js|jsx)$/,  
      use: ['babel-loader'],    
      exclude: /node_modules/,   
    },
  ],
},

ここの設定を詳しく知るには、Loader(ローダー)を知る必要があります。

moduleプロパティは、Webpackがバンドルするモジュールを定義するために使用されます。

rulesプロパティは、特定のファイルタイプを処理するためのローダーの設定を定義するために使用されます。

上記での、rulesプロパティには、JavaScriptファイルとJSXファイルの拡張子を持つすべてのファイルを、babel-loaderというローダーで処理するように設定しています。

ローダーは、Webpackがモジュールを読み込む際に、特定の形式のファイルを変換してからバンドルに含めるために使用されます。

例えば、babel-loaderは、ES6やJSXなどの新しいJavaScript構文を古いブラウザでも動作するように変換するために使用されます。

また、excludeプロパティには、特定のディレクトリやファイルを除外するための正規表現が指定しています。

node_modulesディレクトリ以下にあるファイルは、babel-loaderを使用して変換されないように除外されます。

ローダーは、Webpackの主要な機能であり、異なるタイプのファイルをバンドルするために非常に重要な役割を果たしています。

ローダーは、JavaScript、TypeScript、CSS、Sass、画像、フォントなど、さまざまな形式のファイルを処理するために使用されます。

また、ローダーは、モジュールのローダーとも呼ばれ、Webpackコンフィグファイルのmodule.rulesプロパティ内で定義されます。

testプロパティは、ローダーが適用されるファイルのパターンを指定します。

この場合、test: /\.(js|jsx)$/は、.jsまたは.jsx拡張子を持つファイルにローダーを適用することを示しています。

useプロパティは、指定されたファイルタイプに対して適用されるローダーを指定します。

つまり、.jsまたは.jsxファイルにbabel-loaderを適用して、ローダーは、Webpackがコンパイルする前に、ファイルを変換するために使用されます。

この設定により、ES6やJSXのような最新のJavaScript構文を古いバージョンのJavaScriptに変換できます。

この2つのプロパティ以外にも複数あり設定は複雑となっております。

本日は、Reactファイルであるjsxjsはbabelを使ってビルド致します。

// webpack.config.js

  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: 'bundle.js',
  },

outputプロパティは、Webpackが生成したファイルの設定を行う場所です。

上記の場合、pathプロパティは、出力ファイルが配置されるディレクトリのパスを指定します。

__dirnameは、現在のファイルのディレクトリを表します。

path.resolve()は、渡されたパスを結合して絶対パスを生成してくれます。

したがって、この場合では、path.resolve(__dirname, 'dist')は、現在のファイルのディレクトリにあるdistディレクトリの絶対パスを生成します。

filenameプロパティは、生成されたファイルの名前を指定し、bundle.jsという名前のファイルが出力されます。

Webpackは、エントリーポイントで指定されたファイルを基にして、すべての依存関係を解決し、出力ファイルを生成します。

ここで、outputプロパティを使用して、生成されたファイルを配置する場所と名前を指定します。

以下のオプションで指定された拡張子のファイルはimportの際に拡張子を省略することが可能となるのでこちらを設定しました。

  resolve: {
    extensions: ['*', '.js', '.jsx']
  },

resolveプロパティは、Webpackがモジュールを解決するための設定を行います。

extensionsプロパティは、Webpackが解決するファイルの拡張子を指定しています。

ここで['*', '.js', '.jsx']と指定している場合、Webpackは次の拡張子のファイルを探しに行きます。

'' (空文字列):拡張子を持たないファイル

.jsJavaScriptファイル .jsx:JSXファイル

このように、resolveプロパティを使用することで、import文内で拡張子を省略することができます。

たとえば、import App from './components/App';というコードは、App.jsxおよびApp.jsというファイルを自動的に探し出してくれます。

次の設定はHtmlWebpackPluginの設定となります。

// webpack.config.js

plugins: [
    new HtmlWebpackPlugin({
      template: './src/index.html',
    }),
  ],

pluginsプロパティは、Webpackによるビルドの際に実行するプラグインを指定するための設定です。

ここでは、HtmlWebpackPluginプラグインを使用しています。

このプラグインは、HTMLファイルを自動生成するために使用されます。

new演算子で HtmlWebpackPluginのインスタンスを生成し必要に応じて引数にオプションを指定していきます。

HtmlWebpackPluginプラグインは、templateプロパティで指定されたテンプレートファイルを元に、output.pathで指定された出力ディレクトリにHTMLファイルを生成します。

テンプレートファイルには、ビルド後のJavaScriptファイルへのリンクなどが含まれます。

このプラグインを使用することで、手動でHTMLファイルを作成する手間を省くことができます。

また、ビルド後のJavaScriptファイルの名前が変わった場合にも、自動的にHTMLファイルが更新されるため、手動でHTMLファイルを修正する必要がありません。

つまり、HtmlWebpackPluginはWebpack初心者にもおすすめのプラグインの一つです。

このプラグインを使用することで、初心者でもより効率的にWebpackを学ぶことができます。

Babelの設定

Babelの設定をしなければいけません。

.babelrcという名前のBabelファイルを生成し、以下のように記述してください。

// .babelrc

{
    "presets": [
        "@babel/preset-env",
        "@babel/react"
    ]
}

Webpack用ローダーを追加します。

Webpackには、ファイルを前処理するためにローダーと呼ばれるものが必要となります。

上記のBabelの設定は、プロジェクトでES6+やReactのコードを書くために必要な変換を行うためのものです。

具体的には、@babel/preset-envは、最新のJavaScriptの構文をES5に変換するプリセットであり、@babel/reactは、JSXをJavaScriptに変換するためのプリセットです。

これらのプリセットを使用することで、ES6+やReactのコードをより多くのブラウザで実行可能な形式に変換することができます。

これらのプリセットは、より広い範囲のブラウザで動作するようにするために必要なコード変換を自動的に行うために使用されます。

つまり、ReactはすべてJavaScriptではないため、.jsxファイルであるReact構文をサポートする必要性があります。

したがって、コードをトランスパイルするために、これら依存関係を追加してあげます。

HTMLファイルの生成

以下のように、Reactで使用するHTMLファイルを./src/index.htmlとして生成して下さい。

// index.html

<!DOCTYPE html>
<html lang="ja">
  <head>
    <meta charset="UTF-8" />
 <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Hello</title>
  </head>
  <body>
    <div id="root"></div>
  </body>
</html>

当記事では<div id="root"></div>内にReactを追加していきます。

それでは、最上位ファイルとなる、エントリポイントのindex.jsファイルを生成します。

以下ファイルがReactアプリの起点となるルートファイルとなります。

// React v17以降のルートファイル
// index.js

import React from 'react';
import { createRoot } from 'react-dom/client';
import App from './App';

const root = ReactDOM.createRoot(document.getElementById('root'));

root.render(
<React.ScriptMode>

<App />

</React.ScriptMode>
);

上記のコードは、React v18のルートファイルであり、React DOMで管理しレンダリングしています。

createRootメソッドを使用して、React DOMがレンダリングするためのルートを作成しています。

レンダリングのルートを作成して、その後に、root.render()メソッドを使用して、アプリケーションのルートコンポーネントである<App />レンダリングしています。

React.ScriptModeは、スクリプトをモードで宣言して、コンポーネントが非同期モードでレンダリングされることを示しています。

<React.ScriptMode>タグはReact v18から導入された機能で、複数のバンドルからライブラリやコードを効率的に読み込むことができるようになっています。

このルートファイルにより、React DOMがアプリケーションのエントリーポイントを理解し、アプリケーションのコンポーネント階層をレンダリングすることができます。

Reactのバージョンがv17以前の場合は、ルートファイルは異なりますので気を付けて下さい。

現在プロジェクトで使用している、Reactバージョンの確認は、package.jsonで確認ができます。

// package.json

"react": "^17.0.2",
"react-dom": "^17.0.2"

// または

"react": "^18.2.0",
"react-dom": "^18.2.0"

バージョンのダウングレードおよびアップグレードを検討する場合は当記事の以下を参考下さい。

dev-k.hatenablog.com

それでは、親コンポーネントであるReactの関数コンポーネントファイルApp.jsx作成しましょう。

// App.jsx

const App = () => {
    return(
        <div><h1>My new React App</h1></div>
    )
}

export default App;

ここまでのディレクトリ構成は以下の通りです。

/📁webpack-react
/📁react_test
 ├📁node_modules
        ├依存関係
/📁src
 ├ App.jsx
 ├ index.html
 ├ index.js
.babelrc
package.look.json
package.json
webpack.config.js
     

以下のコマンドを使用し、これまで設定してきたのがしっかり動作するか確認致します。

npm start

Webpackを使用したReactセットアップ

package.josnのscriptsで設定した"start": "webpack-dev-server --mode development",にオプションとして--openの設定を追加すればnpm start実行時に自動でブラウザが起動するようになります。

localhost: 8080で表示されてるか確認がとれましたらpackage.josnのscriptsで設定した 、"build": "webpack --mode production",

このbuildコマンドを使用します。

buildする前に開発サーバーはCTRL + Cで一度止めておきましょう。

npm run build

ビルドディレクトリの設定はoutputの設定でdistとして指定したので、buildすると自動でdistフォルダが生成されます。

このdistフォルダは公開用となります。

dist内にはHTMLファイルと1つのJSファイルとしてバンドルされたのを確認できたかと思います。

// dist/index.html

<script type="text"src='/react_test/dist/bundle.js'></script> 

これらは非常に基本的な設定ですが、ローダーとプラグインを追加して、必要に応じて設定する方法がわかります。

以下でも、基本的な設定をここよりも詳しく解説しておりますので参照下さい。

dev-k.hatenablog.com

これらをさらにご自身でカスタマイズしたい場合は、Webpackのドキュメントから詳細を確認して、その方法について得ることができます

webpack

本日は以上となります。

最後まで読んで頂きありがとうございました。

この記事が役に立ったら、ブックマークと共有していただけると幸いです。

プライバシーポリシー

© 2023 Icons8 LLC. All rights reserved.

© [deve.K], 2023. React logo is a trademark of Facebook, Inc. JavaScript is a trademark of Oracle Corporation and/or its affiliates. jQuery and the jQuery logo are trademarks of the JS Foundation. TypeScript and the TypeScript logo are trademarks of the Microsoft Corporation. Next.js and the Next.js logo are trademarks of Vercel, Inc. Firebase and the Firebase logo are trademarks of Google LLC. All logos edited by [deve.K].