LoginSignup
1
0

More than 5 years have passed since last update.

TypeScript+nodemon+BrowserSyncをgulpでまともに動かすために

Last updated at Posted at 2016-06-27

お品書き

  1. TypeScriptをサーバー側で差分コンパイル。
  2. nodemonでNodeの自動再起動
  3. BrowserSyncでフロントエンドも自動リロード

概要

  • TypeScriptとnodemonが絡んだサンプルの作成。
  • とりあえず使えるもの

実際の設定

devDependencies

package.json(一部抜粋)

"devDependencies" {
    "browser-sync": "^2.13.0",
    "gulp": "^3.9.1",
    "gulp-nodemon": "^2.1.0",
    "gulp-typescript": "^2.13.6"
}

インストール

npm i -D browser-sync gulp gulp-nodemon gulp-typescript

TypeScriptの差分コンパイル

参考→ gulp-tscとgulp-typescriptの利用方法の違いについて

残念ながらgulp-tscは当の昔にdeprecatedされてしまったようです。なので今後はgulpに組み込むときはgulp-typescriptのみを使っていくようですが、こっちのほうがtsconfig.jsonから設定を取り込めたり、差分コンパイルできたり何かと便利です。

tsconfig.json

{
    "compilerOptions": {
        "diagnostics": true,
        "emitDecoratorMetadata": true,
        "experimentalDecorators": true,
        "module": "commonjs",
        "moduleResolution": "node",
        "target": "es2015"
    },
    "exclude": [
        "node_modules",
        "bower_components",
        "jspm_packages"
    ]
}

targetはとりあえずes2015で最新の機能をフル活用するようにしていますがここら辺は様々な事情で変えていく必要があるかもしれません。例えばどうしてもIE向けに作る必要があるときとか、古いNode向けとか。

gulpfile.js(TypeScript部)

const gulpts = require("gulp-typescript");
const tsProject = gulpts.createProject(
    "tsconfig.json", {
        sortOutput: true,
        typescript: require('typescript')
    });

gulp.task("serverCompile", () => {
    gulp.src(['server/ts/**/*.ts'])
        .pipe(gulpts(tsProject))
        .js
        .pipe(gulp.dest('server/js/'));
});

gulp.task("clientCompile", () => {
    gulp.src(['public/**/*.ts'])
        .pipe(gulpts(tsProject))
        .js
        .pipe(gulp.dest('public/'));
});

ここら辺は好みでしょうが自分はpublicserverの二つのディレクトリでサーバー処理部分とクライアント処理部分を分けさらにそれぞれの中にtsjsとディレクトリを分けています。

BrowserSync

厄介者その1

gulpfile.js(BrowserSync部)

const browserSync = require("browser-sync").create();
const reload = browserSync.reload;
gulp.task("browser-sync", ['nodemon'], () => {
    browserSync.init(null, {
        proxy:"localhost:3000",
        open:false,
        port:"7000",
        files: [
            "public/**/*.*"
        ],
        serveStatic:['public/**/*.*'],
        minify:true
    });
});

何が厄介ってときどきportが暴れだしたりproxyが暴れだしたりするところでしょう。具体的には番号が一つずれてたり。とりあえずそんな時はCtrl+Cで様子見。このBrowserSyncをnodemonで実際に動作させてNodeの再起動時にもブラウザを自動リロードできるようになります。

nodemon

厄介者その2

gulpfile.js(nodemon部)

const gulpts = require("gulp-nodemon");
const path = require("path");
gulp.task('nodemon', (cb) => {
    let called = false;

    return nodemon({
        script: 'server/js/',
        watch:'server/',
        ext: 'js html css ts pug',
        tasks: (changedFiles) => {
            let tasks = [];
            changedFiles.forEach(file => {
                if (path.extname(file) === '.ts' && !~tasks.indexOf("serverCompile"))
                    tasks.push("serverCompile");
            });
            return tasks;
        }
    }).on('start', () => {
        if (!called) {
            called = true;
            cb();
        }
    }).on('restart', () => {
        setTimeout(() => {
            reload();
        }, 500);
    });
});

なんとなくtasks使わなくてもできそうなものなんだけどそれだとコンパイルに連動して動作しません。それにwatchscriptの指定ミスると動作が遅くなったり、こけたり。あと最初pathの存在に気づかなくて延々と悩んだり。いよいよ締めのdefaultです。

default

gulp.task("default", ['clientCompile','browser-sync'], () => {
    console.log("gulp start");
    // client tasks
    gulp.watch('public/**/*.ts',['clientCompile']);
});

実はここもひと悶着ありました。gulp.watch('public/**/*.ts',['clientCompile']) これをどこに持ってくるかで。nodmonのところに持って行ってみたり。browser-syncのところに持って行ってみたり。

感想

JavaScriptは神秘的。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0