docs: static assets and build targets

This commit is contained in:
Evan You
2018-02-08 14:28:45 -05:00
parent 8b79644052
commit 9ca77cdbb5
3 changed files with 175 additions and 4 deletions

View File

@@ -57,8 +57,6 @@ See [CLI Service docs](./cli-service.md) for all available commands.
The file `public/index.html` is a template that will be processed with [html-webpack-plugin](https://github.com/jantimon/html-webpack-plugin). During build, asset links will be injected automatically. In addition, Vue CLI also automatically injects resource hints (`preload/prefetch`), manifest/icon links (when PWA plugin is used) and inlines the webpack runtime / chunk manifest for optimal performance.
You can edit the file to add your own tags, but note one thing: you need to prefix links to assets with `<%= webpackConfig.output.publicPath %>` in case you are not deploying your app at the root of a domain.
### Static Assets Handling
Static assets can be handled in two different ways:

View File

@@ -1 +1,78 @@
## [TODO] Static Asset Handling
## Static Asset Handling
- [Relative Path Imports](#relative-path-imports)
- [URL Transform Rules](#url-transform-rules)
- [The `public` Folder](#the-public-folder)
- [When to use the `public` folder](#when-to-use-the-public-folder)
### Relative Path Imports
When you reference a static asset using relative path inside JavaScript, CSS or `*.vue` files, the asset will be included into webpack's dependency graph. During 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') }})
```
Internally, we use `file-loader` to determine the final file location with version hashes and correct public base paths, and use `url-loader` to conditional inline assets that are smaller than 10kb, reducing the amount of HTTP requests.
#### URL 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">
```
- If the URL starts with `@`, it's also interpreted as a module request. This is useful because Vue CLI by default aliases `@` to `<projectRoot>/src`.
### The `public` Folder
Any static assets placed in the `public` folder will simply be copied and not go through webpack. You need to reference to them using absolute paths.
Note we recommended importing assets as part of your module dependency graph so that they will go through webpack with the following benefits:
- Scripts and stylesheets get minified and bundled together to avoid extra network requests.
- Missing files cause compilation errors instead of 404 errors for your users.
- Result filenames include content hashes so you dont need to worry about browsers caching their old versions.
The `public` directory is provided as an **escape hatch**, and when you reference it via absolute path, you need to take into account where your app will be deployed. If your app is not deployed at the root of a domain, you will need to prefix your URLs with the base path:
- In `public/index.html`, you need to prefix the link with `<%= webpackConfig.output.publicPath %>`:
``` html
<link rel="shortcut icon" href="<%= webpackConfig.output.publicPath %>favicon.ico">
```
- In templates, you will need to first pass the base URL to your component:
``` js
data () {
return {
baseUrl: process.env.BASE_URL
}
}
```
Then:
``` html
<img :src="`${baseUrl}my-image.png`">
```
#### When to use the `public` folder
- You need a file with a specific name in the build output.
- You have thousands of images and need to dynamically reference their paths.
- Some library may be incompatible with Webpack and you have no other option but to include it as a `<script>` tag.

View File

@@ -1,7 +1,103 @@
## [TODO] Build Targets
## Build Targets
### App
App mode is the default mode. In this mode:
- `index.html` with asset and resource hints injection
- vendor libraries split into a separate chunk for better caching
- static assets under 10kb are inlined into JavaScript
- static assets in `public` are copied into output directory
### Library
You can build a single entry as a library using
```
vue-cli-service build --target lib --name myLib [entry]
```
The entry can be either a `.js` or a `.vue` file. If no entry is specified, `src/App.vue` will be used.
A lib build outputs:
- `dist/myLib.common.js`
A CommonJS bundle for consuming via bundlers (unfortunately, webpack currently does not support ES modules output format for bundles yet)
- `dist/myLib.umd.js`
A UMD bundle for consuming directly in browsers or with AMD loaders
- `dist/myLib.umd.min.js`
Minified version of the UMD build.
- `dist/myLib.css`
Extracted CSS file (can be forced into inlined by setting `css: { extract: false }` in `vue.config.js`)
### Web Component
> [Compatibility](https://github.com/vuejs/vue-web-component-wrapper#compatibility)
You can build a single entry as a library using
```
vue-cli-service build --target wc --name my-element [entry]
```
This will produce a single JavaScript file (and its minified version) with everything inlined. The script, when included on a page, registers the `<my-element>` custom element, which wraps the target Vue component using `@vue/web-component-wrapper`. The wrapper automatically proxies properties, attributes, events and slots. See the [docs for `@vue/web-component-wrapper`](https://github.com/vuejs/vue-web-component-wrapper) for more details.
Note the bundle relies on `Vue` being globally available on the page.
This mode allows consumers of your component to use the Vue component as a normal DOM element:
``` html
<script src="https://unpkg.com/vue"></script>
<script src="path/to/my-element.js"></script>
<!-- use in plain HTML, or in any other framework -->
<my-element></my-element>
```
#### Bundle that Registers Multiple Web Components
When building a web component bundle, you can also target multiple components by using a glob as entry:
```
vue-cli-service build --target wc --name foo 'src/components/*.vue'
```
When building multiple web components, `--name` will be used as the prefix and the custom element name will be inferred from the component filename. For example, with `--name foo` and a component named `HelloWorld.vue`, the resulting custom element will be registered as `<foo-hello-world>`.
### Async Web Component
> [Compatibility](https://github.com/vuejs/vue-web-component-wrapper#compatibility)
When targeting multiple web components, the bundle may become quite large, and the user may only use a few of the components your bundle registers. The async web component mode produces a code-split bundle with a small entry file that provides the shared runtime between all the components, and registers all the custom elements upfront. The actual implementation of a component is then fetched on-demand only when an instance of the corresponding custom element is used on the page:
```
vue-cli-service build --target wc-async --name foo 'src/components/*.vue'
```
```
File Size Gzipped
dist/foo.0.min.js 12.80 kb 8.09 kb
dist/foo.min.js 7.45 kb 3.17 kb
dist/foo.1.min.js 2.91 kb 1.02 kb
dist/foo.js 22.51 kb 6.67 kb
dist/foo.0.js 17.27 kb 8.83 kb
dist/foo.1.js 5.24 kb 1.64 kb
```
Now on the page, the user only needs to include Vue and the entry file:
``` html
<script src="https://unpkg.com/vue"></script>
<script src="path/to/foo.min.js"></script>
<!-- foo-one's implementation chunk is auto fetched when it's used -->
<foo-one></foo-one>
```