Commit 72ea25f2 authored by Evan You's avatar Evan You

docs: update for v15

parent 27c60e0b
......@@ -27,15 +27,14 @@ module.exports = {
sidebar: [
'/',
'/guide/',
'/guide/pre-processors',
'/guide/asset-url',
'/guide/pre-processors',
'/guide/scoped-css',
'/guide/css-modules',
'/guide/postcss',
'/guide/hot-reload',
'/guide/functional',
'/guide/extract-css',
'/guide/custom-blocks',
'/guide/extract-css',
'/guide/linting',
'/guide/testing'
]
......
# redirect v14 urls to root
/en/start/* /guide/:splat
/en/features/* /guide/:splat
/en/configurations/* /guide/:splat
/en/workflow/* /guide/:splat
/en/features/postcss.html /guide/pre-processors.html#postcss
/en/start/* /guide/:splat
/en/features/* /guide/:splat
/en/configurations/* /guide/:splat
/en/workflow/* /guide/:splat
# redirect any other langs to legacy
/zh-cn/* https://vue-loader-v14.vuejs.org/zh-cn/:splat
......
# Basic Configuration
# Getting Started
## Vue CLI
If you are not interested in manually setting up webpack, it is recommended to scaffold a project with [Vue CLI](https://github.com/vuejs/vue-cli) instead. Projects created by Vue CLI is pre-configured with most of the common development needs and works out of the box.
Follow this guide if the built-in configuration of Vue CLI does not suit your needs, or you'd rather create your own webpack config from scratch.
## Manual Configuration
Vue Loader's configuration is a bit different form other loaders. In addition to a rule that applies `vue-loader` to any files with extension `.vue`, make sure to add Vue Loader's plugin to your webpack config:
``` js
// webpack.config.js
const { VueLoaderPlugin } = require('vue-loader')
module.exports = {
module: {
rules: [
// ... other rules
{
test: /\.vue$/,
loader: 'vue-loader'
}
]
},
plugins: [
// make sure to include the plugin!
new VueLoaderPlugin()
]
}
```
**The plugin is required.** It is responsible for cloning any other rules you have defined and applying them to the corresponding language blocks in `.vue` files. For example, if you have a rule matching `/\.js$/`, it will be applied to `<script>` blocks in `.vue` files.
A more complete example webpack config will look like this:
``` js
// webpack.config.js
const path = require('path')
const { VueLoaderPlugin } = require('vue-loader')
module.exports = {
mode: 'development',
module: {
rules: [
{
test: /\.vue$/,
loader: 'vue-loader'
},
// this will apply to both plain .js files
// AND <script> blocks in vue files
{
test: /\.js$/,
loader: 'babel-loader'
},
// this will apply to both plain .css files
// AND <style> blocks in vue files
{
test: /\.css$/,
use: [
'vue-style-loader',
'css-loader'
]
}
]
},
plugins: [
// make sure to include the plugin for the magic
new VueLoaderPlugin()
]
}
```
# 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**.
When Vue Loader compiles the `<template>` blocks in SFCs, it also converts any encountered asset URLs into **webpack module requests**.
For example, `url(./image.png)` will be translated into `require('./image.png')`, and
For example, the following template snippet
``` html
``` vue
<img src="../image.png">
```
will be compiled into:
``` js
createElement('img', { attrs: { src: require('../image.png') }})
createElement('img', {
attrs: {
src: require('../image.png') // this is now a module request
}
})
```
### Transform Rules
By default the following tag/attribute combinations are transformed, and can be configured using the [transformAssetUrls](../config.md#transformasseturls) option.
In addition, if you have configured to use [css-loader](https://github.com/webpack-contrib/css-loader) for the `<style>` blocks, asset URLs in your CSS will also be processed in a similar fashion.
## Transform Rules
Asset URL transforms adhere to the following rules:
- If the URL is an absolute path (e.g. `/images/foo.png`), it will be preserved as-is.
......@@ -26,15 +36,15 @@ createElement('img', { attrs: { src: require('../image.png') }})
<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`.
- 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
## 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.
Because extensions like `.png` are not JavaScript modules, 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 properly handle them. Projects created with Vue CLI has this pre-configured.
### Why
## Why
The benefits of all this are:
The benefits of asset URL transforms 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.
......
# 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
## Usage
Just add the `module` attribute to your `<style>`:
First, CSS Modules must be enabled by passing `modules: true` to `css-loader`:
``` html
``` js
// webpack.config.js
{
module: {
rules: [
// ... other rules omitted
{
test: /\.css$/,
use: [
'vue-style-loader',
{
loader: 'css-loader',
options: {
// enable CSS Modules
modules: true,
// customize generated class names
localIdentName: '[local]_[hash:base64:8]'
}
}
]
}
]
}
}
```
Then, add the `module` attribute to your `<style>`:
``` vue
<style module>
.red {
color: red;
......@@ -19,9 +45,9 @@ Just add the `module` attribute to your `<style>`:
</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:
The `module` attribute instructs Vue Loader to inject the CSS modules locals object into the component as a computed property with the name `$style`. You can then use it in your templates with a dynamic class binding:
``` html
``` vue
<template>
<p :class="$style.red">
This should be red
......@@ -31,7 +57,7 @@ This will turn on CSS Modules mode for `css-loader`, and the resulting class ide
Since it's a computed property, it also works with the object/array syntax of `:class`:
``` html
``` vue
<template>
<div>
<p :class="{ [$style.red]: isRed }">
......@@ -46,12 +72,12 @@ Since it's a computed property, it also works with the object/array syntax of `:
And you can also access it from JavaScript:
``` html
``` vue
<script>
export default {
created () {
console.log(this.$style.red)
// -> "_1VyoJ-uZOjlOxP7jWUy19_0"
// -> "red_1VyoJ-uZ"
// an identifier generated based on filename and className.
}
}
......@@ -60,47 +86,69 @@ export default {
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>
```
## Opt-in Usage
### 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:
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
// webpack.config.js -> module.rules
{
modules: true,
importLoaders: 1,
localIdentName: '[hash:base64]'
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'
]
}
]
}
```
You can use vue-loader's `cssModules` option to provide additional query options to `css-loader`:
## Using with Pre-Processors
CSS Modules can be used along with other pre-processors:
``` js
module: {
rules: [
// webpack.config.js -> module.rules
{
test: /\.scss$/,
use: [
'vue-style-loader',
{
test: '\.vue$',
loader: 'vue-loader',
options: {
cssModules: {
localIdentName: '[path][name]---[local]---[hash:base64:5]',
camelCase: true
}
}
}
loader: 'css-loader',
options: { modules: true }
},
'sass-loader'
]
}
```
## 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>
```
# Custom Blocks
> Requires 10.2.0+
You can define custom language blocks inside `*.vue` files. Loaders applied for a custom block are matched based on the `lang` attribute of the block, the block's tag name, and the rules in your webpack config.
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 `lang` attribute is specified, the custom block will be matched as a file with the `lang` as its extension.
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
You can also use `resourceQuery` to match a rule against a custom block with no `lang`. For example, to match against `<foo>` custom blocks:
``` 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'),
}
}
resourceQuery: /blockType=foo/,
loader: 'loader-to-use'
}
]
},
plugins: [
// output all docs into a single file
new ExtractTextPlugin('docs.md')
]
}
}
```
## Runtime available docs
If a matching rule is found for a custom block, it will be processed; otherwise the custom block will be silently ignored.
> Requires 11.3.0+
Additionally, if the custom block exports a function as the final result after being processed by all the matching loaders, that function will be called with the component of the `*.vue` file as a parameter.
Here's an example of injecting the `<docs>` custom blocks into the component so that it's available during runtime.
## Example
#### docs-loader.js
Here's an example of injecting the `<docs>` custom blocks into the component so that it's available during runtime.
In order for the custom block content to be injected, we'll need a custom loader:
In order for the custom block content to be injected, we'll write a custom loader:
``` js
module.exports = function (source, map) {
this.callback(null, 'module.exports = function(Component) {Component.options.__docs = ' +
JSON.stringify(source) +
'}', map)
this.callback(
null,
`export default 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')
// wepback.config.js
module.exports = {
module: {
rules: [
{
test: /\.vue$/,
loader: 'vue-loader',
options: {
loaders: {
'docs': docsLoader
}
}
resourceQuery: /blockType=docs/,
loader: require.resolve('./docs-loader.js')
}
]
}
}
```
#### component.vue
We are now able to access the `<docs>` block's content of imported components during runtime.
``` html
``` vue
<!-- ComponentB.vue -->
<template>
<div>Hello</div>
</template>
<docs>
This is the documentation for component B.
</docs>
```
``` vue
<!-- ComponentA.vue -->
<template>
<div>
<component-b />
<ComponentB/>
<p>{{ docs }}</p>
</div>
</template>
<script>
import componentB from 'componentB';
import ComponentB from './ComponentB.vue';
export default = {
components: { ComponentB },
data () {
return {
docs: componentB.__docs
docs: ComponentB.__docs
}
},
components: {componentB}
}
}
</script>
```
# Extracting CSS into a Single File
# CSS Extraction
``` bash
npm install extract-text-webpack-plugin --save-dev
```
::: tip
Only apply CSS extraction for production so that you get CSS hot reload during development.
:::
## The Easy Way
## webpack 4
> requires vue-loader@^12.0.0 and webpack@^2.0.0
``` bash
npm install -D mini-css-extract-plugin
```
``` js
// webpack.config.js
var ExtractTextPlugin = require("extract-text-webpack-plugin")
var MiniCssExtractPlugin = require('mini-css-extract-plugin')
module.exports = {
// other options...
module: {
rules: [
// ...other rules omitted
{
test: /\.vue$/,
loader: 'vue-loader',
options: {
extractCSS: true
}
test: /\.css$/,
use: [
process.env.NODE_ENV !== 'production'
? 'vue-style-loader'
: MiniCssExtractPlugin.loader,
'css-loader'
]
}
]
},
plugins: [
new ExtractTextPlugin("style.css")
// ...vue-loader plugin omitted
new MiniCssExtractPlugin({
filename: 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.
Also see [mini-css-extract-plugin docs](https://github.com/webpack-contrib/mini-css-extract-plugin).
## Manual Configuration
## webpack 3
Example config to extract all the processed CSS in all Vue components into a single CSS file:
``` bash
npm install -D extract-text-webpack-plugin
```
``` js
// webpack.config.js
......@@ -47,22 +55,21 @@ module.exports = {
// other options...
module: {
rules: [
// ...other rules omitted
{
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
})
}
}
test: /\.css$/,
loader: ExtractTextPlugin.extract({
use: 'css-loader',
fallback: 'vue-style-loader'
})
}
]
},
plugins: [
// ...vue-loader plugin omitted
new ExtractTextPlugin("style.css")
]
}
```
Also see [extract-text-webpack-plugin docs](https://github.com/webpack-contrib/extract-text-webpack-plugin).
# Template for Functional Components
# 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.
Functional components defined as a Single-File Component in a `*.vue` file also receives 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
``` vue
<template functional>
<div>{{ props.foo }}</div>
</template>
```
If you need to access properties defined globally on `Vue.prototype`, you can access them on `parent`:
``` vue
<template functional>
<div>{{ parent.$someProperty }}</div>
</template>
```
# 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.
The official [eslint-plugin-vue](https://github.com/vuejs/eslint-plugin-vue) supports linting both the template and script parts of Vue single file components.
Make sure to use the plugin's included config in your ESLint config:
``` json
{
"extends": [
``` js
// .eslintrc.js
module.exports = {
extends: [
"plugin:vue/essential"
]
}
......@@ -23,7 +22,7 @@ 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
npm install -D eslint eslint-loader
```
Make sure it's applied as a pre-loader:
......
# 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.
---
sidebarDepth: 2
---
# 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.
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 based on the `lang` attribute of a language block and the rules in your webpack config.
### CSS
## SASS
For example, let's compile our `<style>` tag with Sass:
For example, to compile our `<style>` tag with SASS/SCSS:
``` bash
npm install sass-loader node-sass --save-dev
npm install -D sass-loader node-sass
```
In your webpack config:
``` js
module.exports = {
module: {
rules: [
// ...other rules omitted
// this will apply to both plain .scss files
// AND <style lang="scss"> blocks in vue files
{
test: /\.scss$/,
use: [
'vue-style-loader',
'css-loader',
'sass-loader'
]
}
]
},
// plugin omitted
}
```
Now in addition to being able to `import 'style.scss'`, we can use SCSS in Vue components as well:
``` html
<style lang="sass">
/* write sass here */
<style lang="scss">
/* write SCSS 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.
Any content inside the block will be processed by webpack as if it's inside a `*.scss` file.
#### sass-loader caveat
### SASS vs SCSS
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.
Note that `sass-loader` processes the non-indent-based `scss` syntax by default. In order to use the indent-based `sass` syntax, you need to pass options to the loader:
```javascript
``` js
// webpack.config.js -> module.rules
{
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">
test: /\.sass$/,
use: [
'vue-style-loader',
'css-loader',
{
loader: 'sass-loader',
options: {
indentedSyntax: true
}
}
}
]
}
```
See the [Advanced Loader Configuration](./advanced.md) Section for further information about how to configure vue-loader.
### Sharing Global Variables
#### Loading a global settings file
`sass-loader` also supports a `data` option which allows you to share common variables among all processed files without having to explicit import them:
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:
``` js
// webpack.config.js -> module.rules
{
test: /\.scss$/,
use: [
'vue-style-loader',
'css-loader',
{
loader: 'sass-loader',
options: {
// you can also read from a file, e.g. `variables.scss`
data: `$color: red;`
}
}
]
}
```
## LESS
``` bash
npm install sass-resources-loader --save-dev
npm install -D less less-loader
```
Then add the following webpack rule:
``` js
// webpack.config.js -> module.rules
{
test: /\.less$/,
use: [
'vue-style-loader',
'css-loader',
'less-loader'
]
}
```
## Stylus
``` bash
npm install -D stylus stylus-loader
```
``` js
// webpack.config.js -> module.rules
{
loader: 'sass-resources-loader',
options: {
resources: path.resolve(__dirname, '../src/style/_variables.scss')
}
test: /\.styl(us)?$/,
use: [
'vue-style-loader',
'css-loader',
'stylus-loader'
]
}
```
As an example, if you are using [vuejs-templates/webpack](https://github.com/vuejs-templates/webpack), modify `build/utils.js` like so:
## PostCSS
::: tip
Vue Loader v15 no longer applies PostCSS transforms by default. You will need to use PostCSS via `postcss-loader`.
:::
``` bash
npm install -D postcss-loader
```
``` js
scss: generateLoaders('sass').concat(
{
loader: 'sass-resources-loader',
options: {
resources: path.resolve(__dirname, '../src/style/_variables.scss')
}
}
),
// webpack.config.js -> module.rules
{
test: /\.css$/,
use: [
'style-loader',
{
loader: 'css-loader',
options: { importLoaders: 1 }
},
'postcss-loader'
]
}
```
It is recommended to only include variables, mixins, etc. in this file, to prevent duplicated css in your final, compiled files.
Configuration of PostCSS can be done via `postcss.config.js` or `postcss-loader` options. For details, consult [postcss-loader docs](https://github.com/postcss/postcss-loader).
### JavaScript
`postcss-loader` can also be applied in combination with other pre-processors mentioned above.
All JavaScript inside Vue components are processed by `babel-loader` by default. But you can of course change it:
## Babel
``` bash
npm install coffee-loader --save-dev
npm install -D babel-core babel-loader
```
``` html
<script lang="coffee">
# Write coffeescript!
</script>
``` js
// webpack.config.js -> module.rules
{
test: /\.js?$/,
loader: 'babel-loader'
}
```
### Templates
Configuration of Babel can be done via `.babelrc` or `babel-loader` options.
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`:
## TypeScript
``` bash
npm install pug --save-dev
npm install -D typescript ts-loader
```
``` js
// webpack.config.js
module.exports = {
resolve: {
// Add `.ts` as a resolvable extension.
extensions: ['.ts', '.js']
},
module: {
rules: [
// ...other rules omitted
{
test: /\.ts$/,
loader: 'ts-loader',
options: { appendTsSuffixTo: [/\.vue$/] }
}
]
},
// ...plugin omitted
}
```
Configuration of TypeScipt can be done via `tsconfig.json`. Also see docs for [ts-loader](https://github.com/TypeStrong/ts-loader).
## Pug
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 need to use a loader that returns the raw HTML string instead, e.g. `pug-plain-loader`:
``` bash
npm install -D pug pug-plain-loader
```
``` js
// webpack.config.js -> module.rules
{
test: /\.pug$/,
loader: 'pug-plain-loader'
}
```
Then you can write:
``` html
<template lang="pug">
div
......@@ -100,16 +226,22 @@ div
</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:
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:
``` html
<style lang="sass?outputStyle=expanded">
/* use sass here with expanded output */
</style>
``` js
// webpack.config.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']
}
]
}
```
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.**
......@@ -28,9 +28,7 @@ Into the following:
</template>
```
## Tips
### Mixing Local and Global Styles
## Mixing Local and Global Styles
You can include both scoped and non-scoped styles in the same component:
......@@ -44,11 +42,11 @@ You can include both scoped and non-scoped styles in the same component:
</style>
```
### Child Component Root Elements
## 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
## Deep Selectors
If you want a selector in `scoped` styles to be "deep", i.e. affecting child components, you can use the `>>>` combinator:
......@@ -66,11 +64,11 @@ The above will be compiled into:
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
## 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
## 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.
......
# Testing
- [@vue/cli](https://github.com/vuejs/vue-cli) offers pre-configured unit testing and e2e testing setups for you.
- [Vue CLI](https://github.com/vuejs/vue-cli) offers pre-configured unit testing and e2e testing setups.
- 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/).
- 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/), which covers setup with [mocha-webpack](https://vue-test-utils.vuejs.org/en/guides/testing-SFCs-with-mocha-webpack.html) or [Jest](https://vue-test-utils.vuejs.org/en/guides/testing-SFCs-with-jest.html).
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