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とは何かを理解してもらわなければいけません。
詳しくはこちらで解説しておりますので、まずはWebpack
とBabel
の基礎知識をある程度学びこの記事にお戻り下さい。
それでは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ファイルであるjsx
とjs
は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は次の拡張子のファイルを探しに行きます。
・ '' (空文字列)
:拡張子を持たないファイル
・ .js
:JavaScriptファイル
.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"
バージョンのダウングレードおよびアップグレードを検討する場合は当記事の以下を参考下さい。
それでは、親コンポーネントである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
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>
これらは非常に基本的な設定ですが、ローダーとプラグインを追加して、必要に応じて設定する方法がわかります。
以下でも、基本的な設定をここよりも詳しく解説しておりますので参照下さい。
これらをさらにご自身でカスタマイズしたい場合は、Webpackのドキュメントから詳細を確認して、その方法について得ることができます
本日は以上となります。
最後まで読んで頂きありがとうございました。
この記事が役に立ったら、ブックマークと共有していただけると幸いです。