ECMAScript6で書こう!WebPackとES6-loaderで環境を作り、ES6を先取り体験する方法

ECMAScript6で書こう!WebPackとES6-loaderで環境を作り、ES6を先取り体験する方法

先生

先生

こんにちは。私事ですが、サイトリニューアルに伴いあだ名が変わり、「先生」となりました。(元博士)
降格になった訳ではありません。馴染まなかっただけです。

さて、ES5のブラウザ対応も広まり、ES6の話題がちらほらと出始めました。

ES6ではClassやConstが加わることとなり、これまでのJavaScriptの書き方も変わってくることでしょう。

というわけで早速ES6でコードを書いてみたいと思いますが、普通に書いたのでは動かないブラウザが多数です。
そこで本日は、WebPackとES6-Loaderを使い、ES6で書きつつもES5にコンバートさせていく手順を紹介したいと思います。

環境

インストールの前に開発ディレクトリを作ります。今回はこんな感じにします。

/es6
┣ /node_modules
┣ /source
┗ package.json

Node.js

npmが使える状態になっている必要があります。Nodeのインストールとpackage.jsonの作り方については、過去の記事「Gulp.js入門 – コーディングを10倍速くする環境を作る方法まとめ」を参考にしてください。

WebPack

グローバルにWebPackをインストールします。

npm install -g webpack

ES6 Loader

Package.jsonはnpm initすれば作れます。
こちらも先ほどの「Gulp.js入門 – コーディングを10倍速くする環境を作る方法まとめ」で紹介しておりますので、参考にしてください。

そしてES6 Loaderをインストールします。

npm install es6-loader --save-dev

これで環境ができました。

WebPackの設定

先ほど作ったディレクトリの1番上にwebpack.config.jsというファイルを作ります。

/es6
┣ /node_modules
┣ /source
┣ package.json
┗ webpack.config.js

webpack.config.jsには以下のように記述します。

module.exports = {
    output: {
        filename: "[name].js"
    },
    module: {
        loaders: [
            { test: /\.js$/, loader: 'es6-loader' },
        ]
    },
    plugins: [
    ]
};

module.loadersに.jsファイルだったらex6-loaderを実行すると記述してあげます。

これで設定はOKです。

さっそくクラスとモジュールを試す

sourceディレクトリに以下のJSを作ります。

  • animal.js
class Animal {
	constructor(name) {
		this.name = name;
	}
}
export default Animal;

export default AnimalでAnimalクラスを外部にエクスポートしてimportできるようにしています。

  • dog.js
import Animal from './animal';
class Dog extends Animal{
	constructor(name) {
		super(name);
	}
	callName() {
		alert(this.name);
	}
}

var dog = new Dog('Natsu');
dog.callName();

上記のように「class クラス名」でクラスができます。constructorはclassがnewされたときに実行され、「class クラス名 extends 継承元クラス名」で継承ができます。簡単ですね!

また、super()を使って継承元のconstrutor関数を呼んだり、継承元の関数を指定して実行もできます。

そして、importを用いてエクスポートされているJSを呼び出すことができ、これによってdog.jsでAnimalクラスが使えるようになります。

しかし、このままでは多くのブラウザで実行できないため、最初にインストールしたWebPackを使います。

以下のコマンドを実行するとmain.jsが作成されます。

webpack ./js/dog.js

開くとこんな感じに。

/******/ (function(modules) { // webpackBootstrap
/******/ 	// The module cache
/******/ 	var installedModules = {};
/******/
/******/ 	// The require function
/******/ 	function __webpack_require__(moduleId) {
/******/
/******/ 		// Check if module is in cache
/******/ 		if(installedModules[moduleId])
/******/ 			return installedModules[moduleId].exports;
/******/
/******/ 		// Create a new module (and put it into the cache)
/******/ 		var module = installedModules[moduleId] = {
/******/ 			exports: {},
/******/ 			id: moduleId,
/******/ 			loaded: false
/******/ 		};
/******/
/******/ 		// Execute the module function
/******/ 		modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
/******/
/******/ 		// Flag the module as loaded
/******/ 		module.loaded = true;
/******/
/******/ 		// Return the exports of the module
/******/ 		return module.exports;
/******/ 	}
/******/
/******/
/******/ 	// expose the modules object (__webpack_modules__)
/******/ 	__webpack_require__.m = modules;
/******/
/******/ 	// expose the module cache
/******/ 	__webpack_require__.c = installedModules;
/******/
/******/ 	// __webpack_public_path__
/******/ 	__webpack_require__.p = "";
/******/
/******/ 	// Load entry module and return exports
/******/ 	return __webpack_require__(0);
/******/ })
/************************************************************************/
/******/ ([
/* 0 */
/***/ function(module, exports, __webpack_require__) {

	"use strict";
	var Animal = __webpack_require__(1)["default"];
	var Dog = (function(super$0){var PRS$0 = (function(o,t){o["__proto__"]={"a":t};return o["a"]===t})({},{});var DP$0 = Object.defineProperty;var GOPD$0 = Object.getOwnPropertyDescriptor;var MIXIN$0 = function(t,s){for(var p in s){if(s.hasOwnProperty(p)){DP$0(t,p,GOPD$0(s,p));}}return t};var SP$0 = Object.setPrototypeOf||function(o,p){if(PRS$0){o["__proto__"]=p;}else {DP$0(o,"__proto__",{"value":p,"configurable":true,"enumerable":false,"writable":true});}return o};var OC$0 = Object.create;if(!PRS$0)MIXIN$0(Dog, super$0);var proto$0={};
		function Dog(name) {
			super$0.call(this, name);
		}if(super$0!==null)SP$0(Dog,super$0);Dog.prototype = OC$0(super$0!==null?super$0.prototype:null,{"constructor":{"value":Dog,"configurable":true,"writable":true}});DP$0(Dog,"prototype",{"configurable":false,"enumerable":false,"writable":false});
		proto$0.callName = function() {
			alert(this.name);
		};
	MIXIN$0(Dog.prototype,proto$0);proto$0=void 0;return Dog;})(Animal);

	var dog = new Dog('Natsu');
	dog.callName();

/***/ },
/* 1 */
/***/ function(module, exports, __webpack_require__) {

	"use strict";
	var Animal = (function(){var PRS$0 = (function(o,t){o["__proto__"]={"a":t};return o["a"]===t})({},{});var DP$0 = Object.defineProperty;var GOPD$0 = Object.getOwnPropertyDescriptor;var MIXIN$0 = function(t,s){for(var p in s){if(s.hasOwnProperty(p)){DP$0(t,p,GOPD$0(s,p));}}return t};
		function Animal(name) {
			this.name = name;
		}DP$0(Animal,"prototype",{"configurable":false,"enumerable":false,"writable":false});
	;return Animal;})();
	exports["default"] = Animal;

/***/ }
/******/ ])

実行させると……

実行できました!
ES6-loaderを使うことでES5で動作するように変換してくれます。これで未来のコーディングが体験できます。

なお、現在対応されている機能についてはこちらに記載されています。

WebPackの機能例:JSの圧縮

WebPackは今回紹介したもの以外にも数多くの機能を持っています。そのうちの1つとして、JSの圧縮をしてみましょう。

先ほどはグローバルにWebPackをインストールしましたが、今度はローカルにインストールします。

npm install web pack --save-dev

続いてwebpack.config.jsを以下のように変更します。

var webpack = require('webpack');
module.exports = {
    output: {
        filename: "[name].js"
    },
    module: {
        loaders: [
            { test: /\.js$/, loader: 'es6-loader' },
        ]
    },
    plugins: [
        new webpack.optimize.UglifyJsPlugin(),
    ]
};

この状態で再びWebPackコマンドを実行します。

webpack ./js/dog.js

すると今度はmain.jsが圧縮された状態で出力されます。

!function(t){function e(n){if(r[n])return r[n].exports;var o=r[n]={exports:{},id:n,loaded:!1};return t[n].call(o.exports,o,o.exports,e),o.loaded=!0,o.exports}var r={};return e.m=t,e.c=r,e.p="",e(0)}([function(t,e,r){"use strict";var n=r(1)["default"],o=function(t){function e(e){t.call(this,e)}var r=function(t,e){return t.__proto__={a:e},t.a===e}({},{}),n=Object.defineProperty,o=Object.getOwnPropertyDescriptor,a=function(t,e){for(var r in e)e.hasOwnProperty(r)&&n(t,r,o(e,r));return t},u=Object.setPrototypeOf||function(t,e){return r?t.__proto__=e:n(t,"__proto__",{value:e,configurable:!0,enumerable:!1,writable:!0}),t},c=Object.create;r||a(e,t);var i={};return null!==t&&u(e,t),e.prototype=c(null!==t?t.prototype:null,{constructor:{value:e,configurable:!0,writable:!0}}),n(e,"prototype",{configurable:!1,enumerable:!1,writable:!1}),i.callName=function(){alert(this.name)},a(e.prototype,i),i=void 0,e}(n),a=new o("Natsu");a.callName()},function(t,e){"use strict";var r=function(){function t(t){this.name=t}{var e=(function(t,e){return t.__proto__={a:e},t.a===e}({},{}),Object.defineProperty);Object.getOwnPropertyDescriptor}return e(t,"prototype",{configurable:!1,enumerable:!1,writable:!1}),t}();e["default"]=r}]);

このようにWebPackはさまざまなプラグインやローダーを使ってJavaScriptをコンパイルすることができます。詳しくは公式サイトをごらんください。

LIGではこのWebPackとAngularJSで開発をおこなうなどしています。

まとめ

いかがでしたでしょうか。

ほんの触りだけの紹介でしたが、ES6が楽しみになりましたでしょうか。
WebPackとES6-loaderを使うことでES5へコンバートできるので、AltJSの選択肢の1つとして考えても良いのではないかと思います。

また、今回使用したサンプルはGithubにて公開しておりますので、興味のある方はこちらよりダウンロードまたはフォークしてみてください。

それでは、Enjoy ES6!

 

【先生に聞いてみよう!】

業務で安心して使える厳選AngularJSモジュール8選+α

LIG主催のAngularJS勉強会 #ngCurryが開催されました

LIGのソースコードレビュー会で使用している共有ツールとライブラリの活用方法の紹介

AngularJS勉強会 ng-mtg#6に登壇してきました

フロントエンド開発を裏から支えるデバッグアプリケーション4選

LIGはWebサイト制作を支援しています。ご興味のある方は事業ぺージをぜひご覧ください。

Webサイト制作の実績・料金を見る

この記事のシェア数

CTOの林です。フロントエンドを専門とし、AngularJSのコミュニティをはじめ、様々な勉強会に顔を出しています。効率化マニアでGrunt,Gulpをはじめ、プロジェクト進行やサーバーサイド、インフラ周りの効率化を目指し日々活動しています。 【役職紹介 / CTO】 Web制作にかかる内容を統括しています。プロジェクトを横断的に見渡し、技術的な見地からアドバイスなどを行い、ときには実制作のヘルプを行ったりしています。新人エンジニアの育成や、体外的な活動としてLIG全体のエンジニアのブランディングのため勉強会やイベントへの登壇・開催なども行っています。 【普段やっていること】 新規サービスの設計(UI,遷移,DB,APIなど)、エンジニアの育成及び環境整備、技術選定、Web制作ユニットの統括とプロジェクト進行を円滑にするための仕組みづくり、フロントエンド周りの実装、エンジニアリングの開発効率化、勉強会の登壇・主催など

このメンバーの記事をもっと読む