The joy that is Source Maps (with Vue.js and TypeScript) Dapper Extensions Reloaded: Version 3

Vue.js with TypeScript

Published on Monday, January 22, 2018 7:00:00 AM UTC in Programming

For quite some time now I've been watching the development of Vue.js, listened to talks and tutorials from time to time, read articles - but never made an attempt to actually use it. Why? Maybe I was under the impression that support for TypeScript (which is a main criteria for me with any framework) still is rather fragile and of low priority. Until I read the following a few days ago, that was:

[...] we have included official TypeScript type declarations [...] (Source).

I felt that now is the time to start some first experiments myself. And, frankly, I was pleasantly surprised how simple the setup was. Here's a step by step guide.

Preface

I make a few assumptions here; if you feel you want to set-up some of these details differently, you may have to change the steps that follow accordingly. I assume that you want to...

  • ... use Single File Components (SFC)
  • ... create class-style components in TypeScript
  • ... use WebPack

Agree? Good, go!

Prerequisites

These are not officially required, but I strongly recommend them to everybody:

  • For editing, I use Visual Studio Code. It has the excellent Vetur extension to support Vue.js, TypeScript and SFC.
  • For debugging and more, there's a Chrome extension (apparently also available for other browsers) to inspect your app in detail. Install it now.

Step-by-step guide

Make sure you have the CLI installed globally:

npm i -g vue-cli

Create a new app

This is quite simple:

vue init webpack my-fancy-project

Answer all the questions as you like, and there you go. By the end, you should be able to go to your new project folder and use:

npm run dev

... and have a running development environment that hosts your app on port 8080. But enough procastination, on to the important parts!

Install dev dependencies

For TypeScript support, install:

yarn add typescript ts-loader vue-property-decorator --dev

I'm using Yarn, and you should too. But NPM should be OK too, of course :).

Short explanation:

  • typescript is the actual TypeScript compiler
  • ts-loader is the required loader for WebPack
  • vue-property-decorator adds decorators that support writing class-based components. It also re-exports vue-class-decorator so you don't have to pull that in manually.

Next!

TypeScript compiler configuration

That one is simple: create a new tsconfig.json file in the root of your project folder, containing:

{
  "compilerOptions": {
    "lib": ["dom", "es5", "es2015"],
    "target": "es5",
    "strict": true,
    "module": "es2015",
    "moduleResolution": "node",
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true
  },
  "include": [
    "src/**/*"
  ]
}

There are some important/required parts, like:

  • The decorator stuff, to enable class-based components properly.
  • The target and module format to bring the output in line with what Vue.js supports.
  • Enabling strict options is always a good idea, but some parts are even required by Vue.js for better typing support.

Adjust WebPack

There's three things we need to do to configure WebPack:

  1. Make it work on TypeScript files in general.
  2. Make it understand what to do with TypeScript files in detail.
  3. Make sure it uses a TypeScript entry point instead of the current JavaScript one.

All of these are performed in the build/webpack.base.conf.js file of your project.

For the first issue, search for the resolve node and extend the extensions entry:

extensions: ['.ts', '.js', '.vue', '.json'],

Now, add a new node under module/rules:

{
  test: /\.ts$/,
  exclude: /node_modules/,
  loader: "ts-loader",
  options: {
    appendTsSuffixTo: [/\.vue$/]
  }
},

The interesting part here is the option to treat .vue files, because for SFC they will contain inline-TypeScript. We'll see that in a moment.

For the third issue, simply change the entry node's value to:

app: './src/main.ts'

Done!

Add a shim for .vue files

This step is required to tell the TypeScript compiler that importing .vue files is OK. It prevents build errors when you import from SFCs. Add a new file vue-shims.d.ts in your /src folder. You don't need to include it anywhere, it will be picked up automatically.

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

Only a few steps remaining now!

Rename files and fix broken stuff

Now is the time to rename the JavaScript files in your project (should only be main.js and, if you chose to configure it by the CLI, router/index.js).

With that done, what you still need to do is the following:

  • In all places that import from a .vue-file, you need to add the file extension. For example, in main.ts there's a line import App from './App' that you need to change to import App from './App.vue'.
  • In all Single File Components (SFC) you need to change the <script>-Tags to specify TypeScript as their language. For example, in HelloWorld.vue, change <script> to <script lang="ts">.

Start writing code

With that in place, you can write TypeScript class-components. For example, the original source in HelloWorld.vue (the script part) is:

export default {
  name: 'HelloWorld',
  data () {
    return {
      msg: 'Welcome to Your Vue.js App'
    }
  }
}

Change that to:

import { Component, Vue } from "vue-property-decorator";

@Component
export default class HelloWorld extends Vue {
  public msg: string = "Welcome to your Vue.js TypeScript App!";
}

Ahhhh, much better. SCNR :)

Note that you may need to close and restart Visual Studio Code to digest all these changes. The warnings about experimental decorators seem particularly stubborn and only disappeared for me once I re-opened the editor.

With that in place, you should be able to run the dev server again:

npm run dev

... and have a working environment, with full hot-reload functionality and TypeScript support.

Have fun!

Tags: SPA · TypeScript · Vue.js