🏢

ReactやVueのビルドで何が起こっているか

2024/09/16に公開

はじめに

Web設計はどんどん肥大化と複雑化していくもので、それに抗うための技術が発生するなどして…中々イメージが捉えづらいと思います。
本記事はそんな捉えづらい概念をご紹介していければと思います。
書いているうちに長くなってしまったので、とりあえずビルドに関係する部分をまとめました。

Node.js

Node

Node.jsとは…単にGoogle Chromeをサーバーサイドで動かしてしまおうという技術です。
今までJavaScriptはブラウザサイドで動くものとして扱ってきました。
しかしサーバーサイドで動かせるようになるということはサーバー内のファイルにJavaScriptでアクセスできる事を指します。
つまり頭の良い人はこう考えました…

  • Node.jsのおかげでJavaScriptでもライブラリを導入できるよね?
  • PHPと同じようにサーバー内のDBもアクセスできるってこと!?

大きな革命ですね。
今や当たり前になってるNode.jsですが、本当は革命的なものであることを抑えとくと
Node.jsがいかに基礎的で重要なものかわかると思います。

JavaScriptのビルド

Minify

Node.jsにより、ライブラリーを簡単に導入できるようになり勢いを増したJavaScript。
しかし、ここで大きな問題に直面します。
JavaScriptのファイル容量が多すぎ問題
ライブラリーをどんどん入れられるようになるとその分だけJavaScriptの容量が肥大化して、パフォーマンスに影響を及ぼすことになります。
ここで取った一つの戦略はJavaScriptを圧縮することです。
仕組みは難しいですが概念としては簡単です。
例えば"hogehoge"という変数を"h"と縮めたり、不要な改行やインデントを削除するだけです。

バンドル

もう一つ困ったことが発生します。
それはJavaScriptのファイルが多すぎる問題です。
これはhttp1.1の仕様ですが、1つのURL(オリジン)に対して2つのファイルを送受信できるものです。(Chromeは行儀悪く6つ)
つまり、JavaScriptを何個も受ける取ると通信的なオーバーヘッドが生まれるわけです。
このオーバーヘッドを無くすために出来るだけ無駄なく一つのファイルにまとめてしまうのがバンドルです。

bundle

参考

https://dev.to/bruno8moura/why-am-i-using-the-webpack-tool-4h14

チャンク分割

しかし、前述のバンドルで満足してしまうと特にSPAでは足枷となることになります。
HTTP1.1ではJavaScriptのファイルを出来るだけまとめてしまうことで高速化を行ってましたがHTTP2で送受信の多重化ができるようになりました。
このことで今度はJavaScriptのオーバーヘッドのほうが深刻な問題となりました。

  • JavaScriptのファイルが読み込まれるまでページを表示できない
  • ページに不要なJavaScriptもバンドルされている分、読み込みに時間がかかる

このため、次に効率良くまとまったJavaScriptを分割してしまいます。
せっかくまとめたのに

React LazyImport

const SomeComponent = lazy(load)

Vue LazyLoading

const Foo = () => import('./Foo.vue')

rollup(ビルドツール)manualchunks

({
	manualChunks: {
		lodash: ['lodash']
	}
});

他にもありますが、上記記述を駆使して効率よくJavaScriptを分割します。

まとめ

一番面倒な場合でも実は3ステップです。
使用率の多いReact、Vueをビルドする場合なので、
他のフレームワークの場合はもう少し複雑かもしれませんが。

  1. バンドル(ライブラリの依存関係を解決・整理してまとめる)
  2. チャンク分割(効率よくファイルを分ける)
  3. Minify(JavaScriptのファイルサイズを削減する)

たとえば、私の簡単なポートフォリオサイトでもチャンクを画像化すると以下になります。
これは壮観。

chunk

ECMAScriptとBabel

ECMAScript

ECMAScript

ECMAScriptとはEcma Internationalという国際的な標準化団体が制定したJavaScriptの標準規格(ECMA-262)のことを示します。
ブラウザ乱立時代、JavaScriptの仕様がブラウザごとに大きく異なりました。
そのため、ブラウザによっては誤作動が多発し、JavaScriptの信頼は地に落ちていました。
これを解決するために中立なEcma Internationalという団体により、各ブラウザのJavaScriptの仕様を統一することにしました。
現在でも以下のようにJavaScriptのエンジンは異なりますが、ECMAScriptのおかげで、昨今のJavaScriptはどのブラウザでも安定して動作するようになっています。

Web Browser Rendering Engine JavaScript Engine
Chrome Blink V8
Firefox Gecko SpiderMonkey
Safari Webkit JavaScriptCore

毎年更新されるECMAScript

EcmaScriptバージョン一覧 2024年まで

Standard Date
EcmaScript 1st June 1997
EcmaScript 2nd August 1998
EcmaScript 3rd December 1999
EcmaScript 5th December 2009
EcmaScript 5.1th June 2011
EcmaScript 2015 June 2015
EcmaScript 2016 June 2016
EcmaScript 2017 June 2017
EcmaScript 2018 June 2018
EcmaScript 2019 June 2019
EcmaScript 2020 June 2020
EcmaScript 2021 June 2021
EcmaScript 2022 June 2022
EcmaScript 2023 June 2023
EcmaScript 2024 June 2024

上記の細長い表のように
ECMAScriptは2015年以降、毎年6月にアップデートされています。
何がどう変わったのか毎年仕様を追うのがすごく大変ですね…。

Babel

Babel

毎年更新されるECMASCript。
仕事熱心なのは良いのですが、これもなかなかの弊害を生んでいます。

  • JavaScriptのエンジンが最新の規格に対応していない場合がある
  • 古いバージョンのブラウザでは最新の記法が動作しない

これを解消するJavaScriptのコンパイラーBabelが登場しました。
Babelの役割は以下になります。

  • 新しい規格の記法を古い記法に変換する
  • TypeScriptやフレームワーク特有の記法をJavaScriptに変換する

Babelは機械語に変換をするコンパイラーと異なり、
JavaScript=>JavaScriptの変換です。
人によっては同じ言語同士で変換しているのでコンパイラーと区別するために、
トランスパイラーと呼んでいる人もいるようです。
特に組み込み系のシステムでは、お客様のブラウザーが古いこともあるので、Babelを導入して、環境によるトラブルを避ける用途が期待されます。

まとめ

  • ECMAScriptのお陰でどのブラウザでも均一にJavaScriptが動作するようになった
  • ECMAScriptは毎年更新される
  • 仕様が毎年更新されるので、古い規格に変換するコンパイラーが登場した

ECMAScriptのお陰でJavaScriptは広く使われるようになりました。
しかし、毎年規格が更新されるので一部のシステムでは互換性に配慮する必要がありました。
その問題を解決するためにBabelという素晴らしい呪文が発明されることになりました。

次回予告

次回は遅延読み込みあたりをお話できればと思います。
人気が出れば出るほど私のモチベーションが上がりますので、良いなと思ったら「いいね」をお願いします!

Discussion