クモのようにコツコツと

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

【gulp】Sass(SCSS)とTypeScriptを同時にコンパイルする環境を作る

gulpの続きです。gulpでメタ言語を同時にコンパイルしたい。前回はその準備編としてSass(SCSS)を「src」フォルダから「dest」フォルダにコンパイルするファイル構成にしました。今回はここに他のメタ言語のコンパイル設定も加えていきます。まずはAltJSのTypeScriptから。それではいきましょう!

【目次】

※参考:【gulp】Sass(SCSS)以外のメタ言語をコンパイルするためフォルダ構成(src→dest) - クモのようにコツコツと

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

前回のファイル構成

前回のファイル構成はこちら

glup_frontend
├node_modules(中身は省略)
├src
│└scss
│ ├common.scss
│ └other.scss
├dest
│├css
││├common.css
││└other.css
│├js
││└common.js
│├index.html
│└other.html
├gulpfile.js
├package.json
└package-lock.json

gulpタスクを実行すると「src」フォルダの中のscssファイルが「dest」フォルダにcssファイルとしてコンパイルされる。また、「browser-sync」によって修正のたびに自動リロード、自動コンパイルされる。

詳細は前回記事参照

※参考:【gulp】Sass(SCSS)以外のメタ言語をコンパイルするためフォルダ構成(src→dest) - クモのようにコツコツと

今回はここに他のメタ言語も追加したい。

AltJSはTypescriptを選定

メタ言語、まずはAltJSから追加したい。AltJSのコンパイルはこれまでTypeScriptとBabelを行った。

※参考:【JS】TypeScriptをGulpでコンパイルしてみる - クモのようにコツコツと

※参考:【JS】BabelでESをコンパイルする - クモのようにコツコツと

Babelは最新のESをES5にコンパイルする。TypeScriptはESの要素はありつつさらに変数に型を指定できる。こちらのほうが用途が広いのでTypeScriptを使うことにする。

TypeScript単体のコンパイルはこちらを参照。

※参考:【JS】TypeScriptをGulpでコンパイルしてみる - クモのようにコツコツと

f:id:idr_zz:20200424063646p:plain

この時は「js」フォルダの中でtsファイルをjsファイルにコンパイルした。今回はこれをSass(SCSS)と同じく「src」→「dest」にコンパイルする構成にしたい。

gulp-typescriptをインストール

まずターミナルのcdコマンドで「gulp_frontend」フォルダに移動する。

cd /(フォルダ)/gulp_frontend

TypeScriptをJSにコンパイルする「gulp-typescript」パッケージをインストールする。

npm install -D gulp-typescript

成功するとpackage.jsonに追記される!

  "devDependencies": {
    "browser-sync": "^2.26.7",
    "gulp": "^4.0.2",
    "gulp-sass": "^4.0.2",
    "gulp-typescript": "^6.0.0-alpha.1"
  }

gulpfile.js全体(修正前)

gulpの設定が書かれている「gulpfile.js」、前回はこうだった。

const gulp = require('gulp');
const sass = require('gulp-sass');
const browserSync = require('browser-sync'); 

// sassコンパイル
gulp.task('sass', (done) => {
    gulp.src('./src/scss/*.scss')
        .pipe(sass({
                    outputStyle: 'expanded'
                })
            )
        .on("error", sass.logError)
        .pipe(gulp.dest('./dest/css'));
    done();
});

// リロードするhtml
gulp.task('browser-sync', (done) => {
    browserSync.init({
        server : {
            baseDir : './dest/',
            index : 'index.html',
        },
    });
    done();
});

// リロード設定
gulp.task('browser-reload', (done) => {
    browserSync.reload();
    done();
});

// 監視ファイル
gulp.task('watch-files', (done) =>  {
    gulp.watch("./dest/*.html", gulp.task('browser-reload'));
    gulp.watch("./dest/css/*.css", gulp.task('browser-reload'));
    gulp.watch("./src/scss/*.scss", gulp.task('sass'));
    gulp.watch("./dest/js/*.js", gulp.task('browser-reload'));
    done();
});

// タスク実行
gulp.task('default', gulp.series( gulp.parallel('watch-files', 'browser-sync', 'sass'), (done) => {
    done();
}));
  • 冒頭でgulpgulp-sassbrowser-syncを読み込んでいる
  • gulp.tasksassでsassコンパイルを設定
  • gulp.taskbrowser-syncでリロードするhtmlを設定
  • gulp.taskbrowser-reloadでリロード設定
  • gulp.taskwatch-filesで監視ファイルを設定
  • gulp.taskdefaultで複数のタスクを同時に実行

タスク名defaultにするとタスク名なしの「gulp」だけで実行できるようになる。

詳細は前回の記事を参照。

※参考:【gulp】Sass(SCSS)以外のメタ言語をコンパイルするためフォルダ構成(src→dest) - クモのようにコツコツと

gulpfile.jsを修正(TypeScript設定を追加)

gulp-typescript読み込み

まず冒頭にgulp-typescriptを読み込む設定を追加

const typescript = require('gulp-typescript');
  • 変数typescriptrequire()メソッドでgulp-typescriptを読み込む

TypeScriptのコンパイル設定

tsというgulp.task()を作ってTypeScriptのコンパイルを設定する。

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

前回の記事の合わせてreternを使わない書き方にして、フォルダも「src」→「dest」構成にしてみた。

監視ファイルにTypeScriptを追加

gulp.watch()の常時監視にTypeScriptの設定を追加

// 監視ファイル
gulp.task('watch-files', (done) =>  {
    gulp.watch("./dest/*.html", gulp.task('browser-reload'));
    gulp.watch("./dest/css/*.css", gulp.task('browser-reload'));
    gulp.watch("./src/scss/*.scss", gulp.task('sass'));
    gulp.watch("./dest/js/*.js", gulp.task('browser-reload'));
    gulp.watch("./src/ts/*.ts", gulp.task('ts')); // ←追加
    done();
});
  • gulp.watch()メソッドに.tsファイルのパスとtsタスクを追加

タスクの同時実行にTypeScriptを追加

最後にタスクを同時に実行するdefaultタスクにTypeScriptコンパイルのタスクを追加する。

// タスク実行
gulp.task('default', 
    gulp.series(gulp.parallel(
        'watch-files', 'browser-sync', 'sass', 'ts'
    ), (done) => {
    done();
}));
  • gulp.series()メソッドのgulp.parallel()の中にtsを追加する。

これで動くかな?実際にTypeScriptのファイルを作ってみよう。

TypeScriptのファイルを作成

「src」フォルダの中に「ts」フォルダを作る。

srcフォルダの中に「ts」フォルダを作り、その中に「common.ts」を作成する

glup_frontend
├node_modules(中身は省略)
├src
│├scss
││├common.scss
││└other.scss
│└ts // ←追加
│ └common.ts // ←追加
├dest
│├css
││├common.css
││└other.css
│├js
││└common.js
│├index.html
│└other.html
├gulpfile.js
├package.json
└package-lock.json

common.tsファイルの作成

「common.ts」にTypeScriptコンパイルの時のコードを書く。

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

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

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

const num: number;
num = 3;

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

ボタンを押すとアラートが立ち上がるクリックイベントだが変数titlenumに型を設定している*1。また、変数の宣言をconstにしてみた。

詳細はこちらの記事を参照

※参考:【JS】TypeScriptをGulpでコンパイルしてみる - クモのようにコツコツと

HTMLの修正

srcフォルダのindex.htmlにボタンを追加

<section id="oya">
    <h2>TypeScriptで書いたクリックイベント</h2>
    <button id="btn">ここ押せワンワン</button>
</section>

TypeScriptがちゃんとコンパイルされたらこのボタンのクリックイベントが動くはず!

jsファイル(コンパイル前)

ではいよいよ動作確認をしよう!

「dest」フォルダの「js」フォルダにある「common.js」は前回のまま。

window.onload = () => {
    console.log("成功したでござる!");
}

※参考:【gulp】Sass(SCSS)以外のメタ言語をコンパイルするためフォルダ構成(src→dest) - クモのようにコツコツと

これがどうなるか??

コンパイル処理が動かない!(追加のインストール)

「モジュールがないよ」エラー

ターミナルからgulpタスクを実行!

npx gulp

ありゃ、エラーになった。。

Error: Cannot find module 'typescript'

「モジュールがないよ」という意味のエラーのようだ。

※参考:gulp導入後モジュールが見つかりませんって言われた | Masahiro's tech note

TypeScriptをインストールするといいらしい。

TypeScriptをインストール

TypeScriptはすでにグローバルに入っているはずだが、もう一回入れてみる。

npm install typescript

お、ローカルにも入った。package.jsonにも追記されとる。

  "devDependencies": {
    "browser-sync": "^2.26.7",
    "gulp": "^4.0.2",
    "gulp-sass": "^4.0.2",
    "gulp-typescript": "^6.0.0-alpha.1"
  },
  "dependencies": {
    "typescript": "^3.8.3"
  }

devDependenciesではなくdependenciesに入った。入れ方によって名前が変わるんだ。この2つ以外にも種類がある。

※参考:ちゃんと使い分けてる? dependenciesいろいろ。 - Qiita

gulp再実行!

npx gulp

結果は変わらず。。

gulp-typescriptをインストール

「gulp-typescript」公式ページを見ると

※参考:gulp-typescript - npm

gulp-typescriptもグローバルにいれろと?

npm install gulp-typescript

入れてみて、再度実行すると

npx gulp

おお!コンパイル処理が始まった!

コンパイルエラーを修正

変数宣言をconst→letに変更

しかし、処理中にさっきとまた違うエラーが…

src/ts/common.ts(13,7): error TS1155: 'const' declarations must be initialized.
src/ts/common.ts(14,1): error TS2588: Cannot assign to 'title' because it is a constant.
src/ts/common.ts(16,7): error TS1155: 'const' declarations must be initialized.
src/ts/common.ts(17,1): error TS2588: Cannot assign to 'num' because it is a constant.

訳すと

src / ts / common.ts(13,7):エラーTS1155: 'const'宣言を初期化する必要があります。
src / ts / common.ts(14,1):エラーTS2588:定数であるため、「title」に割り当てられません。
src / ts / common.ts(16,7):エラーTS1155: 'const'宣言を初期化する必要があります。
src / ts / common.ts(17,1):エラーTS2588:定数であるため、「num」に割り当てられません。

constは定数なので割り当てができません?

あ、そうか。変数を定義したすぐ下の行で変数に値を再代入しているから…

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

constではなくletにすべきなんだ!

変数宣言の挙動についてはこちらを参照。

※参考:【JS】変数 varとletとconst(再代入、再宣言の挙動の違い) - クモのようにコツコツと

「common.js」の変数宣言をconstからletに変更する。

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

let num: number;
num = 3;

で、再実行〜

npx gulp

ターゲットライブラリを変更?

おお、まだエラーは残っている…。

error TS2583: Cannot find name 'Set'. Do you need to change your target library? Try changing the `lib` compiler option to es2015 or later.

えーとこれは…

エラーTS2583:名前「セット」が見つかりません。 ターゲットライブラリを変更する必要がありますか? `lib`コンパイラオプションをes2015以降に変更してみてください。

むむむ?どゆこと?Setlibも「common.js」ではなく「node_modules」フォルダの中のファイルにある記述。ここは自分では触りたくないなー。。

tsconfig.jsonを作成

どうやら「tsconfig.json」というTypeScriptの設定ファイルを修正したほうがよさそうなんだが、そもそもそのファイルを作ってない!

※参考:Typescript の tsconfig.json の簡単作成方法と設定について - ラクするアプリ研究所

このコマンドで作成できるようだ。作ってみよう。

tsc --init

「tsconfig.json」が追加された!

glup_frontend
├node_modules(中身は省略)
├src
│├scss
││├common.scss
││└other.scss
│└ts
│ └common.ts
├dest
│├css
││├common.css
││└other.css
│├js
││└common.js
│├index.html
│└other.html
├gulpfile.js
├package.json
├package-lock.json
└tsconfig.json // 追加!

「tsconfig.json」はこんな内容

{
  "compilerOptions": {
    /* Basic Options */
    // "incremental": true,                   /* Enable incremental compilation */
    "target": "es5",                          /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', or 'ESNEXT'. */
    "module": "commonjs",                     /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */
    // "lib": [],                             /* Specify library files to be included in the compilation. */

    // (後略)

  }
}

ダメもとでこの状態でgulpを実行してみる。

npx gulp

うむ、結果は変わらず。

tsconfig.jsonのlibにes6を追加

で、だ。

「tsconfig.json」のぉ〜、lib項目にぃ〜、es6を〜、追加してみる!

    "lib": ["es6"],                             /* Specify library files to be included in the compilation. */

コメントアウトになっていたのでコメントアウトを解除してみた。

※参考:TypeScriptのコンパイル時に『error TS2304: Cannot find name 'Map'.』が出た時の対応 - Qiita

gulp実行。どうか?

npx gulp

あー、やはり結果は変わらず。。

@types/nodeをインストール

もう少し調べると「@types/node」をインストールするといいと!

Same here with target and lib as es6.
I've managed to fix this by installing @types/node@12.7.4

es6と同じようにtargetとlibを使用します。  
@ types / node @ 12.7.4をインストールすることでこれを修正することができました。

※参考:error TS2304: Cannot find name 'Set'. 815 allowedNodeEnvironmentFlags: Set<string>; · Issue #29172 · DefinitelyTyped/DefinitelyTyped · GitHub

「@types」はTypeScriptを拡張するパッケージらしい。例えばjQueryに拡張するのは「@types/jquery」を使ったり。

※参考:@types - TypeScript Deep Dive 日本語版

で「@types/node」はnodeにTypeScriptを拡張する。

Summary
This package contains type definitions for Node.js (http://nodejs.org/).

このパッケージには、Node.js(http://nodejs.org/)の型定義が含まれています。

※参考:@types/node - npm

インストールしてみる!

npm install --save @types/node

おお、package.jsonに追記された。

  "devDependencies": {
    "browser-sync": "^2.26.7",
    "gulp": "^4.0.2",
    "gulp-sass": "^4.0.2",
    "gulp-typescript": "^6.0.0-alpha.1"
  },
  "dependencies": {
    "@types/node": "^13.13.2",
    "typescript": "^3.8.3"
  }

typescriptと同じくdependenciesの方だな。

ブラウザ起動(イベント設定の修正)

ts→jsコンパイルされた

さあ、gulpを起動!

npx gulp

おお、ブラウザが立ち上がった! f:id:idr_zz:20200425110157j:plain

「dest」フォルダの中の「js」フォルダに「common.js」がコンパイルされた!

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

    /* イベント */
    btn.addEventListener('click', hellow, false);
  • アロー関数=>function宣言に変換されている
  • 型設定は亡くなっている
  • 変数宣言のconstletvarに変換されている。

JSのイベントがエラー

しかしボタンを押しても何もアラートが立ち上がらない。。

デベロッパーツール でみると下記のエラーが

Uncaught TypeError: Cannot read property 'addEventListener' of null

Uncaught TypeError:nullのプロパティ 'addEventListener'を読み取れません

こういう時はaddEventListener自体が問題なのではなく、その「前」のオブジェクトが見つかりませんという意味。

オブジェクトのプロパティへのアクセスではエラーは発生しないのです。かわりにundefinedが黙って返されます。そしてその返ってきたundefinedの何かにアクセスしようとして初めてエラーになります。

※参考:JavaScriptでよく見るエラーとその対策

addEventListener()btnに対して設定しているので

   let btn = document.getElementById('btn');

 // (中略)

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

btnが見つかりませんよ(undefined)ということ。

tsファイル修正(DOMContentLoadedで囲う)

どうやらjsファイルをheadタグでリンクしていると、HTMLのDOMが読まれる前にDOMを取得しようとしているため、見つからない。

※参考:JavaScript - 【JS】addEventListenerが機能しない理由についてご教示ください|teratail

bodyの閉じタグ直前でjsファイルをリンクするのもこれの対策だな。

参考記事にあったように「common.ts」の処理全体をDOMContentLoadedイベントで囲ってみる。

document.addEventListener("DOMContentLoaded", () => {

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

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

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

    let num: number;
    num = 3;

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

}, false);

ちなみにDOMContentLoadedイベントはDOMが読み終われた後、loadイベントは画像なども全て読み込まれた後に実行される。

※参考:DOMContentLoadedイベントとloadイベントの違い[タイミング]

エラーなくなる!

この状態でボタンを押すと…
f:id:idr_zz:20200425112034j:plain おお、アラートが立ち上がった!

「common.js」の内容も修正される

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

一度しかコンパイルされない

tsconfig.jsonのlibを修正

しかし、その後に「index.ts」を保存してもTypeScriptのコンパイルがされない?

ブラウザのデベロッパーツール にはエラーはない。

しかしテキストエディタ(VSCode)の「Problem」タブを見るとエラーが…

Cannot find name 'document'. Do you need to change your target library? Try changing the `lib` compiler option to include 'dom'.

「ドキュメント」という名前が見つかりません。 ターゲットライブラリを変更する必要がありますか? domを含めるようにlibコンパイラオプションを変更してみてください。

これはTypeScriptのエラーメッセージのようだ。このせいでコンパイルされないのかも?

こちらのQ&Aによると「tsconfig.json」のlibキーにes6domを追加する方法が書かれていた。

※参考:javascript - Typescript cannot find name window or document - Stack Overflow

さっそくやってみる。

    "lib": ["es5", "es6", "dom"],   

お、先程のエラーがなくなった!

btnオブジェクトに「!」を追記

エラーはもう一つ残っている。

Object is possibly 'null'. typescript

これもTypeScriptのエラーだった。

elementがnullの可能性があるからダメだよってメッセージ

可能性があるだけでもダメなのね。厳密!

※参考:TypescriptでgetElementByIdを使ったら「Object is possibly 'null'.」のエラーが出た時の対処方法 | KAKIMASSE

参考記事を参考にbtnの後に!を追加してみる。

btn!.addEventListener('click', hellow, false);

おお、TypeScriptエラーがゼロになった!

この!ってなんじゃらほい?

非null(Non-null)アサーション演算子
新しい後ろに付加する(post-fix)式演算子である!は、 型チェッカーが断定することが出来ない状況で、そのオペランドが非null、非undefinedであることを主張することに使用できます。
具体的には演算子x!は、xの型の値をnullとundefinedを除外したもので生成します。

※参考:TypeScript 2.0 | TypeScript 日本語ハンドブック | js STUDIO

nullundefinedを型の値から除外したい時に付けるのか。

gulpのTypeScriptコンパイルのdone()が抜けていた!

これで再度「common.ts」を変更してみるが、まだコンパイルされない。うーむ。。

ターミナルを見ると最後の行、Browsersyncがリロード中のまま次の処理が始まらない。

[Browsersync] Reloading Browsers...

なぜだろう??

こちらの記事をみると「gulpfile.js」にdoneを追記することで動いたとあった。

※参考:【gulp.js】Browsersyncのリロード1回しかされない - Qiita

doneは入れているんだよなー、と再確認すると…

なんと!TypeScriptコンパイル設定のところにdone()が抜けていた!

// TypeScriptコンパイル
gulp.task('ts',  (done) => {
    gulp.src('./src/ts/*.ts')
        .pipe(typescript())
        .js
        .pipe(gulp.dest('./dest/js'));
    done(); // 追加
});

done()を追加しする。

これで「index.ts」を修正すると…

[Browsersync] Reloading Browsers...
[13:50:27] Starting 'ts'...
[13:50:27] Finished 'ts' after 18 ms
[13:50:32] Starting 'browser-reload'...
[13:50:32] Finished 'browser-reload' after 1.94 ms

おお!自動コンパイルされるようになった!

最終的な挙動

TypeScriptコンパイルの挙動

例えば「common.ts」の最初のアラートに「!」を10個追加すると…

    const hellow = () => {
        window.alert('hellow TypeScript!!!!!!!!!!');
        window.alert('こんにちは、型スクリプト');
        window.alert(title + 'は第' + num + '回です。');
        window.alert('おしまい');
    }

「common.js」もコンパイルされて…

    var hellow = function () {
        window.alert('hellow TypeScript!!!!!!!!!!');
        window.alert('こんにちは、型スクリプト');
        window.alert(title + 'は第' + num + '回です。');
        window.alert('おしまい');
    };

ブラウザも「!」が10個になる!!!!!!!!!! f:id:idr_zz:20200425135237j:plain

Sass(SCSS)コンパイルの挙動

「common.scss」にボタンの色を設定すると…

#nest ,
#oya {
  /*  (中略) */
  button {
    background: brown;
    color: #fff;
    padding: 10px;
  }
}

「common.css」もコンパイルて…

#nest button,
#oya button {
  background: brown;
  color: #fff;
  padding: 10px;
}

ブラウザのボタンの色も自動リロードで変わる! f:id:idr_zz:20200425142628j:plain

よし!ようやく期待通りの挙動になった。

gulpfile.js全体(修正後)

色々苦心したけど、最終的にこうなった

const gulp = require('gulp');
const sass = require('gulp-sass');
const typescript = require('gulp-typescript');
const browserSync = require('browser-sync'); 

// sassコンパイル
gulp.task('sass', (done) => {
    gulp.src('./src/scss/*.scss')
        .pipe(sass({
                    outputStyle: 'expanded'
                })
            )
        .on("error", sass.logError)
        .pipe(gulp.dest('./dest/css'));
    done();
});

// TypeScriptコンパイル
gulp.task('ts',  (done) => {
    gulp.src('./src/ts/*.ts')
        .pipe(typescript())
        .js
        .pipe(gulp.dest('./dest/js'));
    done();
});

// リロードするhtml
gulp.task('browser-sync', (done) => {
    browserSync.init({
        server : {
            baseDir : './dest/',
            index : 'index.html',
        },
    });
    done();
});

// リロード設定
gulp.task('browser-reload', (done) => {
    browserSync.reload();
    done();
});

// 監視ファイル
gulp.task('watch-files', (done) =>  {
    gulp.watch("./dest/*.html", gulp.task('browser-reload'));
    gulp.watch("./src/scss/*.scss", gulp.task('sass'));
    gulp.watch("./dest/css/*.css", gulp.task('browser-reload'));
    gulp.watch("./src/ts/*.ts", gulp.task('ts'));
    gulp.watch("./dest/js/*.js", gulp.task('browser-reload'));
    done();
});

// タスク実行
gulp.task('default', 
    gulp.series(gulp.parallel(
        'watch-files', 'browser-sync', 'sass', 'ts'
    ), (done) => {
    done();
}));

最後に

TypeScriptはSass(SCSS)より難産でした。

(やったこと)

  • gulp-typescriptインストール
  • gulpfile.jsの修正
  • TypeScriptインストール
  • tsconfig.json作成
  • @types/nodeインストール
  • JSにロードイベントを追加
  • TypeScriptのエラーをなくす
  • その他いろいろ修正

最終的にはやりたい挙動が実現できました!

  • 「src」フォルダの中にscssファイルがコンパイルされて「dest」フォルダにcssファイルに保存される
  • 「src」フォルダの中にtsファイルがコンパイルされて「dest」フォルダにjsファイルに保存される
  • scssファイルとtsファイルを修正するたびにブラウザも自動リロードされる

次回は更にHTMLテンプレートも組み込んでメタ言語3種(HTML、CSS、JS)揃った状態でコンパイルをしたいです。

それではまた!


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

*1:「btn」は前回エラーになったので指定していない