前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >将静态资源推至 OSS

将静态资源推至 OSS

原创
作者头像
PHP开发工程师
发布2022-06-02 10:07:26
6.4K0
发布2022-06-02 10:07:26
举报
文章被收录于专栏:thinkphp+vue

PUBLIC_PATH 与 webpack 的处理

假设将带有 hash 值的静态资源推至 CDN 中,此时静态资源的地址为: https://cdn.shanyue.tech。而它即是我们将要在 webpack 中配置的 config.output.publicPath

代码语言:javascript
复制
module.exports = {
  output: {
    publicPath: 'https://cdn.shanyue.tech'
  }
}
复制代码

create-react-app 中,对 webpack config 做了进一步封装,阅读其源码,了解其 webpack.config.js 配置。

代码语言:javascript
复制
const publicUrlOrPath = getPublicUrlOrPath(
  process.env.NODE_ENV === 'development',
  require(resolveApp('package.json')).homepage,
  process.env.PUBLIC_URL
)

const config = {
  output: {
    // webpack uses `publicPath` to determine where the app is being served from.
    // It requires a trailing slash, or the file assets will get an incorrect path.
    // We inferred the "public path" (such as / or /my-project) from homepage.
    publicPath: paths.publicUrlOrPath,
  },
}
复制代码

可知 cra 中通过设置环境变量 PUBLIC_URL 即可配置 CDN 地址

代码语言:javascript
复制
export PUBLIC_URL=https://cdn.shanyue.tech
复制代码

OSS 云服务之前的准备

AccessKey

  • aliyun_access_key_id
  • aliyun_access_key_secret

在将静态资源上传至云服务时,我们需要 AccessKey/AccessSecret 获得权限用以上传。可参考文档创建 AccessKey

Bucket

Bucket 是 OSS 中的存储空间。对于生产环境,可对每一个项目创建单独的 Bucket,而在测试环境,多个项目可共用 Bucket。

在创建 Bucket 时,需要注意以下事项

  1. 权限设置为公共读 (Public Read)
  2. 跨域配置 CORS (manifest.json 需要配置 cors)
  3. 记住 Endpoint,比如 oss-cn-beijing.aliyuncs.com。将会在配置 PUBLIC_URL 中使用到

对于 Endpoint 的选择,可参考 访问域名和数据中心

PUBLIC_URL

最终的 PUBLIC_URL 为 $Bucket.$Endpoint,比如本篇文章示例项目的 PUBLIC_URL 为 https://shanyue-cra.oss-cn-beijing.aliyuncs.com

但是,你也可以配置 CNAME 记录并使用自己的域名。

在以下命令行及代码示例中,我们将 cra-deploy 项目的静态资源全部上传至 shanyue-cra 该 Bucket 中。

将资源推送到 OSS: ossutil

在 OSS 上创建一个 Bucket,通过官方工具 ossutil 将静态资源上传至 OSS。

在进行资源上传之前,需要通过 ossutil config 进行权限配置。

代码语言:javascript
复制
$ ossutil config -i $ACCESS_KEY_ID -k $ACCESS_KEY_SECRET -e $ENDPOINT
复制代码

命令 ossutil cp 可将本地资源上传至 OSS。而缓存策略与前篇文章保持一致:

  1. 带有 hash 的资源一年长期缓存
  2. 非带 hash 的资源,需要配置 Cache-Control: no-cache,避免浏览器默认为强缓存
代码语言:javascript
复制
# 将资源上传到 OSS Bucket
# --meta: 配置响应头,也就是这里的缓存策略
# oss://shanyue-cra/: bucket 名字
$ ossutil cp -rf --meta Cache-Control:no-cache build oss://shanyue-cra/

# 将带有 hash 资源上传到 OSS Bucket,并且配置长期缓存
# 注意此时 build/static 上传了两遍 (可通过脚本进行优化)
$ ossutil cp -rf --meta Cache-Control:max-age=31536000 build/static oss://shanyue-cra/static
复制代码

为求方便,可将两条命令维护到 npm scripts

代码语言:javascript
复制
{
  scripts: {
    'oss:cli': 'ossutil cp -rf --meta Cache-Control:no-cache build oss://shanyue-cra/ && ossutil cp -rf --meta Cache-Control:max-age=31536000 build/static oss://shanyue-cra/static'
  }
}
复制代码

将资源推送到 OSS: npm scripts

另有一种方法,通过官方提供的 SDK: ali-oss 可对资源进行精准控制:

  1. 对每一条资源进行精准控制
  2. 仅仅上传变更的文件
  3. 使用 p-queue 控制 N 个资源同时上传
代码语言:javascript
复制
{
  scripts: {
    'oss:script': 'node ./scripts/uploadOSS.js'
  }
}
复制代码

脚本略过不提。

PS: 上传 OSS 的配置文件位于 scripts/uploadOSS.js 中,可通过它使用脚本控制静态资源上传。

Dockerfile 与环境变量

PS: 该 Dockerfile 配置位于 cra-deploy/oss.Dockerfile

由于 Dockerfile 同代码一起进行管理,我们不能将敏感信息写入 Dockerfile

故这里使用 ARG 作为变量传入。而 ARG 可通过 docker build --build-arg 抑或 docker-compose 进行传入。

代码语言:javascript
复制
FROM node:14-alpine as builder

ARG ACCESS_KEY_ID
ARG ACCESS_KEY_SECRET
ARG ENDPOINT
ENV PUBLIC_URL https://shanyue-cra.oss-cn-beijing.aliyuncs.com/

WORKDIR /code

# 为了更好的缓存,把它放在前边
RUN wget http://gosspublic.alicdn.com/ossutil/1.7.7/ossutil64 -O /usr/local/bin/ossutil \
  && chmod 755 /usr/local/bin/ossutil \
  && ossutil config -i $ACCESS_KEY_ID -k $ACCESS_KEY_SECRET -e $ENDPOINT

# 单独分离 package.json,是为了安装依赖可最大限度利用缓存
ADD package.json yarn.lock /code/
RUN yarn

ADD . /code
RUN npm run build && npm run oss:cli

# 选择更小体积的基础镜像
FROM nginx:alpine
ADD nginx.conf /etc/nginx/conf.d/default.conf
COPY --from=builder code/build /usr/share/nginx/html
复制代码

docker-compose 配置

PS: 该 compose 配置位于 cra-deploy/docker-compose.yaml

docker-compose 配置文件中,通过 build.args 可对 Dockerfile 进行传参。

docker-compose.yaml 同样不允许出现敏感数据,此时通过环境变量进行传参,在 build.args 中,默认从宿主机的同名环境变量中取值。

PS: 在本地可通过宿主机环境变量传值,那在 CI 中呢,在生产环境中呢?待以后 CI 篇进行揭晓。

首先手动配置宿主机的环境变量,与 Dockerfile 中环境变量同名:

代码语言:javascript
复制
# 此两项数据需要在阿里云进行获取
export ACCESS_KEY_ID=LTshanyueoworlJEdoPhello
export ACCESS_KEY_SECRET=bhZHelloShanzOxsHelloshanIyueM
复制代码

此时可通过 docker-compose 中的 build.args 将宿主机的环境变量传递给 Dockerfile:

代码语言:javascript
复制
version: "3"
services:
  oss:
    build:
      context: .
      dockerfile: oss.Dockerfile
      args:
        # 此处默认从宿主机(host)环境变量中传参,在宿主机中需要提前配置 ACCESS_KEY_ID/ACCESS_KEY_SECRET 环境变量
        - ACCESS_KEY_ID
        - ACCESS_KEY_SECRET
        - ENDPOINT=oss-cn-beijing.aliyuncs.com
    ports:
      - 8000:80
复制代码

RUN 起来,成功!

代码语言:javascript
复制
$ docker-compose up --build oss
复制代码

免费的托管服务平台

经过几篇文章的持续优化,当我们使用对象存储服务之后,实际上在我们的镜像中仅仅只剩下几个文件。

  • index.html
  • robots.txt
  • favicon.ico

那我们可以再进一步,将所有静态资源都置于公共服务中吗?

可以,实际上 OSS/COS (对象存储服务) 也可以如此配置,但是较为繁琐,如 Rewrite、Redirect 规则等配置。

如果,你既没有个人服务器,也没有属于个人的域名,可将自己所做的前端网站置于以下免费的托管服务平台。

  1. Vercel
  2. Github Pages
  3. Netlify

小结

通过本篇文章,我们已将静态资源部署至 CDN (近乎等同于 CDN),与大部分公司的生产环境一致。

但在测试环境中最好还是建议无需上传至 OSS,毕竟上传至 OSS 需要额外的时间,且对于测试环境无太大意义。

源码附件已经打包好上传到百度云了,大家自行下载即可~

代码语言:javascript
复制
链接: https://pan.baidu.com/s/14G-bpVthImHD4eosZUNSFA?pwd=yu27

开源地址

码云地址: http://github.crmeb.net/u/defu

Github 地址: http://github.crmeb.net/u/defu

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • PUBLIC_PATH 与 webpack 的处理
  • OSS 云服务之前的准备
    • AccessKey
      • Bucket
        • PUBLIC_URL
        • 将资源推送到 OSS: ossutil
        • 将资源推送到 OSS: npm scripts
        • Dockerfile 与环境变量
        • docker-compose 配置
        • 免费的托管服务平台
        • 小结
        • 开源地址
        相关产品与服务
        容器镜像服务
        容器镜像服务(Tencent Container Registry,TCR)为您提供安全独享、高性能的容器镜像托管分发服务。您可同时在全球多个地域创建独享实例,以实现容器镜像的就近拉取,降低拉取时间,节约带宽成本。TCR 提供细颗粒度的权限管理及访问控制,保障您的数据安全。
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档