npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

vue-template-compiler-compat

v0.4.2

Published

Provide compatibility for Vue 2 template compiler

Downloads

11

Readme

vue-template-compiler-compat

npm

Provide compatibility for Vue 2 template compiler.

[!NOTE] This is NOT an official library of Vue.

Installation

npm install --dev vue-template-compiler-compat

Usage

const { compile } = require('vue-template-compiler')
const { createCompatModule } = require('vue-template-compiler-compat')

compile('your template here', {
  modules: [
    createCompatModule({
      model: true,
      typescript: true,
    }),
  ],
})

Standalone usage

const { compile } = require('vue-template-compiler')

compile('your template here', {
  modules: [
    require('vue-template-compiler-compat/modules/model'),
    require('vue-template-compiler-compat/modules/typescript')
  ],
})

For vue-loader

const { createCompatModule } = require('vue-template-compiler-compat')

module.exports = {
  rules: {
    test: /\.vue$/,
    use: [
      {
        loader: 'vue-loader',
        options: {
          compilerOptions: {
            modules: [
              createCompatModule({
                model: true,
                typescript: true,
              }),
            ],
          },
        },
      },
    ],
  },
}

Modules

model

This module compiles the v-model syntax from Vue 3 to the format supported by Vue 2.

<template>
  <Foo v-model:bar="baz"></Foo>
</template>

<!-- will be compiled to -->

<template>
  <Foo v-bind:bar.sync="baz"></Foo>
</template>

It will not affect the v-model without argument. Although v-model without argument differs in Vue 3 from Vue 2, we recommend that you use the model option to shim at runtime, rather than doing it during compilation.

const Foo = {
  // This is set up to ensure consistent behavior with Vue 3
  model: {
    prop: 'modelValue',
    event: 'update:modelValue',
  },
}

In addition, it will also ignore any modifiers to the v-model that are compiled. Because the modifier only works for input elements in Vue 2, however, input does not support v-model directives with argument.

For custom modifiers, you can pass them in manually to maintain compatibility between Vue 2 and Vue 3.

<template>
  <Foo v-model:bar="baz" :model-modifiers="{ qux: true }"></Foo>
</template>

Solving ESLint Errors

If you are using eslint-plugin-vue and extend the plugin:vue/essential, you will need to manually turn off the following rules:

// .eslintrc.js
module.exports = {
  rules: {
    'vue/no-v-model-argument': 'off',
  },
}

Don't worry, it won't cause significant problems because another rule vue/valid-v-model guarantees the legality of the directive.

typescript

This module helps templates to support the TypeScript syntax.

Before you can use it, you need to make sure that esbuild have been installed in your project. To make it easier to manage versions, esbuild or @babel/core are not included in the dependencies by default.

<template>
  <div>{{ foo!.bar }}</div>
</template>

<!-- will be compiled to (for illustration only) -->

<script>
with (this) {
  return (function () {
    return _c('div', [_v(_s(foo.bar))]);
  })()
}
</script>
<template>
  <div>{{ foo as (string | number) }}</div>
</template>

<!-- will be compiled to (for illustration only) -->

<script>
with (this) {
  return (function () {
    return _c("div", [_v(_s(foo))])
  })()
}
</script>

Why not provide it as a custom compiler?

Because vue-template-compiler only supports compilers in object format (not module paths in string), which makes it impossible to share this configuration within threads when using the thread-loader with the default configuration of the Vue CLI.

syntax (for vue@<2.7 only)

This module helps templates to support the latest ECMAScript syntax, such as Optional Chaining and Nullish coalescing Operator proposals.

Before you can use it, you need to make sure that either esbuild or Babel have been installed in your project. To make it easier to manage versions, esbuild or @babel/core are not included in the dependencies by default.

<template>
  <div>{{ foo?.bar }}</div>
</template>

<!-- will be compiled to (for illustration only) -->

<script>
with (this) {
  return (function () {
    return _c('div', [_v(_s(foo == null ? void 0 : foo.bar))]);
  })()
}
</script>
<template>
  <div>{{ foo ?? bar }}</div>
</template>

<!-- will be compiled to (for illustration only) -->

<script>
with (this) {
  return (function () {
    return _c("div", [_v(_s(foo != null ? foo : bar))])
  })()
}
</script>

By default, this module does not inherit any Babel configuration from the current project.

Why esbuild is more recommended than Babel?

Simply, to reduce configuration costs. When using Babel as a transformer, not only we should care about the preset or plugin you need to use, but that configuration may become obsolete with new syntax.

Nevertheless, we've also made the Babel-based implementation available as modules/syntax-babel, which you can use or write your own module based on it. In addition, there is a lower-level modules/syntax-transform module that completes the syntax compilation process with the help of a custom transformer.

As a reference, the results of my tests on a huge private project are as follows (For Babel, with only Optional Chaining and Nullish coalescing Operator proposals enabled):

  • Without transformer: 328.104s
  • Using Babel as transformer: 340.078s (+3.65%)
  • Using esbuild as transformer: 338.509s (+3.17%)

All the above times refer to CPU time, i.e. not considering multi-core performance.

slot (Unofficial)

This module provides compatible syntax of slots for Vue 2.6 and previous versions.

Slot data generated with the v-slot syntax is only available via $scopedSlots in Vue 2. For some early component libraries (such as element-ui), this behavior may not be implemented for some components. In these scenarios, we can only use the deprecated slot syntax, but this is not conducive to migration to Vue 3.

We chose an edge case that matches the syntax of Vue 2.6 and Vue 3, compiling it to the old slot syntax.

<template>
  <Foo>
    <template #header slot>
      <Bar />
    </template>
  </Foo>
</template>

<!-- will be compiled to -->

<template>
  <Foo>
    <template slot="header">
      <Bar />
    </template>
  </Foo>
</template>

Setting the slot attribute with empty value on a template element with a v-slot directive will be ignored in the default compilation syntax. For v-slot directives on non-template elements, this module will not handle them, since no such compatible syntax exists.

This module works with both the v-slot directive and its abbreviation #.

Why not use a directive modifier such as v-slot:foo.compat ?

This is because the vue-template-compiler actually supports . symbols in slot names, which means that v-slot:foo.compat will operate on the foo.compat slot by default.