はじめに
前回、Reactを始める前に環境を整えよう/「npm/yarn」両者対応。という記事で、Reactを書き始める前段階の環境構築に関してまとめました。
その中でWebpackというものが出てきましたが、今回はそのWebpackを使って、「Hello React」をブラウザ上に表示したいと思います。
より詳しくWebpackについて知りたい方はこちらをご参考にしてみたください。
WebpackのWebサイト
Webpackて何?
Webpackとは、JavaScripやCSSなどのリソースファイルを1つにまとめたり、JSXのような特殊な記法で書かれたファイルを変換するツールです。
Webアプリ(Webサイト)は、さまざまなリソースファイルから構成されています。リソースファイルには、JavaScriptやCSSファイルなどいろいろあります。Webpackを使うと、それらを最適な形に作り替えることができます。
例えば、ホームページを作るためには、HTMLファイルだけでなく、CSSやJavaScript、画像やWebフォントなど、さまざまなファイルを用意する必要がありますよね。こうしたWebで必要なファイルをワンパッケージでまとめてくれる便利なものがWebpack
です。また、Webpackは複数のJavaScriptファイルをまとめる高機能なモジュールバンドラーであることにより、WebページのHTTPリクエストの数を減らしたりすることができます。
さらに、Webpackは、複数のファイルを1つのメインファイルにまとめてくれるだけではなく、SassやLESSなどの CSSプリプロセッサー言語をコンパイルしてくれます。
つまり、高度なWebアプリケーションを作ろうとする際に非常に役立ちます。
WebpackでReact/JSXをビルドしてみよう
早速、React/JSXをWebpackで変換する方法をご紹介します。
WebpackでReact/JSXのコンパイル環境を作る時は、次のような手順で行います。
-
yarn init
でpackage.jsonを作成する - 必要なモジュールをインストールする
- webpack.config.jsを作成する
- ソースディレクトリ
src
と出力ディレクトリout
などを作っておく。 - ソースコードを作成し、webpackコマンドでコンパイルする
- Webサーバー上でコンパイル結果を確認する
1. yarn init
でpackage.jsonを作成する
webpack-appという名前のプロジェクトを開始するとします。
$ mkdir webpack-app
$ cd webpack-app/
$ yarn init
$ ls
package.json
yarn init
実行後にはpackage.jsonが作成されていますね。
2. 必要なモジュールをインストールする
続いて、必要なモジュールをインストールします。今回インストールするモジュールは、Webpack
とReact
とBabel
の3種類です。
$ yarn add webpack webpack-dev-server react react-dom babel-core babel-loader babel-preset-react babel-preset-env
yarn add v1.12.3
info No lockfile found.
[1/4] 🔍 Resolving packages...
[2/4] 🚚 Fetching packages...
[3/4] 🔗 Linking dependencies...
warning " > babel-loader@8.0.4" has unmet peer dependency "@babel/core@^7.0.0".
[4/4] 📃 Building fresh packages...
success Saved lockfile.
success Saved 446 new dependencies.
info Direct dependencies
├─ babel-core@6.26.3
├─ babel-loader@8.0.4
├─ babel-preset-env@1.7.0
├─ babel-preset-react@6.24.1
├─ react-dom@16.6.3
├─ react@16.6.3
├─ webpack-dev-server@3.1.10
└─ webpack@4.26.0
info All dependencies
├─ @webassemblyjs/floating-point-hex-parser@1.7.11
├─ @webassemblyjs/helper-code-frame@1.7.11
...
...
✨ Done in 22.30s
$ ls
node_modules/ package.json yarn.lock
node_modules/
ディレクトリとyarn.lock
ファイルが作成されましたね。
package.jsonの中身を確認してみましょう。
{
"name": "webpack-app",
"version": "1.0.0",
"main": "index.js",
"license": "MIT",
"dependencies": {
"babel-core": "^6.26.3",
"babel-loader": "^8.0.4",
"babel-preset-env": "^1.7.0",
"babel-preset-react": "^6.24.1",
"react": "^16.6.3",
"react-dom": "^16.6.3",
"webpack": "^4.26.0",
"webpack-dev-server": "^3.1.10"
}
}
3. webpack.config.jsを作成する
変換指示書となる設定ファイルを作ります。
Webpackの機能は豊富なので、実際にWebpackを使う時は、さまざまなオプションを付けます。
しかし、コマンドラインで全てのオプションを指定するのは大変なので、通常は、webpack.config.js
という設定ファイルを作成し、これを変換指示書として利用します。
webpack.config.jsという名前で保存しておけば、コマンドラインからwebpack
とタイプするだけで変換作業を行うことができます。
$ touch webpack.config.js
以下のように編集しましょう。
module.exports = {
entry: './src/main.js',
output: {
filename: './out/bundle.js'
},
module: {
rules: [
{
test: /.js$/,
loader: 'babel-loader',
options: {
presets: ['react', 'env']
}
}
]
}
}
このモジュールのルール指定では、WebpackのBabelプラグイン(babel-loader)を利用して、ECMAScriptとReactの変換を行うよう設定します。前回の投稿を読んでくださった方はお気づきかもしれませんが、 先ほどインストールしたモジュールではbabel-preset-es2015
からbabel-preset-env
に変わっております。
babel-preset-env
とはなんぞやという方へ、
babel-preset-envとは
Babel preset that automatically determines the the Babel plugins you need based on your supported environments. Uses compat-table
と書かれています。
要するに、compat-table(ECMAScript 6 compatibility table)を用いて、サポートされている環境に基づいて必要なBabelプラグインを自動で決定するライブラリということらしいです。
便利ですね。
それでは、先ほどの設定について説明しましょう。
module: { rules: [...] }
のように書くと、どのプラグインで変換を行うかを指定することができます。
そして、プラグインを指定するオブジェクトは、次のように指定してます。
{
test: /ファイルのパターンを指定/,
loader: "どのプラグインを使うか",
options: { プラグインのオプション }
}
ファイルのパターンは、正規表現で指定します。正規表現が曖昧な方は下記投稿にまとめてますのでよかったらご参考ください。
Ruby 正規表現まとめ(基礎編)
/.js$/
と書くと拡張子.js
を持つファイルという意味になりますね。
そして、loaderの指定ですが、今回は、yarnでインストールしたbabel-loader
を使うという意味になります。そしてbabel-loaderのオプションとして、"react"と"env"を指定することで、React/JSXの変換を行うことができるようになります。
4. ソースディレクトリsrc
と出力ディレクトリout
などを作っておく。
$ mkdir src out
$ ls
node_modules/ out/ package.json src/ webpack.config.js yarn.lock
5. ソースコードを作成し、webpackコマンドでコンパイルする
まず、2つのファイルを作成します。
$ touch src/main.js src/Hello.js
$ ls src
Hello.js main.js
import React from 'react'
import ReactDOM from 'react-dom'
import {Hello} from './Hello'
ReactDOM.render(
<Hello />,
document.getElementById('root') // HTMLファイルのid=rootに描画します
)
import React from 'react'
export class Hello extends React.Component {
render() {
return <h1>Hello React!</h1>
}
}
コンパイルするとout/bundle.js
というファイルが作成されます(のちにコマンドを実行します)ので、このファイルを読み込む設定をこれから作成するHTMLファイルに記述していきます。
$ touch main.html
$ ls
main.html node_modules/ out/ package.json src/ webpack.config.js yarn.lock
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<div id="root">
</div>
<script src="out/bundle.js">
</script>
</body>
</html>
6. Webサーバー上でコンパイル結果を確認する
少しエラーが出ました。
webpack.config.js
ファイルを少し編集しましょう。+
のところを付け加えました。
module.exports = {
entry: './src/main.js',
output: {
filename: './out/bundle.js'
},
module: {
rules: [
{
test: /.js$/,
loader: 'babel-loader',
options: {
presets: ['react', 'env']
}
}
]
},
+ mode: 'development',
}
では、サーバーを起動しましょう(同時にコンパイルも行われます)。
$ ./node_modules/.bin/webpack-dev-server
ℹ 「wds」: Project is running at http://localhost:8080/
ℹ 「wds」: webpack output is served from /
ℹ 「wdm」: wait until bundle finished: /main.html
[BABEL] Note: The code generator has deoptimised the styling of "/Users/takuyanin/webpack-app/node_modules/react-dom/cjs/react-dom.development.js" as it exceeds the max of "500KB".
ℹ 「wdm」: Hash: a47d5ceabedd756af9a5
Version: webpack 4.26.0
Time: 9802ms
Built at: 11/21/2018 8:56:53 PM
Asset Size Chunks Chunk Names
./out/bundle.js 1.08 MiB main [emitted] main
Entrypoint main = ./out/bundle.js
[0] multi (webpack)-dev-server/client?http://localhost:8080 ./src/main.js 40 bytes {main} [built]
[./node_modules/ansi-html/index.js] 4.56 KiB {main} [built]
[./node_modules/ansi-regex/index.js] 139 bytes {main} [built]
[./node_modules/loglevel/lib/loglevel.js] 8.45 KiB {main} [built]
[./node_modules/react-dom/index.js] 1.32 KiB {main} [built]
[./node_modules/react/index.js] 189 bytes {main} [built]
[./node_modules/strip-ansi/index.js] 161 bytes {main} [built]
[./node_modules/url/url.js] 22.6 KiB {main} [built]
[./node_modules/webpack-dev-server/client/index.js?http://localhost:8080] (webpack)-dev-server/client?http://localhost:8080 7.78 KiB {main} [built]
[./node_modules/webpack-dev-server/client/overlay.js] (webpack)-dev-server/client/overlay.js 3.58 KiB {main} [built]
[./node_modules/webpack-dev-server/client/socket.js] (webpack)-dev-server/client/socket.js 1.05 KiB {main} [built]
[./node_modules/webpack/hot sync ^\.\/log$] (webpack)/hot sync nonrecursive ^\.\/log$ 170 bytes {main} [built]
[./node_modules/webpack/hot/emitter.js] (webpack)/hot/emitter.js 89 bytes {main} [built]
[./src/Hello.js] 2.21 KiB {main} [built]
[./src/main.js] 454 bytes {main} [built]
+ 24 hidden modules
ℹ 「wdm」: Compiled successfully.
localhost:8080/main.html
にアクセスしてHello React!
が表示されていれば成功です。
注:前回とはwebpack.config.jsの設定が異なるため、localhost:8080にアクセスしても'Hello React!'は表示されません。
以上となります。お疲れ様でした。
React関連記事
Reactを始める前に環境を整えよう/「npm/yarn」両者対応。
おわりに
上記(前回)の記事の最後に書いたように、Reactアプリを作る手順は、前回のもの(Reactを導入しないもの)と全く変わりないことがご理解いただけるでしょう。
ですので、やはり導入の段階の理解が最初の障壁になるのではと思っております。
逆に、そこを乗り越えてしまえば、Reactの書き方を学ぶことによってサクッとアプリが作れちゃいます。
何かご質問、ご指摘などございましたらコメント欄などにてお願いいたします。