Vue静态资源上CDN方案简述

5,741 阅读1分钟

描述

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

已知Vueconfig提供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")