Commit 135947a0 authored by Evan You's avatar Evan You

docs: initial setup

parent 5cd5f6fa
module.exports = {
title: 'Vue Loader',
description: 'Webpack loader for single-file Vue components',
serviceWorker: true,
theme: 'vue',
themeConfig: {
repo: 'vuejs/vue-loader',
docsDir: 'docs',
nav: [
{
text: 'Guide',
link: '/guide/'
},
{
text: 'SFC Spec',
link: '/spec.html'
},
{
text: 'Options Reference',
link: '/options.html'
},
{
text: 'Migrating from v14',
link: '/migrating.md'
}
],
sidebar: [
'/',
'/guide/',
'/guide/pre-processors',
'/guide/asset-url',
'/guide/scoped-css',
'/guide/css-modules',
'/guide/postcss',
'/guide/hot-reload',
'/guide/functional',
'/guide/extract-css',
'/guide/custom-blocks',
'/guide/linting',
'/guide/testing'
]
}
}
# redirect v14 urls to root
/en/start/* /:splat
/en/features/* /:splat
/en/configurations/* /:splat
/en/workflow/* /:splat
# redirect any other langs to legacy
/zh-cn/* https://vue-loader-v14.vuejs.org/zh-cn/:splat
/ja/* https://vue-loader-v14.vuejs.org/ja/:splat
/kr/* https://vue-loader-v14.vuejs.org/kr/:splat
/ru/* https://vue-loader-v14.vuejs.org/ru/:splat
/pt_BR/* https://vue-loader-v14.vuejs.org/pt_BR/:splat
# Introduction
:::tip VERSION NOTE
This is the documentation for Vue Loader v15 and above. If you are upgrading from v14 or an earlier version, check out the [Migration Guide](../migrating.md). If you are using an older version, the old docs are [here](vue-loader-v14.vuejs.org).
:::
## What is Vue Loader?
`vue-loader` is a loader for [webpack](https://webpack.js.org/) that allows you to author Vue components in a format called [Single-File Components (SFCs)](./spec.md):
``` vue
<template>
<div class="example">{{ msg }}</div>
</template>
<script>
export default {
data () {
return {
msg: 'Hello world!'
}
}
}
</script>
<style>
.example {
color: red;
}
</style>
```
There are many cool features provided by `vue-loader`:
- Allows using other webpack loaders for each part of a Vue component, for example Sass for `<style>` and Pug for `<template>`;
- Allows custom blocks in a `.vue` file that can have custom loader chains applied to them;
- Treat static assets referenced in `<style>` and `<template>` as module dependencies and handle them with webpack loaders;
- Simulate scoped CSS for each component;
- State-preserving hot-reloading during development.
In a nutshell, the combination of webpack and `vue-loader` gives you a modern, flexible and extremely powerful front-end workflow for authoring Vue.js applications.
# Basic Configuration
# Asset URL Handling
By default, `vue-loader` automatically processes your style and template files with [css-loader](https://github.com/webpack/css-loader) and the Vue template compiler. In this compilation process, 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')`, and
``` html
<img src="../image.png">
```
will be compiled into:
``` js
createElement('img', { attrs: { src: require('../image.png') }})
```
### Transform Rules
- If the URL is an absolute path (e.g. `/images/foo.png`), it will be preserved as-is.
- If the URL starts with `.`, it's interpreted as a relative module request and resolved based on the folder structure on your file system.
- If the URL starts with `~`, anything after it is interpreted as a module request. This means you can even reference assets inside node modules:
``` html
<img src="~some-npm-package/foo.png">
```
- (13.7.0+) If the URL starts with `@`, it's also interpreted as a module request. This is useful if your webpack config has an alias for `@`, which by default points to `/src` in any project created by `vue-cli`.
### Related Loaders
Because `.png` is not a JavaScript file, you will need to configure webpack to use [file-loader](https://github.com/webpack/file-loader) or [url-loader](https://github.com/webpack/url-loader) to handle them. The project scaffolded with `vue-cli` has also configured this for you.
### Why
The benefits of all this are:
1. `file-loader` allows you to designate where to copy and place the asset file, and how to name it using version hashes for better caching. Moreover, this also means **you can just place images next to your `*.vue` files and use relative paths based on the folder structure instead of worrying about deployment URLs**. With proper config, webpack will auto-rewrite the file paths into correct URLs in the bundled output.
2. `url-loader` allows you to conditionally inline a file as base-64 data URL if they are smaller than a given threshold. This can reduce the amount of HTTP requests for trivial files. If the file is larger than the threshold, it automatically falls back to `file-loader`.
# CSS Modules
> requires ^9.8.0
[CSS Modules](https://github.com/css-modules/css-modules) is a popular system for modularizing and composing CSS. `vue-loader` provides first-class integration with CSS Modules as an alternative for simulated scoped CSS.
### Usage
Just add the `module` attribute to your `<style>`:
``` html
<style module>
.red {
color: red;
}
.bold {
font-weight: bold;
}
</style>
```
This will turn on CSS Modules mode for `css-loader`, and the resulting class identifier object will be injected into the component as a computed property with the name `$style`. You can use it in your templates with a dynamic class binding:
``` html
<template>
<p :class="$style.red">
This should be red
</p>
</template>
```
Since it's a computed property, it also works with the object/array syntax of `:class`:
``` html
<template>
<div>
<p :class="{ [$style.red]: isRed }">
Am I red?
</p>
<p :class="[$style.red, $style.bold]">
Red and bold
</p>
</div>
</template>
```
And you can also access it from JavaScript:
``` html
<script>
export default {
created () {
console.log(this.$style.red)
// -> "_1VyoJ-uZOjlOxP7jWUy19_0"
// an identifier generated based on filename and className.
}
}
</script>
```
Refer to the [CSS Modules spec](https://github.com/css-modules/css-modules) for mode details such as [global exceptions](https://github.com/css-modules/css-modules#exceptions) and [composition](https://github.com/css-modules/css-modules#composition).
### Custom Inject Name
You can have more than one `<style>` tags in a single `*.vue` component. To avoid injected styles to overwrite each other, you can customize the name of the injected computed property by giving the `module` attribute a value:
``` html
<style module="a">
/* identifiers injected as a */
</style>
<style module="b">
/* identifiers injected as b */
</style>
```
### Configuring `css-loader` Query
CSS Modules are processed via [css-loader](https://github.com/webpack/css-loader). With `<style module>`, the default query used for `css-loader` is:
``` js
{
modules: true,
importLoaders: 1,
localIdentName: '[hash:base64]'
}
```
You can use vue-loader's `cssModules` option to provide additional query options to `css-loader`:
``` js
module: {
rules: [
{
test: '\.vue$',
loader: 'vue-loader',
options: {
cssModules: {
localIdentName: '[path][name]---[local]---[hash:base64:5]',
camelCase: true
}
}
}
]
}
```
# Custom Blocks
> Requires 10.2.0+
You can define custom language blocks inside `*.vue` files. The content of a custom block will be processed by the loaders specified in the `loaders` object of `vue-loader` options and then required by the component module. The configuration is similar to what is described in [Advanced Loader Configuration](../configurations/advanced.md), except the matching uses the tag name instead of the `lang` attribute.
If a matching loader is found for a custom block, it will be processed; otherwise the custom block will simply be ignored. Additionally, if the found loader returns a function, that function will be called with the component of the `*.vue` file as a parameter.
## Single docs file example
Here's an example of extracting all `<docs>` custom blocks into a single docs file:
#### component.vue
``` html
<docs>
## This is an Example component.
</docs>
<template>
<h2 class="red">{{msg}}</h2>
</template>
<script>
export default {
data () {
return {
msg: 'Hello from Component A!'
}
}
}
</script>
<style>
comp-a h2 {
color: #f00;
}
</style>
```
#### webpack.config.js
``` js
var ExtractTextPlugin = require("extract-text-webpack-plugin")
module.exports = {
module: {
rules: [
{
test: /\.vue$/,
loader: 'vue-loader',
options: {
loaders: {
// extract all <docs> content as raw text
'docs': ExtractTextPlugin.extract('raw-loader'),
}
}
}
]
},
plugins: [
// output all docs into a single file
new ExtractTextPlugin('docs.md')
]
}
```
## Runtime available docs
> Requires 11.3.0+
Here's an example of injecting the `<docs>` custom blocks into the component so that it's available during runtime.
#### docs-loader.js
In order for the custom block content to be injected, we'll need a custom loader:
``` js
module.exports = function (source, map) {
this.callback(null, 'module.exports = function(Component) {Component.options.__docs = ' +
JSON.stringify(source) +
'}', map)
}
```
#### webpack.config.js
Now we'll configure webpack to use our custom loader for `<docs>` custom blocks.
``` js
const docsLoader = require.resolve('./custom-loaders/docs-loader.js')
module.exports = {
module: {
rules: [
{
test: /\.vue$/,
loader: 'vue-loader',
options: {
loaders: {
'docs': docsLoader
}
}
}
]
}
}
```
#### component.vue
We are now able to access the `<docs>` block's content of imported components during runtime.
``` html
<template>
<div>
<component-b />
<p>{{ docs }}</p>
</div>
</template>
<script>
import componentB from 'componentB';
export default = {
data () {
return {
docs: componentB.__docs
}
},
components: {componentB}
}
</script>
```
# Extracting CSS into a Single File
``` bash
npm install extract-text-webpack-plugin --save-dev
```
## The Easy Way
> requires vue-loader@^12.0.0 and webpack@^2.0.0
``` js
// webpack.config.js
var ExtractTextPlugin = require("extract-text-webpack-plugin")
module.exports = {
// other options...
module: {
rules: [
{
test: /\.vue$/,
loader: 'vue-loader',
options: {
extractCSS: true
}
}
]
},
plugins: [
new ExtractTextPlugin("style.css")
]
}
```
The above will automatically handle extraction for `<style>` inside `*.vue` files and works with most pre-processors out of the box.
Note this only extracts `*.vue` files though - CSS imported in JavaScript still needs to be configured separately.
## Manual Configuration
Example config to extract all the processed CSS in all Vue components into a single CSS file:
``` js
// webpack.config.js
var ExtractTextPlugin = require("extract-text-webpack-plugin")
module.exports = {
// other options...
module: {
rules: [
{
test: /\.vue$/,
loader: 'vue-loader',
options: {
loaders: {
css: ExtractTextPlugin.extract({
use: 'css-loader',
fallback: 'vue-style-loader' // <- this is a dep of vue-loader, so no need to explicitly install if using npm3
})
}
}
}
]
},
plugins: [
new ExtractTextPlugin("style.css")
]
}
```
# Template for Functional Components
> New in 13.1.0, requires Vue >= 2.5.0
With `vue-loader >= 13.3.0`, functional components defined as a Single-File Component in a `*.vue` file now enjoys proper template compilation, Scoped CSS and hot-reloading support.
To denote a template that should be compiled as a functional component, add the `functional` attribute to the template block. This also allows omitting the `functional` option in the `<script>` block.
Expressions in the template are evaluated in the [functional render context](https://vuejs.org/v2/guide/render-function.html#Functional-Components). This means props need to be accessed as `props.xxx` in the template:
``` html
<template functional>
<div>{{ props.foo }}</div>
</template>
```
# Hot Reload
"Hot Reload" is not simply reloading the page when you edit a file. With hot reload enabled, when you edit a `*.vue` file, all instances of that component will be swapped in **without reloading the page**. It even preserves the current state of your app and these swapped components! This dramatically improves the development experience when you are tweaking the templates or styling of your components.
![hot-reload](http://blog.evanyou.me/images/vue-hot.gif)
## State Preservation Rules
- When editing the `<template>` of a component, instances of the edited component will re-render in place, preserving all current private state. This is possible because templates are compiled into new render functions that produce no side-effects.
- When editing the `<script>` part of a component, instances of the edited component will be destroyed and re-created in place. (State of the other components in the app are preserved) This is because `<script>` can include lifecycle hooks that may produce side-effects, so a "reload" instead of re-render is required to ensure consistent behavior. This also means you need to be careful about global side effects such as timers inside your components lifecycle hooks. Sometimes you may need to do a full-page reload if your component produces global side-effects.
- `<style>` hot reload operates on its own via `vue-style-loader`, so it doesn't affect application state.
## Usage
When scaffolding the project with `vue-cli`, Hot Reload is enabled out-of-the-box.
When manually setting up your project, hot-reload is enabled automatically when you serve your project with `webpack-dev-server --hot`.
Advanced users may want to check out [vue-hot-reload-api](https://github.com/vuejs/vue-hot-reload-api), which is used internally by `vue-loader`.
## Disabling Hot Reload
Hot Reload is always enabled except following situations:
* webpack `target` is `node` (SSR)
* webpack minifies the code
* `process.env.NODE_ENV === 'production'`
You may use `hotReload: false` option to disable the Hot Reload explicitly:
``` js
module: {
rules: [
{
test: /\.vue$/,
loader: 'vue-loader',
options: {
hotReload: false // disables Hot Reload
}
}
]
}
```
# Linting
You may have been wondering how do you lint your code inside `*.vue` files, since they are not JavaScript. We will assume you are using [ESLint](https://eslint.org/) (if you are not, you should!).
You will also need the official [eslint-plugin-vue](https://github.com/vuejs/eslint-plugin-vue) which supports linting both the template and script parts of Vue files.
Make sure to use the plugin's included config in your ESLint config:
``` json
{
"extends": [
"plugin:vue/essential"
]
}
```
Then from the command line:
``` bash
eslint --ext js,vue MyComponent.vue
```
Another option is using [eslint-loader](https://github.com/MoOx/eslint-loader) so that your `*.vue` files are automatically linted on save during development:
``` bash
npm install eslint eslint-loader --save-dev
```
Make sure it's applied as a pre-loader:
``` js
// webpack.config.js
module.exports = {
// ... other options
module: {
rules: [
{
enforce: 'pre',
test: /\.(js|vue)$/,
loader: 'eslint-loader',
exclude: /node_modules/
}
]
}
}
```
# PostCSS
Any CSS output processed by `vue-loader` is piped through [PostCSS](https://github.com/postcss/postcss) for scoped CSS rewriting. You can also add custom PostCSS plugins to the process, for example [autoprefixer](https://github.com/postcss/autoprefixer) or [CSSNext](http://cssnext.io/).
## Using a Config File
`vue-loader` supports auto-loading the same PostCss config files supported by [`postcss-loader`](https://github.com/postcss/postcss-loader#usage):
- `postcss.config.js`
- `.postcssrc`
- `postcss` field in `package.json`
Using a config file allows you to share the same config between your normal CSS files processed by `postcss-loader` and the CSS inside `*.vue` files, and is recommended.
## Using with `postcss-loader`
Since `vue-loader` handles PostCSS on its styles internally, you only need to apply `postcss-loader` to standalone CSS files. There's no need to specify `lang="postcss"` on a style block if there is a PostCSS config file in your project.
Sometimes the user may want to use `lang="postcss"` only for syntax highlighting purposes. Starting in 13.6.0, if no loader has been explicitly configured for the following common PostCSS extensions (via `vue-loader`'s own `loaders` option), they will simply go through `vue-loader`'s default PostCSS transforms:
- `postcss`
- `pcss`
- `sugarss`
- `sss`
## Inline Options
Alternatively, you can specify PostCSS config specifically for `*.vue` files using the `postcss` option for `vue-loader`.
Example:
``` js
// webpack.config.js
module.exports = {
// other options...
module: {
// `module.rules` is the same as `module.loaders` in 1.x
rules: [
{
test: /\.vue$/,
loader: 'vue-loader',
// `vue-loader` options goes here
options: {
// ...
postcss: [require('postcss-cssnext')()]
}
}
]
}
}
```
In addition to providing an Array of plugins, the `postcss` option also accepts:
- A function that returns an array of plugins;
- An object that contains options to be passed to the PostCSS processor. This is useful when you are using PostCSS projects that relies on custom parser/stringifiers:
``` js
postcss: {
plugins: [...], // list of plugins
options: {
parser: 'sugarss' // use sugarss parser
}
}
```
### Disabling Auto Config File Loading
In `13.6.0+`, auto PostCSS config file loading can be disabled by specifying `postcss.useConfigFile: false`:
``` js
postcss: {
useConfigFile: false,
plugins: [/* ... */],
options: {/* ... */}
}
```
This allows the PostCSS configuration inside `*.vue` files to be entirely controlled by the inline config.
# Using Pre-Processors
In webpack, all pre-processors need to be applied with a corresponding loader. `vue-loader` allows you to use other webpack loaders to process a part of a Vue component. It will automatically infer the proper loaders to use from the `lang` attribute of a language block.
### CSS
For example, let's compile our `<style>` tag with Sass:
``` bash
npm install sass-loader node-sass --save-dev
```
``` html
<style lang="sass">
/* write sass here */
</style>
```
Under the hood, the text content inside the `<style>` tag will be first compiled by `sass-loader` before being passed on for further processing.
#### sass-loader caveat
Contrary to what its name indicates, [*sass*-loader](https://github.com/jtangelder/sass-loader) parses *SCSS* syntax by default. If you actually want to use the indented *Sass* syntax, you have to configure vue-loader's options for sass-loader accordingly.
```javascript
{
test: /\.vue$/,
loader: 'vue-loader',
options: {
loaders: {
scss: 'vue-style-loader!css-loader!sass-loader', // <style lang="scss">
sass: 'vue-style-loader!css-loader!sass-loader?indentedSyntax' // <style lang="sass">
}
}
}
```
See the [Advanced Loader Configuration](./advanced.md) Section for further information about how to configure vue-loader.
#### Loading a global settings file
A common request is to be able to load a settings file in each component without the need to explicity import it each time, e.g. to use scss variables globally throughout all components. To accomplish this:
``` bash
npm install sass-resources-loader --save-dev
```
Then add the following webpack rule:
``` js
{
loader: 'sass-resources-loader',
options: {
resources: path.resolve(__dirname, '../src/style/_variables.scss')
}
}
```
As an example, if you are using [vuejs-templates/webpack](https://github.com/vuejs-templates/webpack), modify `build/utils.js` like so:
``` js
scss: generateLoaders('sass').concat(
{
loader: 'sass-resources-loader',
options: {
resources: path.resolve(__dirname, '../src/style/_variables.scss')
}
}
),
```
It is recommended to only include variables, mixins, etc. in this file, to prevent duplicated css in your final, compiled files.
### JavaScript
All JavaScript inside Vue components are processed by `babel-loader` by default. But you can of course change it:
``` bash
npm install coffee-loader --save-dev
```
``` html
<script lang="coffee">
# Write coffeescript!
</script>
```
### Templates
Processing templates is a little different, because most webpack template loaders such as `pug-loader` return a template function instead of a compiled HTML string. Instead of using `pug-loader`, we can just install the original `pug`:
``` bash
npm install pug --save-dev
```
``` html
<template lang="pug">
div
h1 Hello world!
</template>
```
> **Important:** If you are using `vue-loader@<8.2.0`, you also need to install `template-html-loader`.
### Inline Loader Requests
You can use [webpack loader requests](https://webpack.github.io/docs/loaders.html#introduction) in the `lang` attribute:
``` html
<style lang="sass?outputStyle=expanded">
/* use sass here with expanded output */
</style>
```
However, note this makes your Vue component webpack-specific and not compatible with Browserify and [vueify](https://github.com/vuejs/vueify). **If you intend to ship your Vue component as a reusable 3rd-party component, avoid using this syntax.**
# Scoped CSS
When a `<style>` tag has the `scoped` attribute, its CSS will apply to elements of the current component only. This is similar to the style encapsulation found in Shadow DOM. It comes with some caveats, but doesn't require any polyfills. It is achieved by using PostCSS to transform the following:
``` html
<style scoped>
.example {
color: red;
}
</style>
<template>
<div class="example">hi</div>
</template>
```
Into the following:
``` html
<style>
.example[data-v-f3f3eg9] {
color: red;
}
</style>
<template>
<div class="example" data-v-f3f3eg9>hi</div>
</template>
```
## Tips
### Mixing Local and Global Styles
You can include both scoped and non-scoped styles in the same component:
``` html
<style>
/* global styles */
</style>
<style scoped>
/* local styles */
</style>
```
### Child Component Root Elements
With `scoped`, the parent component's styles will not leak into child components. However, a child component's root node will be affected by both the parent's scoped CSS and the child's scoped CSS. This is by design so that the parent can style the child root element for layout purposes.
### Deep Selectors
If you want a selector in `scoped` styles to be "deep", i.e. affecting child components, you can use the `>>>` combinator:
``` html
<style scoped>
.a >>> .b { /* ... */ }
</style>
```
The above will be compiled into:
``` css
.a[data-v-f3f3eg9] .b { /* ... */ }
```
Some pre-processors, such as Sass, may not be able to parse `>>>` properly. In those cases you can use the `/deep/` combinator instead - it's an alias for `>>>` and works exactly the same.
### Dynamically Generated Content
DOM content created with `v-html` are not affected by scoped styles, but you can still style them using deep selectors.
### Also Keep in Mind
- **Scoped styles do not eliminate the need for classes**. Due to the way browsers render various CSS selectors, `p { color: red }` will be many times slower when scoped (i.e. when combined with an attribute selector). If you use classes or ids instead, such as in `.example { color: red }`, then you virtually eliminate that performance hit. [Here's a playground](https://stevesouders.com/efws/css-selectors/csscreate.php) where you can test the differences yourself.
- **Be careful with descendant selectors in recursive components!** For a CSS rule with the selector `.a .b`, if the element that matches `.a` contains a recursive child component, then all `.b` in that child component will be matched by the rule.
# Testing
- [@vue/cli](https://github.com/vuejs/vue-cli) offers pre-configured unit testing and e2e testing setups for you.
- If you are interested in manually setting up unit tests for `*.vue` files, consult [the docs for `@vue/test-utils`](https://vue-test-utils.vuejs.org/en/).
---
sidebar: auto
sidebarDepth: 2
---
# Migrating from v14
## Notable Breaking Changes
### Loader Inference
`vue-loader` 15 now infers loaders to use for language blocks a bit differently.
Take `<style lang="less">` as an example: in v14 and below, it will attempt to load the block with `less-loader`, and implicitly chains `css-loader` and `vue-style-loader` after it, all using inline loader strings.
In v15, `<style lang="less">` will behave as if it's an actual `*.less` file being loaded. So, in order to process it, you need to provide an explicit rule in your main webpack config:
``` js
{
module: {
rules: [
// ...other rules
{
test: /\.less$/,
use: [
'vue-style-loader',
'css-loader',
'less-loader'
]
}
]
}
}
```
The benefit is that this same rule also applies to plain `*.less` imports from JavaScript, and you can configure options for these loaders anyway you want. In v14 and below, if you want to provide custom options to an inferred loader, you'd have to duplicate it under `vue-loader`'s own `loaders` option. In v15 it is no longer necessary.
v15 also allows using non-serializable options for loaders, which was not possible in previous versions.
### Template Preprocessing
v14 and below uses [consolidate](https://github.com/tj/consolidate.js/) to compile `<template lang="xxx">`. v15 now applies preprocessing for them using webpack loaders instead.
Note that some template loaders such as `pug-loader` exports a compiled templating function instead of plain HTML. In order to pass the correct content to Vue's template compiler, you must use a loader that outputs plain HTML instead. For example, to support `<template lang="pug">`, you can use [pug-plain-loader](https://github.com/yyx990803/pug-plain-loader):
``` js
{
module: {
rules: [
{
test: /\.pug$/,
loader: 'pug-plain-loader'
}
]
}
}
```
If you also intend to use it to import `.pug` files as HTML strings in JavaScript, you will need to chain `raw-loader` after the preprocessing loader. Note however adding `raw-loader` would break the usage in Vue components, so you need to have two rules, one of them targeting Vue files using a `resourceQuery`, the other one (fallback) targeting JavaScript imports:
``` js
{
module: {
rules: [
{
test: /\.pug$/,
oneOf: [
// this applies to <template lang="pug"> in Vue components
{
resourceQuery: /^\?vue/,
use: ['pug-plain-loader']
},
// this applies to pug imports inside JavaScript
{
use: ['raw-loader', 'pug-plain-loader']
}
]
}
]
}
}
```
### Style Injection
Client-side style injection now injects all styles upfront to ensure consistent behavior between development and extracted mode.
Note the injection order is still not guaranteed, so you should avoid writing CSS that relies on insertion order.
### PostCSS
`vue-loader` no longer auto applies PostCSS transforms. To use PostCSS, configure `postcss-loader` the same way you would for normal CSS files.
### CSS Modules
CSS Modules now need to be explicitly configured via `css-loader` options. The `module` attribute on `<style>` tags is still needed for locals injection into the component.
The good news is that you can now configure `localIdentName` in one place:
``` js
{
module: {
rules: [
{
test: /\.css$/,
use: [
{
loader: 'vue-style-loader'
},
{
loader: 'css-loader',
options: {
modules: true,
localIdentName: '[local]_[hash:base64:8]'
}
}
]
}
]
}
}
```
If you only want to use CSS Modules in some of your Vue components, you can use a `oneOf` rule and check for the `module` string in resourceQuery:
``` js
{
test: /\.css$/,
oneOf: [
// this matches <style module>
{
resourceQuery: /module/,
use: [
'vue-style-loader',
{
loader: 'css-loader',
options: {
modules: true,
localIdentName: '[local]_[hash:base64:5]'
}
}
]
},
// this matches plain <style> or <style scoped>
{
use: [
'vue-style-loader',
'css-loader'
]
}
]
}
```
## CSS Extraction
Works the same way as you'd configure it for normal CSS. Example usage with [mini-css-extract-plugin](https://github.com/webpack-contrib/mini-css-extract-plugin):
``` js
{
module: {
rules: [
{
test: /\.vue$/,
use: 'vue-loader'
},
{
test: /\.css$/,
// or ExtractTextWebpackPlugin.extract(...)
use: [
MiniCssExtractPlugin.loader,
'css-loader'
]
}
]
},
plugins: [
new MiniCssExtractPlugin({
filename: 'output.css'
})
]
}
```
## SSR externals
In SSR, we typically use `webpack-node-externals` to exclude npm dependencies from the server build. If you need to import CSS from an npm dependency, the previous solution was using a whitelist like this:
``` js
// webpack config
externals: nodeExternals({
whitelist: /\.css$/
})
```
With v15, imports for `<style src="dep/foo.css">` now has resourceQuery strings appended at the end of the request, so you need to update the above to:
``` js
externals: nodeExternals({
whitelist: [/\.css$/, /\?vue&type=style/]
})
```
## Options Deprecation
The following options have been deprecated and should be configured using normal webpack module rules:
- `loader`
- `preLoaders`
- `postLoaders`
- `postcss`
- `cssSourceMap`
- `buble`
- `extractCSS`
- `template`
The following options have been deprecated and should be configured using the new `compilerOptions` option:
- `preserveWhitespace` (use `compilerOptions.preserveWhitespace`)
- `compilerModules` (use `compilerOptions.modules`)
- `compilerDirectives` (use `compilerOptions.directives`)
The following option has been renamed:
- `transformToRequire` (now renamed to `transformAssetUrls`)
The following option has been changed to resourceQuery:
- `shadowMode` (now use inline resource queries, e.g. `foo.vue?shadow`)
:::tip
For a complete list of new options, see [Options Reference](./options.md).
:::
---
sidebar: auto
---
# Options Reference
## transformAssetUrls
- type: `{ [tag: string]: string | Array<string> }`
- default:
``` js
{
video: ['src', 'poster'],
source: 'src',
img: 'src',
image: 'xlink:href'
}
```
During template compilation, the compiler can transform certain attributes, such as `src` URLs, into `require` calls, so that the target asset can be handled by webpack. For example, `<img src="./foo.png">` will attempt to locate the file `./foo.png` on your file system and include it as a dependency of your bundle.
## compiler
- Type: `VueTemplateCompiler`
- default: `require('vue-template-compiler')`
Override the default compiler used to compile `<template>` blocks in single file components.
## compilerOptions
- type: `Object`
- default: `{}`
Options for the template compiler. When using the default `vue-template-compiler`, you can use this option to add custom compiler directives, modules, or discard whitespaces between template tags with `{ preserveWhitespace: false }`.
See [`vue-template-compiler` options reference](https://github.com/vuejs/vue/tree/dev/packages/vue-template-compiler#options).
## transpileOptions
- type: `Object`
- default: `{}`
Configure ES2015+ to ES5 transpiling options for the generated render function code. The [transpiler](https://github.com/vuejs/vue-template-es2015-compiler) is a fork of [Buble](https://github.com/Rich-Harris/buble), so consult the available options [here](https://buble.surge.sh/guide/#using-the-javascript-api).
The template render functions compilation supports a special transform `stripWith` (enabled by default), which removes the `with` usage in generated render functions to make them strict-mode compliant. This is enabled by default.
## optimizeSSR
- type: `boolean`
- default: `true` when the webpack config has `target: 'node'` and `vue-template-compiler` is at version 2.4.0 or above.
Enable Vue 2.4 SSR compilation optimization that compiles part of the vdom trees returned by render functions into plain strings, which improves SSR performance. In some cases you might want to explicitly turn it off because the resulting render functions can only be used for SSR and cannot be used for client-side rendering or testing.
## hotReload
- type: `boolean`
- default: `true` in development mode, `false` in production mode or when the webpack config has `target: 'node'`.
- allowed value: `false` (`true` will not force Hot Reload neither in production mode nor when `target: 'node'`)
Whether to use webpack [Hot Module Replacement](https://webpack.js.org/concepts/hot-module-replacement/) to apply changes in the browser **without reloading the page**.
Use this option (value `false`) to disable the Hot Reload feature in development mode.
## productionMode
- type: `boolean`
- default: `process.env.NODE_ENV === 'production'`
Force production mode, which prohibits the loader from emitting code (e.g. hot-reload related code) that is development-only.
---
title: SFC Spec
sidebar: auto
---
# Vue Single-File Component (SFC) Spec
## Intro
A `*.vue` file is a custom file format that uses HTML-like syntax to describe a Vue component. Each `*.vue` file consists of three types of top-level language blocks: `<template>`, `<script>`, and `<style>`, and optionally additional custom blocks:
``` vue
<template>
<div class="example">{{ msg }}</div>
</template>
<script>
export default {
data () {
return {
msg: 'Hello world!'
}
}
}
</script>
<style>
.example {
color: red;
}
</style>
<custom1>
This could be e.g. documentation for the component.
</custom1>
```
`vue-loader` will parse the file, extract each language block, pipe them through other loaders if necessary, and finally assemble them back into an ES Module whose default export is a Vue.js component options object.
`vue-loader` supports using non-default languages, such as CSS pre-processors and compile-to-HTML template languages, by specifying the `lang` attribute for a language block. For example, you can use Sass for the style of your component like this:
``` vue
<style lang="sass">
/* write Sass! */
</style>
```
More details can be found in [Using Pre-Processors](./pre-processors.md).
## Language Blocks
### Template
- Each `*.vue` file can contain at most one `<template>` block at a time.
- Contents will be extracted and passed on to `vue-template-compiler` and pre-compiled into JavaScript render functions, and finally injected into the exported component in the `<script>` section.
### Script
- Each `*.vue` file can contain at most one `<script>` block at a time.
- The script is executed as an ES Module.
- The **default export** should be a Vue.js [component options object](https://vuejs.org/v2/api/#Options-Data). Exporting an extended constructor created by `Vue.extend()` is also supported, but a plain object is preferred.
- Any webpack rules that match against `.js` files (or the extension specified by the `lang` attribute) will be applied to contents in the `<script>` block as well.
### Style
- Default match: `/\.css$/`.
- A single `*.vue` file can contain multiple `<style>` tags.
- A `<style>` tag can have `scoped` or `module` attributes (see [Scoped CSS](./scoped-css.md) and [CSS Modules](./css-modules.md)) to help encapsulate the styles to the current component. Multiple `<style>` tags with different encapsulation modes can be mixed in the same component.
- Any webpack rules that match against `.css` files (or the extension specified by the `lang` attribute) will be applied to contents in the `<style>` blocks as well.
### Custom Blocks
Additional custom blocks can be included in a `*.vue` file for any project specific needs, for example a `<docs>` block. `vue-loader` will use the tag name to look up which webpack loaders should be applied to the contents of the section. The webpack loaders should be specified in the `loaders` section of `vue-loader` options.
For mode details, see [Custom Blocks](./custom-blocks.md).
### Src Imports
If you prefer splitting up your `*.vue` components into multiple files, you can use the `src` attribute to import an external file for a language block:
``` vue
<template src="./template.html"></template>
<style src="./style.css"></style>
<script src="./script.js"></script>
```
Beware that `src` imports follow the same path resolution rules to webpack module requests, which means:
- Relative paths need to start with `./`
- You can import resources from npm dependencies:
``` vue
<!-- import a file from the installed "todomvc-app-css" npm package -->
<style src="todomvc-app-css/index.css">
```
`src` imports also work with custom blocks, e.g.:
``` vue
<unit-test src="./unit-test.js">
</unit-test>
```
## Syntax Highlighting / IDE Support
Currently there is syntax highlighting support for the following IDE/editors:
- [Sublime Text](https://github.com/vuejs/vue-syntax-highlight)
- [VS Code](https://marketplace.visualstudio.com/items?itemName=octref.vetur)
- [Atom](https://atom.io/packages/language-vue)
- [Vim](https://github.com/posva/vim-vue)
- [Emacs](https://github.com/AdamNiederer/vue-mode)
- [Brackets](https://github.com/pandao/brackets-vue)
- [JetBrains IDEs](https://plugins.jetbrains.com/plugin/8057) (WebStorm, PhpStorm, etc)
Contributions for other editors/IDEs are highly appreciated! If you are not using any pre-processors in Vue components, you can also get decent syntax highlighting by treating `*.vue` files as HTML in your editor.
## Comments
Inside each block you shall use the comment syntax of the language being used (HTML, CSS, JavaScript, Jade, etc). For top-level comments, use HTML comment syntax: `<!-- comment contents here -->`
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
"lint": "eslint lib test --fix", "lint": "eslint lib test --fix",
"build": "webpack --config example/webpack.config.js --hide-modules", "build": "webpack --config example/webpack.config.js --hide-modules",
"dev": "webpack-dev-server --config example/webpack.config.js --inline --hot", "dev": "webpack-dev-server --config example/webpack.config.js --inline --hot",
"docs": "vuepress dev docs",
"prepublishOnly": "conventional-changelog -p angular -r 2 -i CHANGELOG.md -s" "prepublishOnly": "conventional-changelog -p angular -r 2 -i CHANGELOG.md -s"
}, },
"author": "Evan You", "author": "Evan You",
...@@ -72,6 +73,8 @@ ...@@ -72,6 +73,8 @@
"vue": "^2.5.16", "vue": "^2.5.16",
"vue-server-renderer": "^2.5.16", "vue-server-renderer": "^2.5.16",
"vue-template-compiler": "^2.5.16", "vue-template-compiler": "^2.5.16",
"vuepress": "^0.8.4",
"vuepress-theme-vue": "^1.0.0",
"webpack": "^4.1.0", "webpack": "^4.1.0",
"webpack-cli": "^2.0.10", "webpack-cli": "^2.0.10",
"webpack-dev-server": "^3.1.1", "webpack-dev-server": "^3.1.1",
......
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment