vue-loader
Vue.js component loader for Webpack, using Webpack loaders for the parts.
It allows you to write your components in this format:
// app.vue
<style>
.red {
color: #f00;
}
</style>
<template>
<h1 class="red">{{msg}}</h1>
</template>
<script>
module.exports = {
data: function () {
return {
msg: 'Hello world!'
}
}
}
</script>
Table of Contents
- Basic Usage
- Pre-Processors
- Style Imports
- Multi Components
- Asset URL Handling
- Advanced Loader Configuration
- Example Project
Basic Usage
Config Webpack:
// webpack.config.js
module.exports = {
entry: './main.js',
output: {
filename: 'build.js'
},
module: {
loaders: [
{ test: /\.vue$/, loader: 'vue' },
]
}
}
And this is all you need to do in your main entry file:
// main.js
var Vue = require('vue')
var appOptions = require('./app.vue')
var app = new Vue(appOptions).$mount('#app')
Pre-Processors
vue-loader
allows you to use per-file pre-processors inside *.vue
components with the lang
attribute:
<style lang="stylus">
/* use stylus here */
</style>
The lang
attribute will be used to automatically locate the loader to use, and you can pass Webpack loader queries in it as well:
<style lang="sass?outputStyle=expanded">
/* use sass here with expanded output */
</style>
A Note on Dependencies
By default, vue-loader
requires html-loader
, css-loader
and style-loader
as peer dependencies. In order to use pre-processors, you also need to install the corresponding Webpack loader for that language.
Also, for template pre-processors, you should install template-html-loader
plus the raw templating engine. For example to use jade
, you will need to install both template-html-loader
and jade
instead of jade-loader
.
Style Imports
If you want, you can separate your styles into a separate file and import it using the src
attribute:
<style src="./style.css"></style>
Beware that src
imports follow similar rules to require()
calls, which means for relative paths you need to start with ./
, and you can import resources from node modules: <style src="todomvc-app-css/index.css">
.
Multi Components
You can define multi components in a single .vue file.
// app.vue
<component name='first'>
<style>
.red {
color: #f00;
}
</style>
<template>
<h1 class="red">{{msg}}</h1>
</template>
<script>
module.exports = {
data: function () {
return {
msg: 'Hello world!'
}
}
}
</script>
</component>
<component name='second'>
...
</component>
And in your main entry file:
// main.js
var Vue = require('vue')
var appOptions = require('./app.vue')
var appFirst = new Vue(appOptions.first).$mount('#app-first')
var appSecond = new Vue(appOptions.second).$mount('#app-second')
Asset URL Handling
By default, vue-loader
automatically processes your style and template files with css-loader
and html-loader
- this means that all asset URLs such as <img src="...">
, background: url(...)
and CSS @import
are resolved as module dependencies.
For example, url(image.png)
will be translated into require('./image.png')
. Because .png
is not JavaScript, you will need to configure Webpack to use file-loader or url-loader to handle them. This may feel cumbersome, but it gives you some very powerful benefits in managing your static assets this way:
-
file-loader
allows you to customize where to copy and place the asset file (by specifyingpublicPath
in your Webpack config), and how they should be named with version hashes. -
url-loader
allows you to conditionally load a file as a inline Data URL if they are smaller than a given threshold.
For more details, see the respective documentations for html-loader and css-loader.
Advanced Loader configuration
By default, vue-loader
will try to use the loader with the same name as
the lang
attribute, but you can configure which loader should be used.
Example: Using ES6 with Babel
To apply Babel transforms to all your JavaScript, use this Webpack config:
var vue = require('vue-loader')
module.exports = {
// entry, output...
module: {
loaders: [
{
test: /\.vue$/,
loader: vue.withLoaders({
// apply babel transform to all javascript
// inside *.vue files.
js: 'babel?optional[]=runtime'
})
}
]
},
devtool: 'source-map'
}
Some explanantions:
-
Here
js
is the default language for<script>
blocks. -
The
?optional[]=runtime
query string passed to the loader. This instructs Babel to use helper functions from thebabel-runtime
NPM package instead of injecting the helpers into every single file. You'll want this most of the time.
Example: Extracting CSS into a Single File
To extract out the generated css into a separate file, use this Webpack config:
var ExtractTextPlugin = require("extract-text-webpack-plugin");
var vue = require("vue-loader");
module.exports = {
// entry, output...
module: {
loaders: [
{
test: /\.vue$/, loader: vue.withLoaders({
css: ExtractTextPlugin.extract("css"),
stylus: ExtractTextPlugin.extract("css!stylus")
})
},
]
},
plugins: [
new ExtractTextPlugin("[name].css")
]
}
Example Project
See vue-loader-example.