wildhart:vue-typescript-babel

v2.0.0•Published 2 months ago

Integrate TypeScript with vue single-file components for Meteor

This meteor package adds TypeScript support in your single-file .vue components.

wildhart:vue-typescript-babel is a Meteor 3 compatible republish of nathantreid:vue-typescript-babel, created by Nathan Reid (@akanix42). All credit to the original author. Changes from nathantreid:vue-typescript-babel@1.0.3:

  • The typescript lang handler is a plain synchronous function instead of a fiber-based Meteor.wrapAsync wrapper, which cannot return a result on Meteor 3 (no fibers).
  • Depends on wildhart:npm-check (Meteor 3 republish of akryum:npm-check).
  • Rebuilt and published with the Meteor 3 toolchain (the 1.0.3 isopack bundles a fibers-era promise package that throws Cannot find module 'fibers' at plugin load on Meteor 3).
  • 2.0.0: optional modern build output via vueTypescriptBabel.useBabel: false in the app's package.json (see Modern build output below). The default behaviour is identical to 1.1.0; the major bump only exists so the version solver never moves an existing app onto the new code without a human present.

Scope and support status

Read this before adopting:

  • Vue 2 only. This package is a lang handler for the Vue 2 single-file-component toolchain (vue-component from Akryum/vue-meteor). It does not support Vue 3 - the surrounding SFC compiler is Vue 2, so a Vue 3 Meteor app needs a different build path entirely.
  • Verified: options-API script blocks (<script lang="ts"> exporting a plain component options object), on Meteor 3.5 in a production app.
  • NOT verified: class components (vue-class-component / decorators). The upstream repo's own issue tracker reports them broken (akanix42/meteor-vue-typescript-babel#6), and this plugin only wires @babel/plugin-transform-typescript into the Babel options - no decorators plugin - so decorator syntax will most likely fail to parse. The class-component example below is inherited from the upstream README and is kept only for reference. If you get class components working (probably by adding @babel/plugin-proposal-decorators to the compiler), a PR is welcome.

Prerequisites

This package is an add-on for a Meteor 3 compatible republish of akryum:vue-component, such as bslocombe:vue-component@0.16.2. You must first have that package installed.

Your app must also provide the Babel TypeScript transform (the Babel 7 line):

meteor npm install --save-dev @babel/plugin-transform-typescript@^7

Installation

meteor add wildhart:vue-typescript-babel

Usage

Set your script's lang attribute to ts or typescript:

1<script lang="ts">
2  let message: string;
3
4  export default {
5    mounted() {
6      message = 'world';
7      console.log(`Hello, ${message}!`);
8    }
9  }
10</script>

Or with vue-class-component (untested - likely broken, see Scope and support status):

1<script lang="typescript">
2  import Vue from 'vue'
3  import Component from 'vue-class-component'
4
5  let message: string;
6
7  @Component
8  class MyButton extends Vue {
9    mounted() {
10      message = 'world';
11      console.log(`Hello, ${message}!`);
12    }
13  }
14    
15  // The export default has to be on a separate line due to the way the code is transpiled.
16  export default MyButton;
17</script>

Modern build output (opt-in)

By default, the compiled script block is handed back to vue-component for a second Babel pass (useBabel: true). That second pass is arch-blind and targets ES5, so every .vue script block is down-levelled to ES5 + regeneratorRuntime even in the modern web.browser bundle - while plain .ts/.js modules in the same app keep native async/await. The second pass adds nothing: this package's own compile already IS Meteor's arch-aware BabelCompiler (babel-preset-meteor, modern preset on web.browser, reify module transform included).

If - and only if - your app builds a single web architecture, you can skip the second pass and get modern output for .vue script blocks. Opt in from your app's package.json with a top-level vueTypescriptBabel key. Shown here alongside the Meteor 3.3+ meteor.modern flags that keep dev/test builds to one web arch:

1{
2  "meteor": {
3    "modern": {
4      "webArchOnly": true,
5      "transpiler": false,
6      "minifier": false,
7      "watcher": true,
8      "cordova": false
9    }
10  },
11  "vueTypescriptBabel": {
12    "useBabel": false
13  }
14}

Notes on that example:

  • vueTypescriptBabel.useBabel is read by THIS package. It is a separate top-level key, not part of the meteor section. Only the literal value false changes anything; omit the key entirely for the default (1.x-identical) behaviour.
  • meteor.modern.webArchOnly: true is what stops dev/test builds producing web.browser.legacy (upgraded apps do NOT get this by default). The other keys are shown because once a meteor.modern object exists, unspecified keys default to true - a bare {"webArchOnly": true} would also silently enable the SWC transpiler, minifier and watcher. Set each one deliberately.
  • Production meteor build filters archs independently of meteor.modern - exclude the legacy arch there too, via --exclude-archs web.browser.legacy or the METEOR_FORCE_EXCLUDE_ARCHS=web.browser.legacy environment variable (the latter is the only option under deploy tools like mup, which cannot pass build flags).
  • Cordova counts as a second web arch (web.cordova) - don't opt in if you build mobile platforms.

Why single-arch only: vue-component's compile cache keys on the source file hash and ignores the build architecture, and its on-disk cache persists across builds. With useBabel: false the cached output is arch-specific, so a build with two web archs would nondeterministically serve one arch's compiled output to the other (e.g. modern JS to legacy clients). To convert most of that silent corruption into a loud failure, this package throws a build error if it is opted in and receives a file for any web arch other than web.browser. The guard is not airtight - a warm vue-component cache can skip the lang handler entirely - so treat it as a backstop, not permission to try.

Importing TypeScript files

This plugin only handles compilation of TypeScript within .vue files. To import other TypeScript files, you must install a .ts compiler such as nathantreid:typescript-babel or barbatus:typescript.

TypeScript compilation notes

The Babel TypeScript compiler performs transpilation only; type-checking is not supported. As a result, this plugin currently doesn't provide type checking.