やりたいこと
- TypeSciptでファイル分割してコードを書く
- ///<reference ...とかは使わずimportとかexport使う方針で。
- Gulpでコンパイルして1つのファイルに結合
- HTMLのscriptタグ内のJavaScriptから生成したclassとかにアクセスする
そして以下が発生した問題です。
- ファイル1つにするのは楽だったが、export周りでエラー
- Browserifyで解決
- TypeScriptで書いたクラスへどうやってアクセスしよう?←今回はここ
コード部分
今回はこんな感じのコードを想定
// index.ts
// ここには載せてないが、別に読み込むファイルがあるとする。
import p = require( './other' ); // other.tsだけど、拡張子はつけない。
export class CLASS {
static run() {
// ここを呼び出して実行したい
}
}
HTMLはこんな感じ。
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>PTitle</title>
<script src="index.js"></script>
<script>
window.onload = function(){
// こんな感じで呼び出したい!!
CLASS.run();
}
</script>
</head>
<body>
</body>
<script>
</script>
</html>
そしてGulpのタスクがこんな感じ。
var config =
{
src: [ './src/*.ts' ],
dst: './build',
out: 'index.js',
options: { target: 'ES5', module: 'commonjs', sortOutput: true },
entries: { entries: [ 'build/index.js', './build/other.js' ] }
};
gulp.task( 'typescipt', function ()
{
return gulp
.src( config.src )
.pipe( typescript( config.options ) )
.js
.pipe( gulp.dest( config.dst ) );
});
gulp.task( 'build', [ 'typescipt' ],function()
{
return browserify( config.entries )
.bundle()
.pipe( source( config.out ) )
.pipe( gulp.dest( './' ) );
});
gulp.task( 'release', [ 'build' ], function ()
{
return gulp
.src( config.out )
.pipe( uglify() )
.pipe( rename( { extname: '.min.js' } ) )
.pipe( gulp.dest( './' ) );
});
typesciptはsrc/以下にあるindex.tsとother.tsをコンパイルしてbuild/以下に*.jsとして出力するタスクです。
buildはtypescriptで出力されたJavaScriptのファイルをBowserifyでブラウザで使えるようにしながらindex.jsにまとめています。
releaseはbuildで生成されたindex.jsをminifyしてindex.min.jsを出力します。
gulpではbuildやreleaseを指定することを想定した作りです。
実際にしたこと
ここからが本番です。
まず今回生成されたindex.jsはグローバルな場所に今回作ったクラスなどが出てこないです。
かといってTypeSciptでグローバル変数を使おうとするとエラーになります。
どうするか?
上のクラスをグローバル変数に代入する以下の様なJavaSciptファイルを作って、それをTypeSciptビルドが終わった後に結合します。
今回はmain.jsという名前にします。
var p = require('./index');
CLASS = p.CLASS;
コピーは以下の様なGulpタスクを新たに作ります。
gulp.task( 'copy', function ()
{
return gulp
.src( [ 'src/main.js' ] )
.pipe( gulp.dest( config.dst ) );
});
手順をまとめると以下のようになります。
- TypeScriptでコードを書く
- HTML内のscript内から呼び出したいものをグローバル変数に置くJavaScriptファイルを書く
- TypeScriptをコンパイルしたJavaScriptファイルと上のグローバル変数定義ファイルをBrowserifyで結合
まとめ
src/以下は次のようなファイルがあるとします。
- index.ts
- other.ts
- main.js←今回の肝
Gulpファイルは最終的に以下のようになります。
var gulp = require( 'gulp' );
var typescript = require( 'gulp-typescript' );
var rename = require( 'gulp-rename' );
var browserify = require( 'browserify' );
var source = require( 'vinyl-source-stream' );
var uglify = require( 'gulp-uglify' );
var config =
{
src: [ './src/*.ts' ], // src以下のTypeScriptファイルをすべてコンパイル対象とする。
dst: './build', // コンパイルしたJSとmain.jsを入れるディレクトリ
out: 'index.js', // 最終的な出力ファイル名
options: { target: 'ES5', module: 'commonjs', sortOutput: true }, // TypeScriptのオプション
entries: { entries: [ 'build/main.js' ] } // Browserifyのオプション
};
// TypeSciptのコンパイル
gulp.task( 'typescipt', function ()
{
return gulp
.src( config.src )
.pipe( typescript( config.options ) )
.js
.pipe( gulp.dest( config.dst ) );
});
// main.jsをコピー
gulp.task( 'copy', function ()
{
return gulp
.src( [ 'src/main.js' ] )
.pipe( gulp.dest( config.dst ) );
});
// TypeScriptでコンパイルしたJavaSciptとmain.jsをブラウザで使えるようにしつつ結合してindex.jsとして出力
gulp.task( 'build', [ 'typescipt', 'copy' ],function()
{
return browserify( config.entries )
.bundle()
.pipe( source( config.out ) )
.pipe( gulp.dest( './' ) );
});
// index.jsをminifyしてindex.min.jsとして出力
gulp.task( 'release', [ 'build' ], function ()
{
return gulp
.src( config.out )
.pipe( uglify() )
.pipe( rename( { extname: '.min.js' } ) )
.pipe( gulp.dest( './' ) );
});
gulp.task( 'default', [ 'build' ] );
Gulp初心者なので、もっといい方法で同じことができるようなら教えて下さい。