Articles

Set up ES6 Project Using Babel and webpack

この記事では、Babel と webpack を使用して、(Web ブラウザで動作する)モダンな JavaScript を処理するための構築設定を作成することについて説明します。 古き良き時代には、ページにいくつかの <script> タグをドロップし、おそらく jQuery といくつかのプラグインを含めることができ、それで十分だったのです。 新しい言語機能に対するブラウザのサポートは不完全であることが多く、JavaScript アプリケーションがより野心的になるにつれて、開発者はコードを整理するためにモジュールを使用し始めました。 下のリンクからわかるように、ES6 から ES5 への変換は、サポートできるブラウザの数を劇的に増やします。

  • ES6 compatibility
  • ES5 compatibility

ビルド システムの目的は、コードをブラウザおよび実機で使用できる状態にするために必要なワークフローを自動化することです。 これには、異なる標準にコードをトランスパイルする、Sass を CSS にコンパイルする、ファイルをバンドルする、コードを最小化および圧縮する、およびその他多くのステップが含まれる場合があります。 これらが一貫して繰り返されることを確実にするために、単一のコマンドから既知のシーケンスでステップを開始するビルド システムが必要です。

前提条件

これに従うには、Node.js と npm の両方をインストールする必要があります(これらは一緒にパッケージ化されています)。 Node のインストールを管理するために、nvm などのバージョン マネージャーを使用することをお勧めします (その方法はこちら)。 これはあなたの <ROOT> フォルダーになります。

以下のように package.json ファイルを作成します:

npm init -y

注意: -y フラグはデフォルト設定でファイルを作成し、コマンドラインから通常の詳細を完了する必要がないことを意味しています。

あなたの <ROOT> フォルダー内に srcsrc/jspublic というディレクトリを作成します。 src/js フォルダーには未処理のソース コードを置き、public フォルダーにはトランスパイルされたコードが置かれます。

npm install babel-cli babel-preset-env --save-dev

これで、package.json に次のように表示されるはずです:

"devDependencies": { "babel-cli": "^6.26.0", "babel-preset-env": "^1.6.1"}

一方、package.json ファイルで scripts セクションを次のように変更してみましょう:

"scripts": { "build": "babel src -d public"},

これで、毎回ターミナルから直接ではなく、スクリプト経由で Babel を呼び出す機能が提供されることになりました。 npm スクリプトとそれができることについてもっと知りたい場合は、この SitePoint チュートリアルをチェックしてください。

最後に、Babel が動作しているかどうかをテストする前に、.babelrc 設定ファイルを作成する必要があります。

<ROOT> ディレクトリに .babelrc という名前の新しいファイルを作成し、次の内容を貼り付けます:

{ "presets": } } ] ]}

これにより、各ブラウザの最後の 2 バージョンと v7 以上の Safari に対してトランスパイルする Babel を設定することになります。 サポートする必要があるブラウザーに応じて、他のオプションも利用できます。

これで保存したので、ES6 を使用するサンプル JavaScript ファイルで物事をテストすることができるようになりました。 この記事のために、私は leftpad のコピーを変更して、テンプレート リテラル、矢印関数、const、let などの多くの場所で ES6 の構文を使用するようにしました。 それを開くと、ES6 構文はもはや含まれておらず、次のように表示されます。

Organizing Your Code with ES6 Modules

An ES6 module is a JavaScript file containing functions, objects or primitive values you want to make available to another JavaScript file. export からは別のファイルに、import からは別のファイルに利用できます。 本格的なJavaScriptプロジェクトは、モジュールの使用を考慮すべきです。 それらは、コードを自己完結したユニットに分割することを可能にし、それによって物事をより簡単に維持することができます。 執筆時点では、Chrome、Safari (最新の iOS バージョンを含む)、および Edge で利用可能で、Firefox と Opera ではフラグの後ろに隠れています。

次のセクションでは、ビルド設定にモジュールを統合する方法を見ていきます。

Export

エクスポート キーワードは、他のファイルで ES6 モジュールを利用できるようにするもので、名前付きとデフォルトという 2 つのオプションを提供します。 名前付きエクスポートを使用すると、モジュールごとに複数のエクスポートを持つことができ、デフォルトのエクスポートを使用すると、モジュールごとに 1 つだけ持つことができます。 名前付きエクスポートは、いくつかの値をエクスポートする必要がある場合に特に便利です。 たとえば、アプリケーション内のさまざまな場所で利用可能にする必要がある、多数のユーティリティ関数を含むモジュールがあるかもしれません。

では、leftPad ファイルをモジュールに変換し、それを 2 番目のファイルで要求できるようにしましょう。

Named Export

名前付きエクスポートを作成するには、以下を leftPad ファイルの一番下に追加します:

export { leftPad };

また、デフォルトでモジュールは strict モードで実行するので、ファイルの一番上の "use strict"; 宣言を削除することが可能です。

Defult Export

leftPad ファイルにエクスポートされる関数は 1 つだけなので、実際には export default を代わりに使用するのがよいでしょう。

export default function leftPad(str, len, ch) { ...}

この場合も、"use strict"; 宣言をファイルの先頭から削除できます。

Import

エクスポートされたモジュールを利用するために、今度はそれを利用したいファイル(モジュール)にインポートする必要があります。

export defaultオプションでは、エクスポートされたモジュールは、好きな名前でインポートすることができます。 たとえば、leftPad モジュールは次のようにインポートできます:

import leftPad from './leftpad';

または次のように別の名前でインポートできます:

import pineapple_fritter from './leftpad';

機能的にはどちらもまったく同じように動作しますが、エクスポートされた名前と同じか、インポートが理解できる名前にすることは明らかに理にかなっています – おそらくエクスポートした名前が受信モジュール内にすでに存在する別の変数名と衝突してしまう場合です。

名前付きエクスポート オプションの場合、エクスポートされた名前と同じ名前を使用してモジュールをインポートする必要があります。 この例のモジュールでは、export default 構文で使用したのと同様の方法でインポートしますが、この場合、インポートした名前を中括弧で囲む必要があります。

import { leftPad } from './leftpad';

名前付きエクスポートでは中括弧が必須であり、使用しないと失敗します。 export と同様に、これを行うにはさまざまな方法があり、そのすべては MDN のインポートページに詳述されています。

import { leftPad as pineapple_fritter } from './leftpad_es6';

繰り返しますが、名前の変更は少し無意味ですが、何にでも変更できるという点を説明しています。 もちろん、果物を使ったレシピを準備するルーチンを書いているのでなければ、常に良い命名習慣を保つべきです。

エクスポートされたモジュールを使用する

エクスポートされた leftPad モジュールを使用するために、私は src/js フォルダに次の index.js ファイルを作成しました。 ここでは、シリアル番号の配列をループし、その前にゼロを付けて8文字の文字列にしています。 後ほど、これを利用して、HTMLページの順序付きリスト要素に投稿します。

先ほどと同様に、<ROOT> ディレクトリからビルド スクリプトを実行します:

npm run build

これで Babel は public/js ディレクトリに index.js ファイルを作成します。 leftPad.js ファイルと同様に、Babel が ES6 構文をすべて置き換え、ES5 構文のみを残していることがわかるはずです。 また、ES6 モジュールの構文を Node ベースの module.exports に変換し、コマンドラインから実行できるようになったことにも気づくかもしれません。 前述のように、ES6 モジュールは JavaScript 開発者がコードを管理可能なチャンクに分割することを可能にしますが、その結果、それらのチャンクは要求しているブラウザに提供されなければならず、サーバーへの追加の HTTP 要求を何十回も追加する可能性があり、これは本当に避けなければならないことです。 そこで、webpack の登場です。

webpack はモジュール バンドルです。 その主な目的は、すべての依存関係を追跡することによってアプリケーションを処理し、それらをすべて 1 つまたは複数のバンドルにパッケージ化し、ブラウザで実行できるようにすることです。

webpack の設定は、4 つの主要なコンポーネントに基づいています:

  • エントリポイント
  • 出力場所
  • ローダー
  • プラグイン

エントリ。 これは webpack が依存関係を特定できるアプリケーションの開始点を保持します。

Output: 処理されたバンドルの保存場所を指定します。

ローダー。 これらは、入力としてあるものを変換し、出力として別のものを生成する方法です。 Webpack の機能を拡張して、JavaScript ファイル以外のものも扱えるようにし、それらを有効なモジュールに変換するために使用できます。 Webpack をインストールするには、<ROOT> ディレクトリから以下を実行します:

npm install webpack webpack-cli --save-dev

これにより、プロジェクトに webpack がローカルにインストールされ、webpack-cli の追加によりコマンドラインから webpack を実行する機能も提供されるようになります。 これで、package.json ファイルに webpack が表示されるはずです。 そのファイルの中で、scripts セクションを以下のように変更し、Babel を直接使用する代わりに webpack を使用するようにします:

"scripts": { "build": "webpack --config webpack.config.js"},

ご覧のように、このスクリプトは webpack.config.js ファイルを呼び出しているので、<ROOT> ディレクトリに以下の内容で作成しましょう:

これは webpack で必要となる最も簡単な設定ファイルです。 先に説明した entry と output セクションが使われているのがわかりますが (これだけでも機能します)、さらに mode: 'development' 設定も含まれています。

webpack には “development” モードと “production” モードのどちらかを選択するオプションがあります。 mode: 'development' を設定するとビルドの速度とデバッグが最適化され、mode: 'production' を設定すると実行時の実行速度と出力ファイルサイズが最適化されます。 Tobias Koppers 氏の記事「webpack 4: mode and optimization」に、モードについての良い説明がありますので、デフォルト設定以外の設定方法についてもっと読みたい方は、こちらをご覧ください。

次に、public/js フォルダからファイルをすべて削除します。

npm run build

これで、1 つの ./public/bundle.js ファイルが含まれていることがわかります。 しかし、この新しいファイルを開いてみると、最初に作った2つのファイルはかなり違って見えます。 これは index.js コードが含まれているファイルのセクションです。

<ROOT> フォルダーから node public/js/bundle.js を実行すると、以前と同じ結果が得られることがわかります。

Transpiling

前述のように、ローダーによって、あるものを別のものに変換することが可能です。 この場合、ES6 を ES5 に変換したいのです。

npm install babel-loader babel-core --save-dev

これらを利用するには、webpack.config.js の output セクションの後に、次のようにモジュール セクションを追加する必要があります:

これは、babel-loader でトランスパイルする JavaScript ファイルを識別するために正規表現を使用しますが、node_modules フォルダ内のものはそこから除外されます。 最後に、babel-loader は先にインストールされた babel-preset-env パッケージを使用し、.babelrc ファイルで設定されたトランスパイル パラメータを確立するように指示されます。

これが完了したら、これを再実行できます。

Bringing It to the Browser

機能する webpack と Babel の設定を構築したら、今度は行ったことをブラウザで表示する番です。 小さな HTML ファイルが必要で、これは次のように <ROOT> フォルダに作成する必要があります:

リストを表示するためにもう少し JavaScript が必要なので、それを実現するために ./src/js/index.js を変更しましょう。

ここで、ブラウザで index.html を開くと、次のように順序付けられたリストが表示されます:

さらに進める

上記の設定のとおり、ビルド システムはほとんど準備ができています。 webpack を使用してモジュールをバンドルし、Babel を使用して ES6 コードを ES5 にトランスパイルできます。

しかし、ES6 コードをトランスパイルするために、変更を加えるたびに npm run build を実行しなければならないのは少し困りますね。

「監視」を追加する

繰り返し npm run build を実行する必要性を克服するには、ファイルに 'watch' を設定して、webpack が ./src フォルダ内のファイルのいずれかに変更があるたびに自動的に再コンパイルするようにすればよいでしょう。 これを実装するには、package.json ファイルの scripts セクションを以下のように変更します:

"scripts": { "watch": "webpack --watch", "build": "webpack --config webpack.config.js"},

動作を確認するには、ターミナルから npm run watch を実行すると、コマンドプロンプトに戻らなくなることが確認できます。 次にsrc/js/index.jsに戻り、serNosの配列に値を追加して保存します。 私のは次のようになりました:

const serNos = ;

これでターミナルをチェックすると、ログアウトし、webpack build タスクが再実行されているのがわかります。 そしてブラウザに戻り更新すると、leftPad で処理された新しい値がリストの最後に追加されていることがわかります。

Refresh Browser Automatically

変更を加えるたびに webpack が自動的にブラウザを更新するようにできれば、今は本当に良いことだと思います。 webpack-dev-server という追加の npm パッケージをインストールすることによって、それを実現しましょう。 ただし、最初に watch タスクを Ctrl + c で終了することを忘れないでください!

npm install webpack-dev-server --save-dev

これが完了したら、新しいパッケージを呼び出す新しいスクリプトを package.json ファイルに追加してみましょう。 scripts セクションには、次のように記述します。

スクリプトの末尾に追加された --open-page フラグに注目してください。

次に npm start を実行すると、新しいブラウザ タブが で開かれ、パーツ リストが表示されるのが確認できます。 'watch'が機能していることを示すために、src/js/index.jsに移動してserNos配列の最後に別の新しい値を追加してください。

これで完了です。あとは webpack.config.js の mode を production に設定するのみです。 これが設定されると、webpack は出力するコードも ./public/js/bundle.js に Minify してくれます。 mode が設定されていない場合、webpack はデフォルトで production の設定を使用することに注意してください。

Conclusion

この記事では、最新の JavaScript 用のビルドシステムの設定方法について見てきました。 当初は、コマンドラインから Babel を使用して ES6 構文を ES5 に変換していました。 次に、export および import キーワードを使用して ES6 モジュールを使用する方法、バンドルタスクを実行するために webpack を統合する方法、およびソース ファイルの変更が検出されるたびに webpack を自動実行するためにウォッチ タスクを追加する方法について見てきました。 最後に、変更が行われるたびに自動的にページを更新するために webpack-dev-server をインストールする方法を見ました。

これをさらに進めたい場合は、SitePoint の webpack とモジュール バンドルへの深い考察を読み、webpack が Sass と資産圧縮タスクを処理するための追加のローダーとプラグインを研究することをお勧めします。 また、eslint-loader と Prettier 用のプラグインも見てください。

Happy bundling …