AWS 的 S3 可以提供静态网站托管,但是 Vue、React 等框架生成的单页应用的部署略有不同,直接把 build 出来的 dist 目录传上去并不能访问,需要进行一些小小的配置。

修改储桶权限使之能公开访问

打开权限选项卡,然后确保选择公有访问设置。把以下策略文档输入到存储桶策略编辑器,否则每次上传都要设置一次公开,太麻烦了。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow", 
            "Principal": "*", 
            "Action": "s3:GetObject", 
            "Resource": "arn:aws:s3:::[YOUR_BUCKET_NAME]/*" 
        } 
    ] 
}

启用静态网站托管

打开属性选项卡,启用静态网站托管。
注意:索引文档和错误文档都要填写index.html
此时,使用S3分配的域名访问已经完全没有问题了。但在CloudFront中分配之后,在访问非根路由路径时,S3 会发现文件不存在,然后返回404。下一步就是来解决这个问题的。

配置 CloudFront

打开错误页选项卡,创建自定义错误响应。
将404响应为200,页面路径填写index.html,如下图

此时就可以用 CloudFront CDN 加速愉快地访问啦。

使用命令行部署

项目更新之后,每次都要进后台手动上传 dist 目录可太麻烦了,好在 S3 提供了命令行的上传方式,首先要安装 awscli 并配置,然后便可以使用下面命令一键部署

aws s3 sync dist s3://[YOUR_BUCKET_NAME] --delete

关于CloudFront缓存的注意事项

CloudFront就是AWS的cdn加速,可以将网站的副本缓存在世界各地,使网站访问速度更快。问题是如果对页面进行更改,要等很久才会更新。可以通过对象失效来从缓存中删除:

  • 打开CloudFront并选择分配
  • 打开失效标签
  • 创建一个失效,并将对象路径设置为:/*

同样可以以命令行的方式进行操作:

aws cloudfront create-invalidation --distribution-id [distribution_ID] --paths "/*"

参考资料

https://aws.amazon.com/cn/getting-started/hands-on/build-serverless-web-app-lambda-apigateway-s3-dynamodb-cognito/
https://segmentfault.com/a/1190000008343967
https://docs.aws.amazon.com/cli/latest/reference/cloudfront/create-invalidation.html