Laravel MixでTypeScriptを使う

こんにちは。フリーランス・コンサルタント&エンジニアの 九保すこひ です。

さてさて、前々回「Vue 3の新しい機能と変更点・全9件」という記事を紹介しましたが、この中でひとつ気になるところがありました。

それは、

Vue 3はTypeScriptをサポートしました

という部分です。

個人的には、JavaScriptをビルドするというのはあまり好きではないのですが、TypeScriptの評判がいいのは日々実感していたので、「食わず嫌い」にならないよう体験してみることにしました。

そこで!

今回はLaravel MixTypeScriptを使う方法をご紹介します。

ぜひ楽しみながらやってみましょう!

最近マイクロソフトがマジ本気ですよね❗

 

開発環境: Laravel 7.x、TypeScript 3.8.3

準備する

TypeScriptをインストールする

まずパソコンのどこからでもTypeScriptが実行できるようにします。
以下のコマンドを実行してください。

npm install -g typescript

インストールが完了するとtscというコマンドが使えるようになっています。
確認のためにバージョン情報を表示してみましょう。

tsc --version

※この記事を書いている時点(2020.3.30)で3.8.3でした。

TypeScriptの設定をする

続いてLaravelのフォルダに移動し、以下のコマンドを実行します。

tsc --init

すると、tsconfig.jsonというファイルが作成され、この中でTypeScriptの設定ができるようになります。

ちなみに、この中でコンパイル後のJavaScriptバージョンを指定することができます。

初期値はES5となっていますが、すでにIEのサポートも切れているので今回はアロー関数などが使えるES2015(ES6)に変更してみましょう。(もちろん、お好みでOKです)

/tsconfig.json

{
  "compilerOptions": {
    
    // 省略

    "target": "ES2015" // 👈 ここ
    
    // 省略

  }
}

Laravel Mix(webpack)の設定をする

最後にwebpackTypeScriptを使えるようにしましょう。

/webpack.mix.js

mix.js('resources/js/app.js', 'public/js')
    .sass('resources/sass/app.scss', 'public/css')
    .ts('resources/ts/app.ts', 'public/js/app.js'); // 👈 ここ

もし、フォルダ内全てのファイルを対象にする場合はこのようになります。

mix.js('resources/js/app.js', 'public/js')
    .sass('resources/sass/app.scss', 'public/css')
    .ts('resources/ts/**/*', 'public/js/app.js'); // 👈 ここ

では、これで準備は完了です!
次からは実際にTypeScriptを書いてみましょう。

Laravel MixでTypeScriptを使う

シンプルなテスト

では、テストとして次のようなTypeScriptを作ってみます!

/resources/ts/app.ts

export function message(name: string): string {

    return `${name} さん、こんにちは。`;

}

そして、作成したTypeScriptコードを読み込みます。

/resources/js/app.js

window.message = require("../ts/app").message; // 👈 追加

では、この状態でビルドしましょう。

npm run dev

すると、次のようにコンパイルされました。

/public/js/app.js

// 省略

/***/ (function(module, exports, __webpack_require__) {

"use strict";

Object.defineProperty(exports, "__esModule", { value: true });
function message(name) {
    return `${name} さん、こんにちは。`;
}
exports.message = message;


/***/ }),

では次のようなコードを実行してみましょう。

<html>
<body>
    <script src="/js/app.js"></script>
    <script>

        console.log(message('山田太郎'));

    </script>
</body>
</html>

コンソールに「山田太郎 さん、こんにちは。」と表示されました。

うまくいきました😊✨

Vueコンポーネントをつくってみる

では、せっかくですのでTypeScriptVueコンポーネントもつくってみましょう。
作成するのは、あいさつ文が時間帯で切り替わるシンプルなものです。

/resources/ts/app.ts

import Vue from 'vue'

const MessageComponent = Vue.extend({
    props: {
        name: {
            type: String,
            required: true
        },
    },
    methods: {
        greeting(): string {

            const d: Date = new Date();
            const hours: number = d.getHours();
            let greeting = '';

            if(hours >= 18 || hours <= 3) { // 夜

                greeting = 'こんばんは!';

            } else if(hours >= 12) { // 昼

                greeting = 'こんばんは!';

            } else { // 朝

                greeting = 'おはようございます!';

            }

            return greeting;

        }
    },
    computed: {
        text(): string {

            return `${this.name} さん、${this.greeting()}`;

        }
    },
    template: '<div v-text="text"></div>'
});

export {
    MessageComponent
}

そして、呼び出す側はこのように変更してください。

/resources/js/app.js

window.MessageComponent = require('../ts/app.ts').MessageComponent;

では、この状態でビルドします。

npm run dev

ビルドが終わったらビューをつくりましょう。

/resources/views/typescript.blade.php

<html>
<body>
    <div id="app">
        <message-component name="山田太郎"></message-component>
    </div>
    <script src="{{ mix('/js/app.js') }}"></script>
    <script>

        new Vue({
            el: '#app',
            components: { // 👈 コンポーネントをセット
                MessageComponent
            },
        });

    </script>
</body>
</html>

最後に、以下のルートを追加してブラウザで確認します!

/routes/web.php

Route::get('typescript', function(){

    return view('typescript');

});

表示はこうなりました。

成功です😊✨

⚠ もしエラーが出たら・・・

もしコンソールにVue is not a constructorというエラーが出たら、vueを読み込んでいる部分に.defaultを追加してください。(どうやらエクスポート形式が変更になるようです)

/resources/js/app.js

window.Vue = require('vue').default; // 👈 ここ

おまけ:app.jsのキャッシュを無効にする方法

今回のようにビルドをする場合、たまに問題になるのが「キャッシュ」です。

つまり、ブラウザが過去のソースコードを使いまわしている訳ですが、これではせっかくビルドしても古い動きしか確認できません。

そのため、この問題点を回避する方法をご紹介します。

まず、webpack.mix.jsversion()を追加します。

/webpack.mix.js

mix.js('resources/js/app.js', 'public/js')
    .sass('resources/sass/app.scss', 'public/css')
    .ts('resources/ts/app.ts', 'public/js/app.js')
    .version(); // 👈 ここ

そして、ビルドしたapp.jsを読み込む部分でmix()というヘルパー関数を使います。

<script src="{{ mix('/js/app.js') }}"></script>

こうすることで、ビルドするごとに作成されたランダムなパラメータがURLに追加され、毎回新しいソースコードが読み込まれることになります。

<!-- 👇 ビルドするごとにランダムなパラメータが変更になる -->
<script src="/js/app.js?id=d0cab0115e4a4fdcfb8e"></script>
開発のご依頼お待ちしております
開発のご依頼はこちらから: お問い合わせ
どうぞよろしくお願いいたします! by 九保すこひ

おわりに

ということで、今回はLaravel MixTypeScriptを使う方法をご紹介しました。

TypeScriptは、Javaのように型を厳格に決めることができるので、よりエラーが発生しにくいコードが書けるのが特徴です。

また、純粋なJavaScriptでは使えない「インターフェイス」などの機能もあるので、これらを活用することでよりコード量を減らすことができるんじゃないでしょうか。

なお、自動的に実行可能とはいえ、やはりビルドは開発テンポが悪くなったり、保守作業をしようという気持ちが削がれるので、ぜひ今後は純粋なJavaScriptで同じ機能が使えるようになればいいなと考えていました。(もしかすると、ES2016以降ですでに予定してる❓❓)

EdgeChromiumベースになりましたし、以前より期待しています😊✨

ではでは〜!

「はじめてTypeScriptコードを見たとき、
『Javaじゃん!』とつぶやきました😂」

このエントリーをはてなブックマークに追加       follow us in feedly