本文最后更新于 1870 天前,其中的信息可能已经有所发展或是发生改变。
内容纲要
背景
前一篇文章中我谈到如何修改vue.config.js
为Vue-CLI项目添加CDN,实现为静态资源加速的目标。
考虑到VuePress静态资源为数也不少,因此也尝试为其打包的结果做一下CDN。
目标
尽可能将静态资源请求到CDN上
正文
通过研究VuePress的文档,官方并没有向Vue-CLI那样提供一个path使得静态资源重定向到目标的URL。
之前在网上也有issue提到关于CDN加速的问题,官方也没有给出相关的解决方法。
于是考虑设计一套workaround方案,研究生成的目标文件中的内容。
不难发现,在docs/.vuepress/dist/assets/js/app.*.js
文件中,对象a
下的属性p
(即a.p
)给定了所有js文件的prefix。
因此可以考虑设计脚本,在编译完成后批量替换。
另外,文档中会涉及到许多的html文件中的静态资源的替换。因此可以考虑将html文件使用cheerio读入DOM,批量替换link。
以CUP Online Judge Docs为例
#!/bin/bash
WEBPATH="https://cdn.jsdelivr.net/gh/CUP-ACM-Programming-Club/CUPACM-Docs-CDN@v$(cat VERSION)/"
if [[ "$OSTYPE" == "darwin"* ]]; then
sed -i "" "s|a.p=\"/\"|a.p=\"$WEBPATH\"|g" docs/.vuepress/dist/assets/js/app.*.js
sed -i "" "s|/assets/img/|$WEBPATH/assets/img/|g" docs/.vuepress/dist/assets/css/*.css
else
sed -i "s|a.p=\"/\"|a.p=\"$WEBPATH\"|g" docs/.vuepress/dist/assets/js/app.*.js
sed -i "s|/assets/img/|$WEBPATH/assets/img/|g" docs/.vuepress/dist/assets/css/*.css
fi
node .github/shell/build_cdn_environment.js
const glob = require("glob");
const fs = require("fs");
const path = require("path");
const cheerio = require("cheerio");
const version = fs.readFileSync("VERSION");
const webPath = `https://cdn.jsdelivr.net/gh/CUP-ACM-Programming-Club/CUPACM-Docs-CDN@v${version}`;
function rewriteSrc (element, $, attr) {
element.each(function () {
const src = $(this).attr(attr);
if (src.indexOf("http") !== -1) {
return;
}
$(this).attr(attr, webPath + src);
})
}
function writeSrc (element, $, dir) {
element.each(function () {
const src = $(this).attr("src");
if (src.indexOf("http") !== -1) {
return;
}
$(this).attr("src", webPath + path.join(dir, src));
})
}
function loadFile() {
const htmlFileList = glob.sync(`docs/.vuepress/dist/**`)
.filter(name => {
return fs.lstatSync(name).isFile()
})
.filter(name => {
return name.substring(name.length - 5) === '.html';
});
htmlFileList.forEach(filePath => {
const content = fs.readFileSync(filePath, "utf-8");
const $ = cheerio.load(content);
const script = $("script");
const css = $("link");
rewriteSrc(script, $, "src");
rewriteSrc(css, $, "href");
writeSrc($("img"), $, path.dirname(filePath).replace("docs/.vuepress/dist", ""));
fs.writeFileSync(filePath, $.html());
});
}
loadFile();
关于发布CDN的过程,可参考上一篇文章,这里略过不提。
设计一个Github Actions的step
- name: Build distribution
run: |
npm i
npm run docs:build
./.github/shell/after_build.sh
即可完成上面的工作。
以上即完成了CDN静态资源的工作。然而,仍有少数资源没有完成全部的替换,可根据build_cdn_environment.js
的格式,编写替换规则。
存在的问题
通过上面的方法可以解决大部分资源走CDN,但是html文件必须直接访问服务器。
对于服务器速度本身就比较慢的情况,比如说Github Pages,可考虑使用DNS做境内境外不同的CNAME,境内使用Coding Pages,境外使用Github Pages,简单设置Actions,将dist推到两个仓库即可。