Gulp

このクイックスタートガイドでは、gulpでTypeScriptをビルドし、Browserifyterser、またはWatchifyをgulpパイプラインに追加する方法を説明します。このガイドでは、Babelifyを使用してBabel機能を追加する方法も示します。

npmNode.jsをすでに使用していることを前提としています。

最小限のプロジェクト

まず、新しいディレクトリから始めましょう。ここではprojと名付けますが、好きな名前に変更できます。

shell
mkdir proj
cd proj

まず、プロジェクトを次のように構成します。

proj/ ├─ src/ └─ dist/

TypeScriptファイルはsrcフォルダーから始まり、TypeScriptコンパイラーを通じてdistに配置されます。

これを足場にしましょう。

shell
mkdir src
mkdir dist

プロジェクトの初期化

次に、このフォルダーをnpmパッケージにします。

shell
npm init

一連のプロンプトが表示されます。エントリポイントを除いて、デフォルトを使用できます。エントリポイントには、./dist/main.jsを使用します。生成されたpackage.jsonファイルで、いつでも戻って変更できます。

依存関係のインストール

次に、npm installを使用してパッケージをインストールできます。まず、gulp-cliをグローバルにインストールします(Unixシステムを使用している場合は、このガイドのnpm installコマンドの先頭にsudoを付ける必要がある場合があります)。

shell
npm install -g gulp-cli

次に、プロジェクトのdevDependenciesにtypescriptgulpgulp-typescriptをインストールします。Gulp-typescriptは、TypeScript用のgulpプラグインです。

shell
npm install --save-dev typescript gulp@4.0.0 gulp-typescript

簡単な例を作成する

Hello Worldプログラムを作成しましょう。srcに、ファイルmain.tsを作成します。

ts
function hello(compiler: string) {
console.log(`Hello from ${compiler}`);
}
hello("TypeScript");

プロジェクトのルートprojに、ファイルtsconfig.jsonを作成します。

{
"": ["src/main.ts"],
"": true,
"": "es5"
}
}

gulpfile.jsを作成する

プロジェクトのルートに、ファイルgulpfile.jsを作成します。

js
var gulp = require("gulp");
var ts = require("gulp-typescript");
var tsProject = ts.createProject("tsconfig.json");
gulp.task("default", function () {
return tsProject.src().pipe(tsProject()).js.pipe(gulp.dest("dist"));
});

結果のアプリをテストする

shell
gulp
node dist/main.js

プログラムは「Hello from TypeScript!」と出力します。

コードにモジュールを追加する

Browserifyに入る前に、コードを構築し、モジュールを追加しましょう。これは、実際のアプリで使用する可能性が高い構成です。

src/greet.tsというファイルを作成します。

ts
export function sayHello(name: string) {
return `Hello from ${name}`;
}

次に、src/main.tsのコードを、greet.tsからsayHelloをインポートするように変更します。

ts
import { sayHello } from "./greet";
console.log(sayHello("TypeScript"));

最後に、src/greet.tstsconfig.jsonに追加します。

{
"": ["src/main.ts", "src/greet.ts"],
"": true,
"": "es5"
}
}

gulpを実行し、Nodeでテストして、モジュールが機能することを確認してください。

shell
gulp
node dist/main.js

ES2015のモジュール構文を使用しましたが、TypeScriptはNodeが使用するCommonJSモジュールを出力することに注意してください。このチュートリアルではCommonJSを使用しますが、オプションオブジェクトでmoduleを設定してこれを変更できます。

Browserify

次に、このプロジェクトをNodeからブラウザに移行しましょう。これを行うには、すべてのモジュールを1つのJavaScriptファイルにバンドルする必要があります。幸いなことに、それがまさにBrowserifyの機能です。さらに、Nodeで使用されるCommonJSモジュールシステムを使用できます。これはTypeScriptのデフォルトの出力です。つまり、TypeScriptとNodeの設定は、基本的に変更なしでブラウザに転送されます。

まず、browserify、tsify、およびvinyl-source-streamをインストールします。tsifyはBrowserifyプラグインで、gulp-typescriptと同様にTypeScriptコンパイラーへのアクセスを提供します。vinyl-source-streamを使用すると、Browserifyのファイル出力を、vinylと呼ばれるgulpが理解できる形式に戻すことができます。

shell
npm install --save-dev browserify tsify vinyl-source-stream

ページを作成する

srcindex.htmlというファイルを作成します。

html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>Hello World!</title>
</head>
<body>
<p id="greeting">Loading ...</p>
<script src="bundle.js"></script>
</body>
</html>

次に、main.tsを変更してページを更新します。

ts
import { sayHello } from "./greet";
function showHello(divName: string, name: string) {
const elt = document.getElementById(divName);
elt.innerText = sayHello(name);
}
showHello("greeting", "TypeScript");

showHelloを呼び出すと、sayHelloが呼び出され、段落のテキストが変更されます。次に、gulpfileを次のように変更します。

js
var gulp = require("gulp");
var browserify = require("browserify");
var source = require("vinyl-source-stream");
var tsify = require("tsify");
var paths = {
pages: ["src/*.html"],
};
gulp.task("copy-html", function () {
return gulp.src(paths.pages).pipe(gulp.dest("dist"));
});
gulp.task(
"default",
gulp.series(gulp.parallel("copy-html"), function () {
return browserify({
basedir: ".",
debug: true,
entries: ["src/main.ts"],
cache: {},
packageCache: {},
})
.plugin(tsify)
.bundle()
.pipe(source("bundle.js"))
.pipe(gulp.dest("dist"));
})
);

これにより、copy-htmlタスクが追加され、defaultの依存関係として追加されます。つまり、defaultが実行されるたびに、最初にcopy-htmlを実行する必要があります。また、defaultをgulp-typescriptの代わりにtsifyプラグインを使用してBrowserifyを呼び出すように変更しました。都合の良いことに、両方ともTypeScriptコンパイラーに同じオプションオブジェクトを渡すことができます。

bundleを呼び出した後、source(vinyl-source-streamのエイリアス)を使用して、出力バンドルにbundle.jsという名前を付けます。

gulpを実行し、ブラウザでdist/index.htmlを開いてページをテストします。「TypeScriptからのこんにちは」がページに表示されるはずです。

Browserifyにdebug: trueを指定したことに注意してください。これにより、tsifyは、バンドルされたJavaScriptファイル内にソースマップを出力します。ソースマップを使用すると、バンドルされたJavaScriptではなく、元のTypeScriptコードをブラウザでデバッグできます。ブラウザのデバッガーを開き、main.ts内にブレークポイントを設定することで、ソースマップが機能していることをテストできます。ページを更新すると、ブレークポイントでページが一時停止し、greet.tsをデバッグできるようになります。

Watchify、Babel、およびTerser

Browserifyとtsifyでコードをバンドルしているので、browserifyプラグインを使用してビルドにさまざまな機能を追加できます。

  • Watchifyはgulpを起動し、ファイルの保存時にインクリメンタルにコンパイルを継続します。これにより、ブラウザで編集-保存-更新のサイクルを継続できます。

  • Babelは、ES2015以降をES5およびES3に変換する非常に柔軟なコンパイラーです。これにより、TypeScriptがサポートしていない広範でカスタマイズされた変換を追加できます。

  • Terserは、ダウンロードにかかる時間を短縮するために、コードを圧縮します。

Watchify

まず、Watchifyを使用してバックグラウンドコンパイルを提供します。

shell
npm install --save-dev watchify fancy-log

次に、gulpfileを次のように変更します。

js
var gulp = require("gulp");
var browserify = require("browserify");
var source = require("vinyl-source-stream");
var watchify = require("watchify");
var tsify = require("tsify");
var fancy_log = require("fancy-log");
var paths = {
pages: ["src/*.html"],
};
var watchedBrowserify = watchify(
browserify({
basedir: ".",
debug: true,
entries: ["src/main.ts"],
cache: {},
packageCache: {},
}).plugin(tsify)
);
gulp.task("copy-html", function () {
return gulp.src(paths.pages).pipe(gulp.dest("dist"));
});
function bundle() {
return watchedBrowserify
.bundle()
.on("error", fancy_log)
.pipe(source("bundle.js"))
.pipe(gulp.dest("dist"));
}
gulp.task("default", gulp.series(gulp.parallel("copy-html"), bundle));
watchedBrowserify.on("update", bundle);
watchedBrowserify.on("log", fancy_log);

基本的には3つの変更がありますが、コードを少しリファクタリングする必要があります。

  1. browserifyインスタンスをwatchifyの呼び出しでラップし、結果を保持しました。
  2. TypeScriptファイルが変更されるたびにBrowserifyがbundle関数を実行するように、watchedBrowserify.on('update', bundle);を呼び出しました。
  3. コンソールにログを記録するために、watchedBrowserify.on('log', fancy_log);を呼び出しました。

(1)と(2)を合わせると、browserifyの呼び出しをdefaultタスクから移動する必要があることを意味します。また、WatchifyとGulpの両方が呼び出す必要があるため、defaultの関数に名前を付ける必要があります。(3)でログを追加するのはオプションですが、セットアップをデバッグするのに非常に役立ちます。

これでGulpを実行すると、起動して実行を維持する必要があります。main.tsshowHelloのコードを変更して保存してみてください。次のような出力が表示されるはずです。

shell
proj$ gulp
[10:34:20] Using gulpfile ~/src/proj/gulpfile.js
[10:34:20] Starting 'copy-html'...
[10:34:20] Finished 'copy-html' after 26 ms
[10:34:20] Starting 'default'...
[10:34:21] 2824 bytes written (0.13 seconds)
[10:34:21] Finished 'default' after 1.36 s
[10:35:22] 2261 bytes written (0.02 seconds)
[10:35:24] 2808 bytes written (0.05 seconds)

Terser

まずTerserをインストールします。Terserの目的はコードをマングルすることなので、ソースマップを機能させ続けるために、vinyl-bufferとgulp-sourcemapsもインストールする必要があります。

shell
npm install --save-dev gulp-terser vinyl-buffer gulp-sourcemaps

次に、gulpfileを次のように変更します。

js
var gulp = require("gulp");
var browserify = require("browserify");
var source = require("vinyl-source-stream");
var terser = require("gulp-terser");
var tsify = require("tsify");
var sourcemaps = require("gulp-sourcemaps");
var buffer = require("vinyl-buffer");
var paths = {
pages: ["src/*.html"],
};
gulp.task("copy-html", function () {
return gulp.src(paths.pages).pipe(gulp.dest("dist"));
});
gulp.task(
"default",
gulp.series(gulp.parallel("copy-html"), function () {
return browserify({
basedir: ".",
debug: true,
entries: ["src/main.ts"],
cache: {},
packageCache: {},
})
.plugin(tsify)
.bundle()
.pipe(source("bundle.js"))
.pipe(buffer())
.pipe(sourcemaps.init({ loadMaps: true }))
.pipe(terser())
.pipe(sourcemaps.write("./"))
.pipe(gulp.dest("dist"));
})
);

terser自体には1つの呼び出ししかありません。buffersourcemapsの呼び出しは、ソースマップが機能し続けるようにするためのものです。これらの呼び出しにより、以前のようにインラインソースマップを使用する代わりに、個別のソースマップファイルが作成されます。これでGulpを実行して、bundle.jsが読めないメチャクチャなものに最小化されていることを確認できます。

shell
gulp
cat dist/bundle.js

Babel

まず、BabelifyとES2015用のBabelプリセットをインストールします。Terserと同様に、Babelifyはコードをマングルするため、vinyl-bufferとgulp-sourcemapsが必要になります。デフォルトでは、Babelifyは.js.es.es6、および.jsxの拡張子を持つファイルのみを処理するため、Babelifyへのオプションとして.ts拡張子を追加する必要があります。

shell
npm install --save-dev babelify@8 babel-core babel-preset-es2015 vinyl-buffer gulp-sourcemaps

次に、gulpfileを次のように変更します。

js
var gulp = require("gulp");
var browserify = require("browserify");
var source = require("vinyl-source-stream");
var tsify = require("tsify");
var sourcemaps = require("gulp-sourcemaps");
var buffer = require("vinyl-buffer");
var paths = {
pages: ["src/*.html"],
};
gulp.task("copy-html", function () {
return gulp.src(paths.pages).pipe(gulp.dest("dist"));
});
gulp.task(
"default",
gulp.series(gulp.parallel("copy-html"), function () {
return browserify({
basedir: ".",
debug: true,
entries: ["src/main.ts"],
cache: {},
packageCache: {},
})
.plugin(tsify)
.transform("babelify", {
presets: ["es2015"],
extensions: [".ts"],
})
.bundle()
.pipe(source("bundle.js"))
.pipe(buffer())
.pipe(sourcemaps.init({ loadMaps: true }))
.pipe(sourcemaps.write("./"))
.pipe(gulp.dest("dist"));
})
);

また、TypeScriptがES2015をターゲットにする必要もあります。次に、BabelはTypeScriptが出力するES2015コードからES5を生成します。tsconfig.jsonを変更しましょう。

{
"": ["src/main.ts"],
"": true,
"": "es2015"
}
}

BabelのES5出力は、このような単純なスクリプトの場合、TypeScriptの出力と非常に似ているはずです。

TypeScriptドキュメントはオープンソースプロジェクトです。これらのページの改善にご協力ください。プルリクエストを送信してください

このページの貢献者
BKBowden Kelly (51)
OTOrta Therox (15)
DRDaniel Rosenwasser (3)
RCRyan Cavanaugh (2)
MFMartin Fischer (1)
19+

最終更新日: 2024年3月21日