#概要
前回の記事(準備編)でアセットをアップロードするための設定までやりましたが、今回はgulpを使ってトランスパイルからアップロードまで一括で行えるようにgulpタスクを作ります。
なぜgulpを使うのかというと、前回の記事にも書いた通り、PlayCanvas用のgulpタスクが公開されているからです。
#gulpfile.js
後述の問題のため、through2というgulp用のプラグインを使い、トランスパイル後のコードの先頭に2行ほどコードを書き加えるという泥臭い処理を行っています…(´・ω・`)
const gulp = require("gulp");
const playcanvas = require("gulp-playcanvas");
const pcOptions = require("./playcanvas.json");
const typescript = require("gulp-typescript");
const through2 = require('through2');
gulp.task("ts", () => {
return gulp
.src(["src/**/*.ts", "!src/**/_*.ts", "!./node_modules/**"])
.pipe(typescript({target: "ES5", module: "commonjs"})) //ES5
//.pipe(typescript({target: "ES2015", module: "commonjs"})) //ES2015(ES6)
.pipe(through2.obj((file, enc, callback) => {
if (file.isBuffer()) {
let contents = String(file.contents);
contents = "var exports = {};\nvar require = function(mod){};\n" + contents;
//contents = "/*jshint esversion: 6, asi: true, laxbreak: true*/\n" + contents; //ES2015(ES6)
file.contents = Buffer.from(contents);
}
callback(null, file);
}))
.pipe(gulp.dest("dist/"))
.pipe(playcanvas(pcOptions));
});
gulp.task("js", () => {
return gulp
.src(["src/**/*.js", "!src/**/_*.js"])
.pipe(gulp.dest("dist/"))
.pipe(playcanvas(pcOptions));
});
gulp.task("watch", function() {
gulp.watch(["src/**/*.ts", "!src/**/_*.ts"], gulp.task("ts"));
gulp.watch(["src/**/*.js", "!src/**/_*.js"], gulp.task("js"));
});
gulp.task("default", gulp.parallel("watch"));
#モジュール問題
トランスパイルしたコードの先頭に付け足す理由はモジュール機構の問題になります、ざっくり挙げると
- トランスパイルしただけのJavascriptコードそのままではモジュール機構の関係でPlayCanvas上ではエラーになります。
- ブラウザ環境ではES2015(ES6)形式のモジュールしかサポートされていません(IEの場合はモジュール自体対応していません)
- ES2015形式でimportすると、Playcanvasの実行時にエラーが出ます(importはトップレベルに記載する必要があるのですがランタイム上でスクリプトは下位へ移動されるから?)
- AMDやUMDはブラウザ上でも動くモジュール形式だそうですが、非同期だからなのかPlayCanvasエディタでアトリビュートを読み込めないので意味がありません
これをいろいろどうにかする方法を探りましたが、最も簡単で無難だったのが、commonjs形式でトランスパイルした上で
var exports = {};
var require = function(mod){};
という何もしないモジュール関係の変数と関数を定義するコードを付け足すことでした。
もっといい方法があればだれか教えてください…
#そのためのWebpack
そもそもこういったモジュール機構の問題を解決するためにWebpackがあるので、
次回はWebpackを使ってあんなことをしなくてもPlaycanvasで使えるコードを生成するためのタスクを作ります。