HTML
index文件
该文件public/index.html是一个模板,将使用 html-webpack-plugin 进行处理。在构建期间,资源链接会被自动引入。之外,Vue Cli 也会自动注入resource hint 以及构建过程中处理的JavaScript和CSS文件的资源链接。
插值
因为index 文件被用作模板,所以可以使用loadash template 语法插入内容:
- <%=VALUE%> 用来做不转义插值
- <%-VALUE%> 用来做HTML转义插值
- <% expression> 用来描述JavaScript流程控制。 除了被html-webpack-plugin 暴露的默认值之外,所有客户端环境变量也可以直接使用。例如:
<link ref="icon" href="<%= BASE_URL %>favicon.ico">
Preload (预加载)
<link rel="preload"> 是一种资源提示, 用来指定页面加载后很快会被用到的资源,所以在页面加载的过程中,我们希望在浏览器开始主题渲染之前尽早preload。
默认情况下,一个vue-cli 应用会为所有初始化渲染需要的文件自动生成preload提示。这些提示会被 @vue/preload-webpack-plugin 注入,并且通过chainWebpack的config.plugin('preload')进行修改和删除
Prefetch (预取)
<link rel="prefetch">是一种资源提示,用来告诉浏览器在页面加载完成后,利用空闲时间内预取用户可能在不久的将来访问的内容。
默认情况下,Vue Cli应用程序将自动为async chunk 生成的 JavaScript 文件自动生成prefetch提示。
这些提示会被@vue/preload-webpack-plugin 注入,并且可以通过chainWebpack的config.plugin('prefetch') 进行修改和删除。
//vue.config.js
module.exports = {
chainWebpack: config => {
// 移出prefetch 插件
config.plugin.delete("prefetch")
}
//或者修改他的选项:
config.plugin("prefetch").tap(options => {
options[0].fileBlacklist = options[0].fileBlacklist || []
options[0].fileBlacklist.push(/myasyncRoute(.)+?\.js$/)
return options
})
}
当prefetch插件被禁用时,可以通过webpack的内联注释手动选定要提前获取的代码区块:
import(/* webpackPrefetch:true */ './someAsyncComponent.vue')
webpack 运行时 会在父级区块被加载后注入prefetch链接。
注意:
Prefetch 链接将会消耗带宽。如果应用很大且有很多async chunk ,而用户主要使用的是对带宽较敏感的移动端,那么可能需要关掉prefetch链接并手动选择要提前获取的代码区块。
不生成index
当基于已有的后端使用Vue CLI时,可能不需要生成index.html,这样生成的资源可以用于一个服务端渲染的页面。这时可以向 vue.config.js加入以下代码
// vue.config.js
module.exports = {
// 删除文件名中的hash
filenameHashing: false,
//删除HTML相关的webpack插件
chainWebpack: config => {
config.plugins.delete('html')
config.plugins.delete('preload')
config.plugins.delete('prefetch')
}
}
然而不推荐这样做,因为:
- 硬编码的文件名不利于实现高效率的缓存控制。
- 硬编码的文件名也无法很好的进行code-splitting(代码分段),因为无法用变化的文件名生成额外的JavaScript文件。
- 硬编码的文件名无法在现代模式下工作。
应该考虑换用indexPath选项将生成的HTML用作一个服务端框架的视图模板。
构建一个多页应用
不是每个应用都需要是一个单页面应用。Vue CLI 支持使用 vue.config.js中的pages选项构建一个多页面的应用。构建好的应用将会在不同的入口之间高效共享通用的chunk以获得最佳的加载性能。
处理静态资源
静态资源可以通过两种方式进行处理:
- 在JavaScript被导入或在template/CSS中通过相对路径被引用。这类引用会被 webpack 处理
- 放置在public目录下或通过绝对路径被引用。这类资源将会直接拷贝,而不经过 webpack的处理
从相对路径导入
当在JavaScript、CSS或者.vue文件中使用相对路径(必须以.开头)引用一个静态资源时,该资源将会被包含进入webpack的依赖图中。在其编译过程中,所有诸如<img src="...">、background: url(...)和CSS @import 的资源URL都会被解析为一个模块依赖。
例如,url(./img.png)会被翻译为 require('./image.png'),而:
<img src="./image.png">
将会被编译到:
h('img', { attrs: { src:require('./image.png') }})
在其内部,我们通过file-loader用版本哈希值和正确的公共基础路径来决定最终的文件路径,再用url-loader将小于4kb的资源内联,以减少HTTP请求的数量。
可以通过 chainWebpack 调整内联文件大小限制。例如,以下代码会将其限制设置为10kb:
// vue.config.js
module.exports = {
chainWebpack: config => {
config.module
.rule('images')
.use('url-loader')
.loader('url-loader')
.tap( options => Object.assign(options, {limit: 10240}))
}
URL转换规则
- 如果URL是一个绝对路径(例如/image/foo.png),他将会被保留不变。
- 如果URL是以
.开头,它会作为一个相对模块请求被解释且基于文件系统中的目录结构进行解析。 - 如果URL是以
~开头,其后的任何内容都会作为一个模块被解析。这意味者可以引用Node模块中的资源:<img src='~some-npm-package/foo.png'> - 如果URL是以
@开头,它也会作为一个模块请求被解析。它的用处在于Vue CLI默认会设置一个指向项目根目录/src的别名@。
public文件夹
任何放置在public文件夹的静态资源都会被简单的复制,而不经过webpack。需要通过绝对路径来引用他们。
注意推荐资源作为模块依赖图的一部分导入,这样它们会通过webpack的处理并获得如下好处
- 脚本和样式表会被压缩且打包在一起,从而避免额外的网络请求。
- 文件丢失会直接在编译时报错,而不是到了客户端才产生404错误。
- 最终生成的文件名包含了内容哈希,因此不必担心浏览器会缓存他们的老版本。
public 目录提供的是一个应急手段,当通过绝对路径引用它时,留意应用将会部署到哪里。如果应用没有部署到域名的根部,那么需要为URL配置 publicPath前缀:
- 在public/index.html或其它通过html-webpack-plugin用作模板的HTML文件中,需要通过,
<%=BASE_URL%>设置链接前缀:<link rel="icon" href="<%=BASE_URL%>favicon.ico"> - 在模板中,首先需要向组件传入基础URL:
data(){return{publicPath:process.env.BASE_URL}}然后:<img :src=${publicPath}my-image.png>
如何使用public文件夹
- 需要在构建输出中指定一个文件的名字
- 有上千张图片,需要动态引用他们的路径。
- 有些库可能和webpack不兼容,这是除了将其用一个独立的
<script>标签引入没有别的选择