目次
事前準備
HTMLを作る
<!DOCTYPE html>
<html>
<head>
<title>My Website</title>
</head>
<body>
<div id="root">
<h1>Hello, world!</h1>
</div>
</body>
</html>
React/ReactDOM Package を入れる
https://ja.legacy.reactjs.org/docs/cdn-links.html
<script src="https://unpkg.com/react@18/umd/react.production.min.js"></script>
<script src="https://unpkg.com/react-dom@18/umd/react-dom.production.min.js"></script>
正常にロードできていることを確認する
コードと画面
Transpiler(Babel)について
- Transpiler:文法(言語)変換Tool
- 最新文法(JSXを含む)のJavaScriptを旧文法のJavaScriptに変換してくれる
- ES6+ → ES5、JSX → JS、TypeScript → JavaScript
React を入れたからJSXを書いてみる
<!DOCTYPE html>
<html>
<head>
<title>My Website</title>
<script src="https://unpkg.com/react@18/umd/react.production.min.js"></script>
<script src="https://unpkg.com/react-dom@18/umd/react-dom.production.min.js"></script>
</head>
<body>
<div id="root"></div>
<script>
const App = () => {
return <h1>Hello, world!</h1>;
};
const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(<App />);
</script>
</body>
</html>
Scriptに文法エラーが出力されている
原因:Vanila JavaScriptでは認識できないコード(JSX)を書いたため
const App = () => {
const h1 = document.createElement("h1");
h1.textContent = "Hello, world!";
return h1;
};
対策:事前準備で挿入したReactを使ってJSXではない形のコードを書く
const App = () => React.createElement("h1", null, "Hello, world!");
ReactDOM.render(
React.createElement(App),
document.getElementById("root")
);
ただし、アプリケーションが大きくなるほど大変なことになる
ここで必要なのがTranspiler
JavaScriptエンジンで実行できないものを実行できるようにしてくれる。
<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
CDNからBabelを挿入する。
const App = () => <h1>Hello, world!</h1>;
ReactDOM.render(<App />, document.getElementById("root"));
その後もう一度JSXコードを書いてみると
Transpilerをちゃんと入れたのにまたSyntax Errorが出力されている
原因:BabelはまだどんなScriptをTranspileすればいいかがわからない
<script type="text/babel">
const App = () => <h1>Hello, world!</h1>;
ReactDOM.render(<App />, document.getElementById("root"));
</script>
対策:type="text/babel"を追加するとSyntaxErrorがなくなって画面が表示される
が、新しいエラーが出た
原因:TranspileをBuild時ではなく、リアルタイムで行っていること
対策:Build時にTranspileするようにする
npm install --save-dev @babel/cli @babel/core @babel/preset-react
- @babel/cli、@babel/core:Build TimeでTranspileできるようにするためのツール
- @babel/preset-react:またその際に、JSXをJSに変換できるようにするためもプリセット
- CDNから追加した@babel/standaloneにも含まれている
ディレクトリを構成して設定ファイルを追加する
1. /src/app.js を作ってHTMLのコードを移す
const App = () => <h1>Hello, world!</h1>;
ReactDOM.render(<App />, document.getElementById("root"));
2. Babelの設定ファイル .babelrc を作る
"presets": ["@babel/preset-react"]
3. npm install で生成された package.json に build スクリプトを追加する
"scripts": {
"build": "babel src --out-dir dist"
},
babel src --out-dir dist は src のファイルを dist に吐き出すという意味
4. npm run build を実行する
5. 生成された dist/app.jsを index.html に挿入する。CDNのBabelは削除する
<!DOCTYPE html>
<html>
<head>
<title>My Website</title>
<script src="https://unpkg.com/react@18/umd/react.production.min.js"></script>
<script src="https://unpkg.com/react-dom@18/umd/react-dom.production.min.js"></script>
</head>
<body>
<div id="root"></div>
<script src="dist/app.js"></script>
</body>
</html>
6. 画面が表示されるようになり、エラーも解消された
Bundler(Webpack)
全てのエラーはなくなっているが、@babel/standalone のドキュメントを見ると bundler と統合して利用することを推奨している
一般的に開発時には維持保守のためファイルを分けているが、運用時には不要なHTTPリクエストを減らすファイル数を減らすようにしている
ここでファイルを統合して数を減らしてくれるのがBundlerの役割
まずはファイル数を増やしてみる
average.js, divide.js, multiple.js, sum.js の4つのファイルを追加
### average.js
export const average = (a, b) => (a + b) / 2;
### divide.js
export const divide = (a, b) => a / b;
### multiple.js
export const multiple = (a, b) => a * b;
###sum.js
export const sum = (a, b) => a + b;
utilsフォルダーに追加した関数をapp.jsにimportする
import { average } from "../utils/average.js";
import { divide } from "../utils/divide.js";
import { multiple } from "../utils/multiple.js";
import { sum } from "../utils/sum.js";
console.log(average(1, 2));
console.log(divide(1, 2));
console.log(multiple(1, 2));
console.log(sum(1, 2));
const App = () => <h1>Hello, world!</h1>;
ReactDOM.render(<App />, document.getElementById("root"));
npm run build を実行して dist/app.js を更新するとブラウザーではまた画面が表示されなくなり、以下のエラーが表示されている
esmoduleでないところでimportを使えないということ
<script src="dist/app.js" type="module"></script>scriptタグにtype="module"をつけることで解消できたけどファイル数が多くなっている
ファイルを統合して数を減らすために
1. webpackをインストールする
npm install --save-dev webpack webpack-cli
npm install --save-dev babel-loader
webpack は依存性グラフに従ってモジュールを集めてまとめるだけなので、最新・拡張文法を理解できない。babel-loader を入れてその役割を任せる必要がある。
2. webpack.config.js を作る
const path = require("path");
module.exports = {
entry: "./src/app.js",
output: {
filename: "bundle.js",
path: path.resolve(__dirname, "dist"),
},
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: "babel-loader",
options: {
presets: ["@babel/preset-react"],
},
},
},
],
},
};
"./src/app.js" をEntry Pointとして、そこから import/requireで繋がっているすべてのモジュールを調べ、dist/bundle.jsに出力する設定
3. package.json の ビルドスクリプトを webpack に置き換える
"build": "webpack"
4. dist/app.js の代わりに webpackでビルドされた dist/bundle.js に置き換える
<script src="dist/bundle.js" type="module"></script>