描述
CDN原理简析 juejin.cn/post/684490…
设有Vue工程example
打包,在服务器/web/example/
目录部署以下资源,
|-- index.html
|-- static
|-- js
|-- img
|-- css
静态资源的域名假定为static.example.cn
,站点的域名为www.example.cn
。
打包构建的时候,静态资源需要以绝对地址来引用,比如js/app.[hash].js
在构建后有目录作为区分,最终可能为static.example.cn/web/example/js/app.[hash].js
。
已知Vue
的config
提供publicPath
来配置资源路径,outputDir
来指定输出目录。可参Vue CLI文档
const staticHost = '//static.example.cn'
const baseURL = '/web/example/'
实践方案
上面说道,部署后访问的静态资源为绝对地址static.example.cn/web/example/
,也就是说我们要把资源引用都加上这个前缀。我们开始配置第一步:
const publicPath = `${staticHost}${baseURL}`
const outputDir = path.join(process.cwd(), `dist/${basePath}`)
module.exports = {
publicPath,
outputDir,
// ...
}
完成第一步后,我们打包可以发现,资源的输出目录变为了:
|-- web
|-- example
|-- index.html
|-- static
|-- js
|-- img
|-- css
html中的引用js如下:
<script src=https://static.estudy.cn/web/example/js/app.0f9f5416.js></script>
如下代码中测试图片的引入,然后配nginx,host,第二步模拟环境测试。
<template>
<div>
<img src="~static/img/bigdata/ranking/header_bg.gif" alt="">
<img :src="testImportSrc" alt="">
<img :src="testSrc" alt="">
<img :src="false || 'static/img/bigdata/ranking/header_bg.gif'" alt="">
<!-- 下面的方式是有问题的,忽略 -->
<img :src="false || '~static/img/bigdata/ranking/header_bg.gif'" alt="">
</div>
</template>
<script>
import testImportSrc from 'static/img/bigdata/ranking/header_bg.gif'
export default {
data() {
return {
testSrc: require('static/img/bigdata/ranking/header_bg.gif'),
testImportSrc,
};
},
}
</script>
dev
build
可以看到,运行时逻辑引入的资源路径,loader是不做处理的,所以我们需要对这种写法做兼容方案处理。
兼容方案简述
以下方案需要区分development/production
环境。
publicPath
可以通过process.env.BASE_URL
来获取。
Vue模板template中
在mixins
或者Vue.prototype
挂上BASE_URL
。
<img :src="false || `${BASE_URL}static/img/bigdata/ranking/header_bg.gif`" alt="">
js脚本中
可以考虑在window上挂,如果是.vue
文件中,如上述挂在原型,this.BASE_URL
获取。
const BASE_URL = process.env.BASE_URL || ''
// 或
window.BASE_URL = process.env.BASE_URL || ''
// .vue script
`${this.BASE_URL}static/img/bigdata/ranking/header_bg.gif`
scss中
通过css.loaderOptions.sass
配置sass的loader,注入$BASE_URL
变量,在scss中使用(less等预处理同理):
background: url("#{$BASE_URL}static/img/bigdata/ranking/header_bg.gif")