本文へジャンプ

gulpでTypeScriptファイルをコンパイルしてWebPackでまとめる

Posted by MONSTER DIVE

今回は、gulpを使ってTypeScriptをコンパイルして、WebPackをまとめる方法について紹介したいと思います。

今までは、RequireJSを使って、JS同士の依存関係を解消していました。最近は、WebPackを用いて依存関係を解決している記事を多く見ます。今回は実際にWebPackを試してみました。

gulp導入については、ビルドツール「gulp.js」を使ってみるの記事が参考になると思います。

準備

今回、やることは下記の通りです。

  1. ファイルを監視して更新されたタイミングで、TypeScriptファイルをコンパイル
  2. コンパイルされた複数のJSファイルをWebPackで1つのJSファイルにマージする
  3. ファイルがマージされたらブラウザをリロードする

ディレクトリ構成

準備する設定ファイルについては下記の通りです。

  1. package.json(読み込むnode_modulesの設定ファイル)
  2. gulpfile.js(タスクを管理する設定ファイル)
  3. webpack.config.js(WebPackの設定ファイル)※

※WebPackの設定は、gulpfile.jsでの設定も可能です。しかし、設定は分けた方が後々分かりやすいので、WebPackのコンパイル設定が書かれたファイルwebpack.config.jsを準備をしました。

フォルダの役割

project(プロジェクトルートフォルダ)
├ package.json
├ gulpfile.js
├ webpack.config.js
│
├ src(ソースフォルダ。TypeScriptファイルやTypeScriptをコンパイルしたJSファイル)
│ ├ ts(TypeScriptファイルを格納するフォルダ)
│ │ ├ app.ts
│ │ └ sub.ts
│ │
│ └ js(TypeScriptファイルのコンパイル先)
│
└ develop(WebPackでマージされたJSがコンパイルされるフォルダ)
    ├ index.html
    └ js(WebPackでまとめられたJSファイルの主力先)

package.json

今回、使用するnode_modulesについては下記の通りです。

{
  "name": "SAMPLE",
  "main": "gulpfile.js",
  "author": {
    "name": "Kentaro Otsuka",
    "url": "https://www.monster-dive.com/"
  },
  "devDependencies": {
    "gulp": "^3.8.11",
    "browser-sync": "^2.7.6",
    "gulp-load-plugins": "1.0.0-rc.1",
    "gulp-plumber": "^1.0.1",
    "gulp-notify": "^2.2.0",
    "gulp-watch": "^4.2.4",
    "gulp-typescript": "^2.7.6",
    "gulp-webpack": "^1.5.0"
  }
}

node_modulesの詳細

  • browser-sync(ローカルサーバーを起動、ブラウザのリロードなどを行うプラグイン)
  • gulp-load-plugins(package.jsonに記載されているgulp-に紐づいたモジュールを読み込むプラグイン)
  • gulp-plumber(エラーが出てもタスクを続けるためのプラグイン)
  • gulp-notify(デスクトップに通知を行えるプラグイン)
  • gulp-watch(ファイルを監視するプラグイン)
  • gulp-typescript(TypeScriptファイルをコンパイルするためのプラグイン)
  • gulp-webpack(WebPackを実行するためのプラグイン)

gulpfile.js

今回使用したgulpfile.jsについては下記の通りです。

(function () {
    'use strict';

    /************************ 設定 ************************/

    var _gulp = require('gulp');

   // WebPackのConfigファイルを読み込み
    var _webpackConfig = require('./webpack.config.js');

    // パスやコマンド、オプション等をオブジェクトにまとめる
    var Config = {
        path: {
            src: 'src/',
            develop: 'develop/',
            js: 'js',
            typescript: 'ts'
        },
        command: {
            typescript: 'ts',
            webpack: 'webpack',
            bs: 'bs'
        },
        tsOpt: {
            module: 'commonjs',
            target: 'ES5',
            removeComments: true,   // TypeScriptで記述したコメントをコンパイルしない
            noEmitOnError: false    // チェックエラーが出てもコンパイルするかの設定
        }
    };

    // gulp-load-pluginsを利用して一括でモジュールを変更する
    // 必要に応じて名前を変更する
    var $ = require('gulp-load-plugins')({
        pattern: ['gulp-*', 'gulp.*'],
        replaceString: /\bgulp[\-.]/,
        rename: {
            'gulp-typescript': 'ts'
        }
    });

    // BrowserSyncをセットする
    $.browserSync = require('browser-sync');
    var _reload = $.browserSync.reload;

    /************************ タスク ************************/

    /**
     * webpackを監視するタスク
     */
    _gulp.task('default', [Config.command.bs, Config.command.typescript], function () {
        // TypeScriptを格納しているフォルダを監視
        _gulp.watch(Config.path.src + Config.path.typescript + '/' + '**/*.ts', [Config.command.typescript]);
    });

    /**
     * TypeScriptをコンパイルするタスク
     */
    _gulp.task(Config.command.typescript, function () {
        // TypeScriptプロジェクトにオプションを渡す
        var _typescriptProject = $.ts.createProject(Config.tsOpt);

        // _から始まるtsファイルを除いたファイルをコンパイル
        // watchタスクが解除されないようにplumberをセットする
        _gulp.src(Config.path.src + Config.path.typescript + '/' + '**/!(_)*.ts')
            .pipe($.plumber({
                errorHandler: $.notify.onError('エラーが出ています')
            }))
            .pipe($.ts(_typescriptProject))
            .pipe(_gulp.dest(Config.path.src + Config.path.js))
            .on('end', function () {
                // コンパイルが完了したらWebPackタスクを実行する
                _gulp.run(Config.command.webpack);
            });
    });

    /**
     * WebPackを実行するタスク
     */
    _gulp.task(Config.command.webpack, function () {
        _gulp.src(_webpackConfig.entry)
            .pipe($.webpack(_webpackConfig))
            .pipe(_gulp.dest(_webpackConfig.dest))
            .pipe($.notify(function () {
                return 'WebPack Complete';
            }))
            .pipe(_reload({stream: true}));
    });

    /**
     * BrowserSyncタスク
     */
    _gulp.task(Config.command.bs, function () {
        $.browserSync({
            notify: false,
            server: {
                baseDir: Config.path.develop
            }
        });
    });
})();

webpack.config.js

今回使用したwebpack.config.jsについては下記の通りです。

(function (module) {
    var WEBPACK_CONFIG = {
        entry: './src/js/app.js',   // このファイルを元に読み込みを辿ります
        dest: 'develop/js/',        // まとめられたJSのコンパイル先
        output: {
            filename: 'app.js'      // まとめられたJSのファイル名
        }
    };
    module.exports = WEBPACK_CONFIG
}(module));

TypeScriptファイル

今回、TypeScriptでやりたいことは下記の通りです。

  1. app.tsからsub.tsを読み込む
  2. app.tsからsub.tsのメソッドを実行して、bodyの色を赤に変更

以下、使用したソースファイルになります。

app.ts

// subを読み込み
import SubClass = require('./sub');

class App {
    constructor() {
        // subClassにrequireしたSubを格納
        var subObject:SubClass = new SubClass();

        // bodyの色を変更する
        subObject.changeBodyColor();
    }
}

// Appのコンストラクタを実行
var app = new App();

sub.ts

class Sub {
    /**
     * bodyの色を変更するメソッド
     */
    changeBodyColor():void {
        var body = document.body;
        body.style.backgroundColor = 'red';
    }
}

// requireするためにクラスをexportする
export = Sub;

コンパイル

設定が完了したら、ターミナルから下記のコマンドを実行します。今回は、実行するコマンドをgulpのデフォルトコマンドに設定しました。必要に応じてコマンドを変更すると、より使いやすい開発環境になると思います。

コンパイルが終わるとデスクトップに通知が表示され、WebPackのコンパイル先(develop/js/)にJSファイルがコンパイルされます。

gulp

コマンド実行時の画面

まとめ

WebPackを利用すると、分割されたファイルを1つのファイルにマージすることが簡単にできます。

制作中はファイルを分割しておいた方が管理がしやすく、使い回しをすることができます。しかし、ファイルはまとめた方が読み込み管理が楽になったり、リクエスト数が減るので1つのファイルにまとめたほうが便利です。

コンパイルとマージなど面倒なことをタスクにまとめることによって、効率的な開発を行うことができます。

Recent Entries
MD EVENT REPORT
What's Hot?