【React】Reactに爆速で入門する4。Webpackを使ってバンドルする

Youtubeでもレブル250/グラディウス400/GN125の情報を発信してます! (登録してもらえると超喜びます!!)

はじめに

Reactに爆速で入門する1~3までで、React自体に対する理解はできてきました。(第1回はこちら)
しかし、入門1~3では、1つのファイルで、しかもReactやBabelの読み込みをscriptタグでCDNで行っていました。

実際のフロントエンド開発においては、この方式はまず採用されていなくて、大体はWebpackやBrowserifyやらを使用して、トランスパイル&バンドルするのが一般的ですよね。

ということで、今回は現状最も人気があると思われる(主観)Webpackを使用して、第3回までに作ったファイルを分割して見やすく、その分割したファイルをトランスパイル&バンドルするということをやっていこうと思います。

ベースは第3回のリスト表示するコードになりますので、コードを取得していない方はもってきてください。

また、npmを使用するので、とりあえずnodeをインストールしてください。公式ページからDLできます。

必要なプラグインをインストールする

とりあえず、npm initします。

 

[text] npm init -y
[/text]

次に、ReactとWebpackとBabelをインストールします。

[text] npm install –save react react-dom
[/text] [text] npm install –save-dev babel-core babel-loader babel-preset-es2015 babel-preset-react webpack
[/text]

 

結果のpackage.jsonは下記のような感じになっていると思います。(webpack-dev-serverは除く)

[text] {
"name": "react-minimal",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"production": "webpack -p",
"dev": "webpack -d",
"watch": "webpack -d –watch",
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {
"react": "^16.2.0",
"react-dom": "^16.2.0"
},
"devDependencies": {
"babel-core": "^6.26.0",
"babel-loader": "^7.1.2",
"babel-preset-es2015": "^6.24.1",
"babel-preset-react": "^6.24.1",
"babel-preset-react-hmre": "^1.1.1",
"webpack": "^3.9.1",
"webpack-dev-server": "^2.9.5"
}
}

[/text]

WebpackとBabelの設定ファイルを作る

さて、使用する色々なもののインストールが完了したら、webpackとbabelの設定フィルをつくります。

webpackの設定ファイル

webpack.config.jsとしてルートに配置します。とりあえずはコピペでokです。

[text] const path = require(‘path’);

module.exports = {
context: path.resolve(__dirname, ‘src’),
entry: {
js: ‘./main.js’
},
output: {
path: path.resolve(__dirname, ‘dist’),
filename: ‘bundle.[name]’,
},
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
loader: ‘babel-loader’,
query: {
presets: [‘react’, ‘es2015’] },
}
] },
plugins: [
],
devServer: {
contentBase: ‘./dist/’,
port: 8080,
inline: true,
historyApiFallback: true,
clientLogLevel: "info",
stats: { colors: true }
}
};
[/text]

srcフォルダのmain.jsを起点としてjsファイルを探していき、出力はdistフォルダ以下にbundle.jsとしてね、的な感じのことを書いてあります。

babelの設定ファイル

.babelrcとしてルートに配置します。

[text] {
"presets": ["es2015", "react"] }
[/text]

 

前回作成したファイルを分割する

第3回で作成したindex.htmlをコンポーネントごとに分割していきましょう。
index.htmlは、/dist/index.htmlとして配置し、それ以外のファイルは/src/以下に配置してください。

/dist/index.html

まずはindex.htmlを。もともとこのファイルに全てがつめこまれていましたが、下記の通りwebpackから生成されるbundle.jsを読み込む部分1つ残して、残り全てはクリアしてしまいます。

[html] <html lang="ja">
<head>
<meta charset="UTF-8" />
</head>
<body>
<div id="app"></div>

<script src="./bundle.js"></script>
</body>
</html>
[/html]

/src/main.js

エントリポイントとしてwebpack.config.jsに記述したmain.jsを作ります。
第3回のindex.htmlの、class定義部以外の全てをここにコピーする感じです。

また、React, ReactDOMのimportを忘れずに、また、ListAppをRenderしますのでListAppのimportも行います。

ListAppやMyListコンポーネントは、/src/components/に配置する予定ですのでListAppの読み込み先は./components/ListAppにします。

[javascript] import React from ‘react’;
import ReactDOM from ‘react-dom’;
import ListApp from "./components/ListApp";

var my_items = [
{
name: "hoge",
text: "this is hoge text"
},
{
name: "foo",
text: "I’m foo"
},
{
name: "bar",
text: "this is bar"
}
];

ReactDOM.render(
<ListApp items={my_items} />,
document.getElementById("app")
);
[/javascript]

/src/components/ListApp.js

ListAppもmain.jsと同じで、React関連の読み込みとMyListの読み込みをします。
main.jsから参照されますので、export defaultでclass自体をexportするのを忘れずに。

[javascript] import React from ‘react’;
import ReactDOM from ‘react-dom’;
import MyList from "./MyList"

export default class ListApp extends React.Component {

constructor(props){
super(props);

this.state = {
items: props.items
};
}

render(){
return(
<div>
<h3>List App</h3>
<div>
<input id="ListApp-name" placeholder="name" />
<input id="ListApp-text" placeholder="text" />
<button onClick={this.handleClick.bind(this)}>add</button>
<MyList items={this.state.items} />
</div>
</div>
)
}

handleClick(event){
this.setState({
items: this.state.items.concat({
name: document.getElementById("ListApp-name").value,
text: document.getElementById("ListApp-text").value
})
});
}
}
[/javascript]

 /src/components/MyList.js

MyList.jsは特筆すべきところはないですね。他と同じです。

[javascript] import React from ‘react’;
import ReactDOM from ‘react-dom’;

export default class MyList extends React.Component{
constructor(props){
super(props);
}

render(){
return(
<ul>
{
this.props.items.map((v, i)=> {
return (
<li key={i}>
<p>name:{v.name}</p>
<p>text:{v.text}</p>
</li>
)
})
}
</ul>
)
}
}
[/javascript]

これでファイル分割の準備が完了しました。

ここまでで、ファイル構成は下記のようになっているはずです。

  • /
    • /src
      • /components
        • ListApp.js
        • MyList.js
      • main.js
    • /dist
      • index.html
    • package.json
    • webpack.config.js
    • .babelrc

ビルドする

ビルド用に、下記のコマンドをscriptsに追記します。

[text] "scripts": {<span data-mce-type="bookmark" style="display: inline-block; width: 0px; overflow: hidden; line-height: 0;" class="mce_SELRES_start"></span>
"production": "webpack -p",
"dev": "webpack -d",
"watch": "webpack -d –watch",
"test": "echo \"Error: no test specified\" && exit 1"
},
[/text]

それでは、webpackによるトランスパイル&バンドルの動作確認します。

ルートで下記のコマンドを叩きます。

[text] npm run dev
[/text]

成功すれば、/dist/bundle.jsが生成されているはずです。

そして、/dist/index.htmlを開くと下記のように第3回と同じものが表示されます。

これでやっとモダンなフロントエンド開発に近づいてきました。

今回は以上です!

 

Youtubeでもレブル250/グラディウス400/GN125の情報を発信してます! (登録してもらえると超喜びます!!)
最新情報をチェックしよう!