Hexo博客开发(2)
目的
- 使用AWS Lambba通知CloudFront自动进行更新.
- 对生成后的文件进行瘦身, 加快加载的时间.
CloudFront自动更新
CloudFront本质上就是一个K/V缓存. 对CloudFront发的请求将会在CloudFront本地检索,
- 如果找到了就直接返回,
- 没找的话就根据行为(Behaviors)的路径转发到不同的源(Origin), 将结果在本地缓存, 然后返回给用户
所以除了刚启动的时候请求可能会经过1-6步骤, 大部分情况下请求在步骤2时就会返回结果. 这也导致了当对已经在缓存里的文章进行更新, 新的文章往往不会被返回(新的文章在S3里, 而用户获取的是CloudFront缓存里的).
这时就应该将CloudFront里的缓存进行无效化(Invalidation), 使请求重新经过步骤1-6. 在当前CloudFront的节点下的”Invalidations”标签下选中Create Invalidation, 在输入框处填 /* 使所有内容无效.
但是这样的话每次内容更新都需要无效化当前的CloudFront, 也太麻烦了. 为了自动化这个步骤, 这里将创建一个新的Lambda函数, 将S3的更新作为触发器, 对CloudFront发送一个无效化内容的请求.
- 创建一个新的Lambda函数, 就叫”my-blog-lambda-invalidate-cloudfront”, 直接默认配置点击创建.
- 进入新的函数, 在”配置”标签的左边找到”触发器”并添加一个新的触发器. 源的话使用S3放置网站的Bucket.
- 模式(Event Type)的话就选在写入(Put)的时触发.
- Prefix填写 index.html
- Prefix填写 index.html
Lambda函数的代码使用nodejs来完成, javascript官方文档没有例子和python官方文档有例子
1 | import { CloudFrontClient, CreateInvalidationCommand} |
需要注意的是
- DistributionId不是ARN, 是ARN最后斜杆的标识. 如, ARN为arn:aws:cloudfront::<
>:distribution/AAAAABBBBB1123. 那么DistributionId就是“AAAAABBBBB1123”。 - 所有请求的变量都要写, 否则函数回报变量为null的错误.
最后发布(Deploy), 这样的话每当CodeBuild将编译完成的博客保存到S3时, 上面的Lambda函数就会被调用, 无效化CloudFront中旧的博客.
Gulp减少文件体积
Gulp是一款自动化工具. 这里将使用Gulp对Hexo生成的博客代码/素材进行瘦身, 是其可以更快得被加载. 这里的配置都是依照Butterfly主题的官方源码来配的.
- 增加包依赖更新CodeBuild的buildspec.yml
1
2yarn add --dev gulp
yarn add gulp-html-minifier-terser gulp-htmlclean gulp-imagemin1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22version: 0.2
phases:
# No need for install because of taskbjorn/hexo container
install:
runtime-versions:
nodejs: 18
commands:
- npm install
- npm install -g hexo-cli
- npm install -g gulp-cli
build:
on-failure: ABORT
commands:
- echo Start building website
- hexo generate
- gulp
artifacts:
files:
- '**/*'
base-directory: public - 在根目录下添加一个文件在gulpfile.js, 引用这里
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55const gulp = require('gulp')
const cleanCSS = require('gulp-clean-css')
const htmlmin = require('gulp-html-minifier-terser')
const htmlclean = require('gulp-htmlclean')
const imagemin = require('gulp-imagemin')
const terser = require('gulp-terser');
// minify js
gulp.task('compress', () =>
gulp.src(['./public/**/*.js', '!./public/**/*.min.js'])
.pipe(terser())
.pipe(gulp.dest('./public'))
)
// css
gulp.task('minify-css', () => {
return gulp.src('./public/**/*.css')
.pipe(cleanCSS())
.pipe(gulp.dest('./public'))
})
// 壓縮 public 目錄內 html
gulp.task('minify-html', () => {
return gulp.src('./public/**/*.html')
.pipe(htmlclean())
.pipe(htmlmin({
removeComments: true, // 清除 HTML 註釋
collapseWhitespace: true, // 壓縮 HTML
collapseBooleanAttributes: true, // 省略布爾屬性的值 <input checked="true"/> ==> <input />
removeEmptyAttributes: true, // 刪除所有空格作屬性值 <input id="" /> ==> <input />
removeScriptTypeAttributes: true, // 刪除 <script> 的 type="text/javascript"
removeStyleLinkTypeAttributes: true, // 刪除 <style> 和 <link> 的 type="text/css"
minifyJS: true, // 壓縮頁面 JS
minifyCSS: true, // 壓縮頁面 CSS
minifyURLs: true
}))
.pipe(gulp.dest('./public'))
})
// 壓縮 public/uploads 目錄內圖片
gulp.task('minify-images', async () => {
gulp.src('./public/assets/**/*.png')
.pipe(imagemin({
optimizationLevel: 5, // 類型:Number 預設:3 取值範圍:0-7(優化等級)
progressive: true, // 類型:Boolean 預設:false 無失真壓縮jpg圖片
interlaced: false, // 類型:Boolean 預設:false 隔行掃描gif進行渲染
multipass: false // 類型:Boolean 預設:false 多次優化svg直到完全優化
}))
.pipe(gulp.dest('./public/assets'))
})
// 執行 gulp 命令時執行的任務
gulp.task('default', gulp.parallel(
'compress', 'minify-css', 'minify-html', 'minify-images'
))
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Ryon49's Blog!