[JavaScript] ES6の書き方でTypeScriptの外部モジュールしたい

2015/08/20

こんにちは。きんくまです。

前回外部モジュールの記事を書いたのですが、Qiitaにあったこんな記事を読みました。
>> TypeScript 1.5.3 変更点 – Qiita

おお、記事によると前に書いたのはES6の書き方じゃなかったみたい。
あと、内部モジュールは module じゃなくて namespace でやるみたい。

それで詳しくは全てこちらの記事にのっているのでそちらを参照いただければ。
今回は、自分でももう一度外部モジュールをES6の書き方で書いてみようと思いまして。

gulpfile.js

これは前回とほとんど同じです。
tsifyの設定に module をつけなくてもcommonjsになるみたいです。

gulpfile.js

var gulp = require('gulp');
var sourcemaps = require('gulp-sourcemaps');
var concat = require('gulp-concat');
var browserify = require('browserify');
var tsify = require('tsify');
var source = require('vinyl-source-stream');
var uglify = require('gulp-uglify');
var argv = require('yargs').argv;
var gulpif = require('gulp-if');

/**
 * TypeScript
 */
function buildTypeScript(){
    function handleError(error) { console.error(error.toString()); }
    var debugMode = argv.release ? false : true;
    var bundler = browserify({
            basedir: 'htdocs/src/',
            debug:debugMode
        })
        .add('Main.ts')
        .plugin('tsify', {
            noImplicitAny: true,
            declaration:true,
            target: 'ES5'
            //module: 'commonjs'
        });
    return bundler.bundle()
        .on('error', handleError)
        .pipe(source('game.js'))
        .pipe(gulp.dest('htdocs/js'));
}
function minifyJS(){
    var targetFile = 'htdocs/js/game.js';
    return gulp.src(targetFile)
        .pipe(uglify())
        .pipe(gulp.dest('htdocs/js'));
}
//debug
gulp.task('ts-debug', buildTypeScript);

gulp.task('ts-release', buildTypeScript);
gulp.task('js-minify', ['ts-release'], minifyJS);

//release
gulp.task('js-release', ['ts-release', 'js-minify']);

外部モジュール

外部に書き出したいときはいくつか方法があって

1. ファイルの最後に export { xxx, yyy }

GameDefs.ts

enum StageType {
    ArowanaMall = 1,     //アロワナモール
    BlackbellySkatepark, //Bバスパーク
    UrchinUnderpass      //デカライン高架下
}

enum InklingFormType {
    Squid = 1,
    Kid
}

export {StageType, InklingFormType}


2. export default キーワードつき

クラスが1ファイルに1つだけのときは export default でやるとうまくできました。
なんかコンパイラーにエラーメッセージが出てきてそんな感じに書くといいみたい。
あと、上の記事にもあるのだけれど、 default つけたやつが import したときにそのまま読み込まれます。

Stage.ts

import {StageType} from './GameDefs';

export default class Stage {
    type:StageType;

    constructor(type:StageType){
        this.type = type;
    }

    setup(){
        console.log('setup stage');
    }
}


3. export キーワードつき

クラスが1ファイルに複数ある場合はそれぞれにexportをつけたらうまくいきました。

Inkling.ts

import {InklingFormType} from './GameDefs';

export class Squid {
    move(){
        console.log('move quickly in ink');
        return 100;
    }
}

export class Kid {
    move(){
        console.log('run on ink');
        return 5;
    }

    shoot(){
        console.log('shoot!');
    }
}

export class Inkling {
    private _formType:InklingFormType;
    private _squid:Squid;
    private _kid:Kid;
    private _position:number;

    constructor(){
        this._formType = InklingFormType.Kid;
        this._squid = new Squid();
        this._kid = new Kid();
        this._position = 0;
    }

    get formType():InklingFormType{
        return this._formType;
    }

    get position():number{
        return this._position;
    }

    transform(){
        if(this._formType == InklingFormType.Squid){
            this._formType = InklingFormType.Kid;
            console.log('transform to kid');
        }else{
            this._formType = InklingFormType.Squid;
            console.log('transform to squid');
        }
    }

    move(){
        if(this._formType == InklingFormType.Squid){
            this._position += this._squid.move();
        }else{
            this._position += this._kid.move();
        }
        console.log('moved. position = ' + this._position);
    }

    shoot(){
        if(this._formType == InklingFormType.Kid){
            this._kid.shoot();
        }
    }
}

最後のメインクラス。最後の行でwindowに参照を渡しているのは、htmlから初期化したいからです。
いろいろとhtmlから引数渡したりできて便利なので。
普通に書き出すとwindowから完全に閉じた状態で作成されるみたいなので、こういう書き方をしてます。
あとStage.tsは export default で書き出したので import するときに { xxx } じゃなくてもうまくいきます。

Main.ts

import {Inkling} from './Inkling';
import Stage from './Stage';
import {StageType} from './GameDefs';

class Main {
    player:Inkling;
    stage:Stage;

    setup(){
        this.player = new Inkling();
        this.stage = new Stage(StageType.ArowanaMall);
        this.stage.setup();
    }

    start(){
        this.player.move();
        this.player.shoot();

        setTimeout(()=>{
            this.player.transform();
            this.player.move();
        }, 1000);
    }
}

(<any>window).Main = Main;

htmlから動かしてみます。

index.html

<!doctype html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <title>Sample</title>
</head>
<body>
<script src="js/game.js"></script>
<script>
    var main = new Main();
    main.setup();
    main.start();
</script>
</body>
</html>

出力

setup stage
run on ink
moved. position = 5
shoot!
transform to squid
move quickly in ink
moved. position = 105

イカたのしいです! でもウデマエはC帯とB帯を往復しているんだけどね、、。

こちらの記事も参考になります。
>> What’s new in TypeScript

LINEで送る
Pocket

自作iPhoneアプリ 好評発売中!
フォルメモ - シンプルなフォルダつきメモ帳
ジッピー電卓 - 消費税や割引もサクサク計算!

ページトップへ戻る