megutech

自身の備忘録として主にWEBサーバー周りの技術について投稿しています。

Laravel mixのVue.jsをTypeScriptにしていく

はじめに

Node.js案件でTypeScriptを使ったところ便利すぎてほれ込んだので、Laravel mixで使っていたvueもTypeScript化していく事に。

とはいえ新規案件ならともかく既にある程度の大きさになっているので少しずつTypeScript化していく。

前提

Service Ver
Laravel 5.7
Vue.js 2.6.10
TypeScript 3.5.3
npm 6.9

必要なパッケージのインストール

$ npm install --save-dev ts-loader typescript vue-property-decorator babel-plugin-syntax-object-rest-spread

必要な追加ファイルをそろえる

ルートディレクトリに以下を追加。

オプションなどは適宜自由に変えてください。

tsconfig.json

{
  "compilerOptions": {
    "module": "commonjs",
    "target": "es5",
    "noUnusedLocals": true,
    "noUnusedParameters": true,
    "noFallthroughCasesInSwitch": true,
    "inlineSourceMap": true,
    "experimentalDecorators": true,
    "emitDecoratorMetadata": true,
    "allowSyntheticDefaultImports": true,
    "declaration": false,
    "lib": [ "dom", "es2015" ]
  },
  "include": [
    "resources/assets/js/**/*"
   ],
  "exclude": ["node_modules"]
}

.babelrc

{
    "env": {
        "test": {
            "presets": [
                ["env", {
                    "targets": {
                        "node": "current"
                    }
                }]
            ]
        },
        "development": {
            "presets": [
                ["env", {
                    "modules": false,
                    "targets": {
                        "browsers": "> 2%",
                        "uglify": true
                    }
                }]
            ]
        },
        "production": {
            "presets": [
                ["env", {
                    "modules": false,
                    "targets": {
                        "browsers": "> 2%",
                        "uglify": true
                    }
                }]
            ]
        }
    },
    "plugins": ["syntax-object-rest-spread"]
}

Vue.jsのTypeScript定義ファイルの用意

適当な場所にディレクトリを切って定義ファイルを用意。

resources/assets/js/types/index.d.ts

declare module '*.vue' {
    import Vue from 'vue'
    export default Vue
}

webpack.mix.jsの編集

webpack.mix.js

-mix.js('resources/assets/js/app.js', 'public/js')
+mix.ts('resources/assets/js/app.ts', 'public/js')

mix.webpackConfig({
   resolve: {
       extensions: [".js", ".jsx", ".vue", ".ts", ".tsx"],
       alias: {
           'vue$': 'vue/dist/vue.esm.js',
       }
   },
    module: {
        rules: [
            {
                test: /\.tsx?$/,
                loader: "ts-loader",
                options: { appendTsSuffixTo: [/\.vue$/] },
                exclude: /node_modules/
            }
        ]
    }
})

app.jsをapp.tsへ

resources/assets/js/app.js -> resources/assets/js/app.ts

import Vue from 'vue'

import router from './router'

/**
 * Next, we will create a fresh Vue application instance and attach it to
 * the page. Then, you may begin adding components to this application
 * or customize the JavaScript scaffolding to fit your unique needs.
 */

import component from './pages/App.vue'
Vue.component('App', component)

const app: any = new Vue({
    router
})
app.$mount('#app')

しれっと vue-router をインストールしてますが、まあ気にしないでください。

実際に稼働中の物をts化していく際は、const hoge: any = require('./hoge') みたいな感じで全部 any で定義すればとりあえず動きます。そして後でゆっくりTypeScript化していってくださいな。

Let's Compile!!

$ npm run dev

これで動かなかったらエラーいっぱい出ます。

いっぱい出たらググって解消していってください。

私がTypeScript化した時に出たエラーが何だったか覚えてないです。。。(何のためのこのブログ)

一応覚えている限り、 ts-loader のバージョンが新しすぎて怒られたので戻した案件もありました。

でもほぼ同条件なのに怒られないものもあるので不思議。いろいろ勉強しなきゃ。。。

おわり

以上でTypeScript化完了です。

実際に開発をするなら eslint なども入れていくとは思いますし、ComponentやVuexもTypeScriptしていくわけですが、そのあたりは気が向いたらいずれ別の記事で。

(本業はサーバーサイドなのであんまり記事にしないと思う。。。)