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-tpl-loader

v1.0.0

Published

Vue.js 2.0 template loader for webpack

Downloads

19

Readme

vue-tpl-loader

Vue.js 2.0 template loader for webpack

This loader pre-compiles a html template into a render function using the vue-template-compiler. Each html file is transformed into a function that takes a vue component options object and injects a render function, styles and HMR support.

In most cases, vue-loader is recommended over this loader.

Features

  • Transforms a html template into a render function
  • Supports scoped css and css modules (similar to vue-loader)
  • HMR support for templates
  • Decorator syntax support (can be used with vue-class-component or other class style components)

Webpack Configuration

Loading a Html Template

Add vue-tpl-loader as a loader to your webpack configuration.

module.exports = {
  module: {
    rules: [
      { test: /\.html$/, use: 'vue-tpl-loader' }
    ]
  }
}

Asset Transforms

To transform asset paths in your templates to require expressions that webpack can handle, configure the transformToRequire option. For example, if you would like webpack to process the image files in the src attribute of <img> elements:

module.exports = {
  module: {
    rules: [
      {
        test: /\.html$/,
        loader: 'vue-tpl-loader',
        options: {
          transformToRequire: {
            // The key should be an element name
            // The value should be an attribute name or an array of attribute names
            img: 'src'
          }
        }
      },

      // Make sure to add a loader that can process the asset files
      {
        test: /\.(png|jpg)/,
        loader: 'file-loader',
        options: {
          // ...
        }
      }
    ]
  }
}

Loading Scoped Styles

For an explanation of scoped styles, see the vue-loader docs.

Html and style files need to be imported using import withRender from './app.html?style=./app.css'.

You also need modify your webpack config as follows:

  • Set scoped: true in the vue-tpl-loader options
  • Mark some of your style loaders (usually style-loader and css-loader) as post-loaders (by setting enforce: 'post').

Logic for what to mark as a post-loader: vue-tpl-loader injects an inline webpack loader into your loader pipeline to modify your style files to include [scope-id] selectors. Webpack loaders run in the order normal -> inline -> post, so any loaders you want to run before the inline loader should be normal loaders, and anything you want to run after the inline loader should be post loaders (i.e. marked with enforce: 'post').

Typically you will want to leave loaders that compile to css (like less, sass and postcss transpilers) as normal loaders, so they run before the [scope-id] injection. Loaders that transform css into a format for webpack consumption (like style-loader and css-loader) should be post loaders (marked as enforce: 'post').

module.exports = {
  module: {
    rules: [
      {
        // Loaders that transform css into a format for webpack consumption should be post loaders (enforce: 'post')
        enforce: 'post',
        test: /\.css$/,
        use: ['style-loader', 'css-loader']
      },
      // We needed to split the rule for .scss files across two rules
      {
        // The loaders that compile to css (postcss and sass in this case) should be left as normal loaders
        test: /\.scss$/,
        use: ['postcss-loader', 'sass-loader']
      },
      {
        // The loaders that format css for webpack consumption should be post loaders
        enforce: 'post',
        test: /\.scss$/,
        use: ['style-loader', 'css-loader']
      }
    ]
  }
}

>>> combinator

There are cases where you may want to style children components e.g. using a third party component. In such cases, you can use the >>> (/deep/) combinator to apply styles to any descendant elements of a scoped styled element.

Input:

.foo >>> .bar {
  color: red;
}

Output:

.foo[data-v-4fd8d954] .bar {
  color: red
}

If you are using less, note that it does not yet support the >>> operator, but you can use:

@deep: ~">>>";

.foo @{deep} .bar {
  color: red;
}

Loading CSS Modules

For an explanation of CSS modules, see the vue-loader docs.

Html and style files need to be imported using the loader syntax: import withRender from './app.html?style=./app.css'. You also need to enable the modules flag of css-loader.

vue-tpl-loader will add the $style property to your view model and you can use hashed classes through it.

module.exports = {
  module: {
    rules: [
      {
        test: /\.html$/,
        use: 'vue-tpl-loader'
      },
      {
        test: /\.css$/,
        use: ['style-loader', 'css-loader?modules'] // Enable CSS Modules
      }
    ]
  }
}

Disabling HMR

By default Hot Module Replacement is disabled in the following situations:

  • Webpack target is node
  • Webpack minifies the code
  • process.env.NODE_ENV === 'production'

You may use the hmr: false option to disable HMR explicitly for any other situation.

module.exports = {
  module: {
    rules: [
      {
        test: /\.html$/,
        loader: 'vue-tpl-loader',
        options: {
          hmr: false // disables Hot Modules Replacement
        }
      }
    ]
  }
}

Example

Write a template for a Vue component using html.

<!-- app.html -->
<div class="app">
  <p>{{ text }}</p>
  <button type="button" @click="log">Log</button>
</div>

Import it as a function and pass a component option to the function. If you would like to load a style file, add the style query and specify the style file path.

// app.js
import withRender from './app.html?style=./app.css'

export default withRender({
  data () {
    return {
      text: 'Example text'
    }
  },

  methods: {
    log () {
      console.log('output log')
    }
  }
})

You can use decorator syntax for any class style components.

import Vue from 'vue'
import Component from 'vue-class-component'
import WithRender from './app.html'

@WithRender
@Component
export default class App extends Vue {
  text = 'Example text'

  log () {
    console.log('output log')
  }
}

Typescript

If you use this loader with TypeScript, make sure to add a declaration file for html files into your project. (If you want to load style files via query string, you need to replace *.html with *.css)

declare module '*.html' {
  import Vue, { ComponentOptions } from 'vue'
  interface WithRender {
    <V extends Vue>(options: ComponentOptions<V>): ComponentOptions<V>
    <V extends typeof Vue>(component: V): V
  }
  const withRender: WithRender
  export default withRender
}

Thanks

This project form vue-template-loader, Thanks to @ktsn.

License

MIT