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.wrapAsyncwrapper, which cannot return a result on Meteor 3 (no fibers). - Depends on
wildhart:npm-check(Meteor 3 republish ofakryum:npm-check). - Rebuilt and published with the Meteor 3 toolchain (the 1.0.3 isopack bundles a
fibers-era
promisepackage that throwsCannot find module 'fibers'at plugin load on Meteor 3). - 2.0.0: optional modern build output via
vueTypescriptBabel.useBabel: falsein the app'spackage.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-componentfrom 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-typescriptinto 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-decoratorsto 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.useBabelis read by THIS package. It is a separate top-level key, not part of themeteorsection. Only the literal valuefalsechanges anything; omit the key entirely for the default (1.x-identical) behaviour.meteor.modern.webArchOnly: trueis what stops dev/test builds producingweb.browser.legacy(upgraded apps do NOT get this by default). The other keys are shown because once ameteor.modernobject 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 buildfilters archs independently ofmeteor.modern- exclude the legacy arch there too, via--exclude-archs web.browser.legacyor theMETEOR_FORCE_EXCLUDE_ARCHS=web.browser.legacyenvironment 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.