クモのようにコツコツと

フロントエンドエンジニア イイダリョウの技術ブログ。略称「クモコツ」

【JS】TypeScriptをGulpでコンパイルしてみる

Gulpの続きです。前回はAltCSSのSass(SCSS)をコンパイルしました。今回はAltJSのTypeScriptをコンパイルします。それでは行きまっしょい!

【目次】

前回記事
※参考:【CSS】Sass(SCSS)をGulpでコンパイルしてみる - クモのようにコツコツと

※参考:メタ言語(HTMLテンプレートエンジン、AltCSS、AltJS)まとめ
qiita.com

フォルダ作成→移動→package.json作成→Gulpインストール

メタ言語選定編の記事でも書いた通り、AltJSはTypeScriptがスタンダードなようなのでこれに取り組む。

※参考:フロントエンドのメタ言語のコンパイル環境を作る(言語選定編) - クモのようにコツコツと

前回までと同様、おなじみの手順でコンパイル環境を準備する。

※参考:【CSS】Sass(SCSS)をGulpでコンパイルしてみる - クモのようにコツコツと

node.jsとnpmは入っている前提(下記のコマンドでバージョン番号が出る)

node -v
npm -v

コンパイルを実行したいフォルダを作成する。今回は「gulp_ts」とする。

cdコマンドで移動する

cd /(フォルダ)/gulp_ts

package.jsonを作成

npm init -y

ローカルにGulpインストール

npm install -D gulp

Gulp以外のコンパイル方法も:tscコマンド

GulpでのTypeScriptコンパイル方法はこちらの記事がわかりやすくまとめられていた!

※参考:TypeScript超入門:とりあえず動く環境を作る - Qiita

また、上記の記事にはGulpを使わず「tsc」というコマンドを使う方法も書かれていた。

tscはTypeScriptを開発しているMicrosoftが提供しているツール。

※参考:GitHub - microsoft/TypeScript: TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

簡易なコンパイルならこれで済みそう。ご参考まで。

パッケージ(gulp-typescript)をインストールする

今回はこれまでと同様Gulpでコンパイルしたいので、Gulpのパッケージ「gulp-typescript」をインストールする。

npm install -D gulp-typescript

インストールに成功するとpackage.jsonに追記される。

  "devDependencies": {
    "gulp": "^4.0.2",
    "gulp-typescript": "^6.0.0-alpha.1"
  }

ファイルを作る

「gulp_ts」フォルダにファイルを追加する。このような構成

gulp_ts
├css
│└common.css
├js
│└common.ts
├index.html
└gulpfile.js

jsフォルダの中のファイルの拡張子は.jsではなく.ts。これがTypeScriptで書かれたファイル、と認識される。

gulpfile.jsにgulp.task()を記述

Sass(SCSS)編の内容をベースに参考記事の内容を反映している。

※参考:TypeScript超入門:とりあえず動く環境を作る - Qiita

const gulp = require('gulp');
const typescript = require('gulp-typescript');

gulp.task('ts',  () => {
    return gulp
        .src('js/common.ts')
        .pipe(typescript())
        .js
        .pipe(gulp.dest('js'));
});
  • 変数gulpgulpを読み込む
  • 変数typescriptgulp-typescriptを読み込む
  • gulp.task()メソッド実行。第一引数はts、第二引数は無名関数(引数はなし)
  • 無名関数の中はgulp.src().pipe().js.pipe()とチェーンになっている
  • src()の引数はcommon.tsのパス
  • 一つ目のpipe()の引数はtypescript()で、中のオプションはなし
  • jsというプロパティが入る
  • jsプロパティの次のpipe()の引数はgulp.dest()でjsフォルダに吐き出す

Sassとの違いはメソッドチェーンの中でjsというプロパティが入る部分。

htmlファイルを作成

以前、AltJSの記事で書いた「TypeScript」の内容を元に作成。

※参考:【CoffeeScript, LiveScript, TypeScript, Babel】AltJS 事始め - クモのようにコツコツと

こちちらが元になったCodePen

See the Pen TypeScript Practice 1 by イイダリョウ (@i_ryo) on CodePen.

HTMLコード

<!doctype html>
<html>
    <head>
   <meta charset="UTF-8">
   <title>初めてのTypeScriptコンパイル</title>
   <link rel="stylesheet" href="css/common.css">
</head>

<body>
    <section id="type">
        <h1>TypeScript事始め</h1>
        <p>CodePen Settingの旅、JS編第3回。TypeScriptは静的型付け、クラス定義、ES対応などの特徴があるそうな。<br>
CoffeeScriptと違ってJSの延長上の記法なので読み書きしやすそう。</p>
        <section id="hello">
            <h2>特徴</h2>
            <ul>
                <li>変数に「:」で静的型付けができる。</li>
                <li>関数内の引数も「:」で静的型付け</li>
                <li>アロー関数式「=>」が使える</li>
                <li>クラス定義ができる</li>
            </ul>
            <p>素のJSでもそのまま行けるようなのでJSからの書き換えもしやすそう。</p>
        </section>
        <div><button id="btn">ここ押せワンワン</button>
    </section>
    <script src="js/common.js"></script>
</body>
</html>

bodyの閉じタグの直前でjsファイルをリンクしているが、まだ該当ファイルは存在しない。

<script src="js/common.js"></script>

tsファイルを作成

同じくAltJSの記事からcommon.tsファイルを作成する。

※参考:【CoffeeScript, LiveScript, TypeScript, Babel】AltJS 事始め - クモのようにコツコツと

/*関数
function hellow(){
window.alert('hellow TypeScript');
window.alert('こんにちは、型スクリプト');
window.alert('おしまい');
}*/

/*アロー関数*/
var hellow = () => {
window.alert('hellow TypeScript');
window.alert('こんにちは、型スクリプト');
window.alert(title + 'は第' + num + '回です。');
window.alert('おしまい');
}

/*変数
var btn = document.getElementById('btn');*/

/*変数(型付け)*/
var btn:object;
btn = document.getElementById('btn');

var title:string;
title = 'JS編';

var num:number;
num = 3;

/*イベント*/
btn.addEventListener('click', hellow, false);

コンパイル実行するがエラー

コンパイルを実行!(ドキドキ)

npx gulp ts

結果、エラー…

 error TS2339:Property 'addEventListener' does not exist on type 'object'.
  • エラーTS2339:プロパティ 'addEventListener'はタイプ 'object'に存在しません。

むむ?addEventListenerは存在しないってどういうこと?JSの正規なクリックイベントなんだが。

色々調べてみる。

こちらの記事ではグローバルにTypeScriptをインストールしている。

※参考:Gulp で TypeScript をコンパイル & tsify で連結 – Gulp で作る Web フロントエンド開発環境 #4 – PSYENCE:MEDIA

入れてみる(アクセス権限でsudoが必要だった)→結果変わらず。。

sudo npm install -g typescript

clickを変数に入れてEventName.CLICKという形で呼び出す?→結果変わらず。

※参考:TypeScriptでのイベント名をclickで指定するのはもう辞めよう - Qiita

変数btnの頭に<HTMLElement>を加える→結果変わらず。

※参考:TypeScriptでビルドエラーになった時の対処法(property 'XXXX' does not exist on type 'XXXX')

if (!btn)でbtnが見つからなかった場合の処理を書く→結果変わらず。

※参考:TypeScriptを1週間さわったのでオススメしてみる - sansaisoba's tech blog

型指定をなくしたら解決した!

最終的に解決したのはこの記事によって!

※参考:合法 TypeScript 第1章 Introduction

// Error: "foo" という property を obj に定義するのを忘れていませんか?

const obj = {} obj.foo

// Error TS2339: Property 'foo' does not exist on type '{}'.

そうか、変数btnをオブジェクト型にしてたけど、その中にaddEventListenerというプロパティが設定されませんよ、と教えてくれてるわけか!?

/*変数(型付け)*/
//var btn:object;
var btn = document.getElementById('btn');

変数btnの型の指定をなくしてみる。

コンパイルを実行!

再度実行する(ドキドキ)

npx gulp ts

結果

Finished 'ts' after 2.05 s

やた!成功!

ファイルが書き出された!

gulp_ts
├css
│└common.css
├js
│├common.ts
│└common.js //書き出された!
├index.html
└gulpfile.js

JSコード

/*関数
function hellow(){
window.alert('hellow TypeScript');
window.alert('こんにちは、型スクリプト');
window.alert('おしまい');
}*/
/*アロー関数*/
var hellow = function () {
    window.alert('hellow TypeScript');
    window.alert('こんにちは、型スクリプト');
    window.alert(title + 'は第' + num + '回です。');
    window.alert('おしまい');
};
/*変数
var btn = document.getElementById('btn');*/
/*変数(型付け)*/
//var btn:object;
var btn = document.getElementById('btn');
var title;
title = 'JS編';
var num;
num = 3;
/*イベント*/
btn.addEventListener('click', hellow, false);

ブラウザで動作確認

ブラウザで動作確認してみる。

開いた状態 f:id:idr_zz:20191225222143p:plain

アラート1:hellow TypeScript f:id:idr_zz:20191225222051p:plain

アラート2:こんにちは、型スクリプト f:id:idr_zz:20191225222055p:plain

アラート3:JS編は第3回です f:id:idr_zz:20191225222058p:plain

アラート4:おしまい f:id:idr_zz:20191225222101p:plain

CodePenと同じ挙動になった!

最後に

TypeScriptを初めてコンパイルできました!今回はエラーが起きてなかなか苦戦しました。CodePenでは問題なかった書き方もコンパイルではエラーになる。もっと厳密なことがわかりました。しかし、これによって未然にエラーを防ぐ

型を静的にするメリットはこの記事がわかりやすかったです。

※参考:ワイ「いうても型なんて面倒くさいだけやろ?」 - Qiita

ハリー先輩「変数や関数のあるべき使い方を自分で定義して」
ハリー先輩「その通りに実装せんと前に進めへん」
ハリー先輩「これだけでちょっとしたテスト駆動開発みたいになるやん?」

しかも、TypeScriptが用意する型だけでなく自分で独自の型も設定できると!(例にある自動販売機に入れられる硬貨、紙幣とか)

エラーコードの読み方にもう少し慣れたらもっとメリットを感じることができると思います。

※参考:逆引きマニュアル: JavaScriptからTypeScriptへの変換方法(コンパイルを通すまで) | ikemo memo

複数人作業の規模になるとより有効になるように思いました。

次回はBabelのコンパイルについて調べようと思います。それではまた!


※参考:メタ言語(HTMLテンプレートエンジン、AltCSS、AltJS)まとめ
qiita.com