ES6とWebpackとbabel-loaderで開発環境を構築する方法

今回はES6とWebpackとbabel-loaderで開発環境を構築する方法を紹介します。

webpack はjsやcssなど、webページで読み込まれる部品の依存関係を整理し、合成してくれるモジュールバンドラーです。

また、Webpackと一緒によく使われるgulpなどは今回は使用しません。

 

今回作成するプロジェクトは以下の条件を満たすものです。

  • classを継承できる
  • classをimportして使用できる
  • IE11が対応していない、ES6のPromiseを使うことができる

 

開発環境はMac OS High Sierra、Webpackはバージョン4.2です。

 

Node.jsをインストール

プロジェクトに必要なパッケージはnpm(Node Package Manager)でインストールできます。

なのでまずはNode.jsをインストールしましょう。homebrewでインストールするのが簡単ですね。

brew install node

 

これでNode.jsをインストールできたので、npmが使えるようになります。

 

プロジェクトを作成

プロジェクトを作成する前にディレクトリ構成について確認しておきます。

今回は以下のようなディレクトリ構成にします。

dist
└── main.js
lib
├── BusinessMember.js
└── Member.js
node_modules
.babelrc
index.js
index.html
package.json
webpack.config.js

 

ではプロジェクトを作成していきます。

まずは任意のディレクトリを作成し、その中で以下コマンドでプロジェクトを作成します。

$ npm init -y

 

これでpackage.jsonが作成されます。

このファイルにはライブラリをどんどん追加していきます。

npm installコマンドで簡単にインストールできるようになるので、他の人に配布すると環境構築が簡単にできるようになりますね。

 

モジュールをインストール

npmで必要なモジュールをインストールしていきます。

babel-loaderは8系と7系で内容が異なりますが、今回は8系を使います。

$ npm install --save-dev @babel/core @babel/polyfill @babel/preset-env babel-loader webpack webpack-cli

 

ビルドするときに必要ですが、実行するときには使わないので–save-devで入れておきましょう。–save-devを付けると package.json のdevDependenciesに記載されます。

また、モジュールがない状態でインストールするとdevDependenciesに書かれたライブラリがnode_modulesにインストールされるようになります。

なのでgitからはnode_modulesディレクトリは外して構いません。

 

モジュールのインストールはこれで終わりです。

インストールしたモジュールを確認したいときはnpm lsで確認できます。–depth 0をつけるとトップ層のみを確認できます。

$ npm ls --depth 0

 

HTMLファイル、jsファイルを作成

まずはjsファイルから。

Member.jsファイルをlibディレクトリに作成します。

'use strict';

export default class Member {
    constructor(firstName, lastName) {
        this.firstName = firstName;
        this.lastName = lastName;
    }

    getName() {
        return this.lastName + ' ' + this.firstName;
    }

    get firstName() {
        return this._firstName;
    }

    set firstName(value) {
        this._firstName = value;
    }

    get lastName() {
        return this._lastName;
    }

    set lastName(value) {
        this._lastName = value;
    }
}

 

次に同じくlibディレクトリにBusinessMember.jsを作成します。

'use strict';

import Member from './Member';

export default class BusinessMember extends Member{
    constructor(firstName, lastName, company) {
        super(firstName, lastName);  // 親クラスのコンストラクタは、コンストラクタの1行目で記載する必要がある
        this.company = company;
    }

    get company() {
        return this._company;
    }

    set company(value) {
        this._company = value;
    }

    getName() {
        return this.lastName + ' ' + this.firstName + '/' + this.company;
    }
}

 

お次はindex.jsファイルです。これはルートに配置ですね。

'use strict';

import BusinessMember from './lib/BusinessMember';

let pro = new Promise((resolve, reject) => {
    setTimeout(() => {
        resolve('ok');
    }, 500)
});

pro.then(response => {
    let user = new BusinessMember('taro', 'yamada', 'G社');
    console.log(user.getName());
});

 

最後にindex.htmlです。

<!DOCTYPE html>
<html lang="ja-jp">
<head>
    <meta charset="UTF-8">
    <script src="dist/main.js"></script>
    <title>ES6のテスト</title>
</head>
<body>

</body>
</html>

 

Webpackを準備

Webpackを実行するための設定ファイルを作成していきます。

babelの設定は「.babelrc」に記述します。webpack.config.jsの中に書くこともできますが、本格的に開発すると大抵の場合は分けることになると思うので、今回は分けました。

まずは.babelrcです。

{
  "presets": [
    [
      "@babel/preset-env",
      {
        "useBuiltIns": "entry"
      }
    ]
  ]
}

 

webpack.config.jsにはコマンド実行時に関する設定を書いていきます。

module.exports = {
  mode: 'development',
  devtool: 'source-map',
  entry: ['@babel/polyfill', './index.js'], // polyfill はIE11などで必要
  output: {
    path: `${__dirname}/dist`,
    filename: 'main.js'
  },
  module: {
    rules: [
      {
        test: /\.js$/,
        exclude: /node_modules/,
        use: {
          loader: 'babel-loader'
        }
      }
    ]
  }
};

 

そうしたらWebpackを実行しましょう。

$ npx webpack
Hash: 53476175c174b19d1a89
Version: webpack 4.20.2
Time: 2695ms
Built at: 2018/10/03 1:56:45
      Asset     Size  Chunks             Chunk Names
    main.js  370 KiB    main  [emitted]  main
main.js.map  294 KiB    main  [emitted]  main
Entrypoint main = main.js main.js.map
[./index.js] 300 bytes {main} [built]
[./lib/BusinessMember.js] 2.95 KiB {main} [built]
[./lib/Member.js] 1.37 KiB {main} [built]
[./node_modules/webpack/buildin/global.js] (webpack)/buildin/global.js 509 bytes {main} [built]
[0] multi @babel/polyfill ./index.js 40 bytes {main} [built]
    + 276 hidden modules

 

これでmain.jsが作成できました。

ついでに動作確認をしておくと、ChromeやIE11でindex.htmlにアクセスし、コンソールに yamada taro/G社 と表示されれば成功です。

 

npm scriptsを編集する

npm scriptsにコマンドを記述することで、処理をより簡単に実行することができます。

package.jsonのscriptsにコマンドを書いていきます。

webpackは –watch を付けることで、対象となるファイルが更新されたときに自動でビルドが実行可能です。watchという名前で実行できるようにしておきましょう。

Webpack自体はbuildという名前で実行できるようにします。

package.jsonに以下のように記述します。

〜
  "scripts": {
    "build": "webpack",
    "watch": "webpack --watch"
  },
〜

 

これでjsファイルに変更を加えると自動的にビルドが実行されるようになります。

$ npm run watch

 

Jestでテストをする

jsファイルをJestで確認しておきましょう。

JestはFacebookが開発したjsテストツールです。

 

まずはJestをインストールします。

$ npm install --save-dev jest

 

次にテスト用のディレクトリである「test」を作成します。

$ mkdir test

testディレクトリの中にテストを作成していきます。

BusinessMember.jsをテストするファイルをBusinessMember.test.js、Member.jsをテストするファイルをMember.test.jsとします。

BusinessMember.test.js

'use strict';

import BusinessMember from '../lib/BusinessMember';

test('BusinessMember.getName() to be "firstName lastName/company"', function() {
  let user = new BusinessMember('ken', 'sato', 'A社');
  expect(user.getName()).toBe('sato ken/A社');
});

 

Member.test.js

'use strict';

import Member from '../lib/Member';

test('Member.getName() to be "firstName lastName"', function() {
  let user = new Member('ken', 'sato');
  expect(user.getName()).toBe('sato ken');
});

 

ではテストを実行します。

$ npx jest
 PASS  test/BusinessMember.test.js
 PASS  test/Member.test.js

Test Suites: 2 passed, 2 total
Tests:       2 passed, 2 total
Snapshots:   0 total
Time:        2.195s
Ran all test suites.

 

testという名前でコマンドが動かせるようにnpm scriptsに追加しておくといいでしょう。

〜
  "scripts": {
    "build": "webpack",
    "watch": "webpack --watch",
    "test": "jest"
  },
〜

 

ではテストを実行しましょう。runは必要ありません。

$ npm test

 

以上がES6とWebpackとbabel-loaderで開発環境を構築する方法です。

最後のテストは面倒ならやる必要はありませんが、やったほうが安心感がありますね。