前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >将网站静态资源全部上传到cdn

将网站静态资源全部上传到cdn

作者头像
心念
发布2023-01-12 10:16:59
6.6K0
发布2023-01-12 10:16:59
举报
文章被收录于专栏:前端心念前端心念

1. 对象存储

对象存储类似云盘,可以将一些小文件存储进去,并暴露出来外链,配合cdn之后访问非常快。我们的目标就是把网站的css、js、图片等其他一些资源上传进去,再通过cdn来加速访问。

这里我使用到的是腾讯云的cos对象存储: https://console.cloud.tencent.com/cos

1.1 新建存储桶

首先新建一个存储桶

选个离自己近的地域,起个名称,先选择公有读私有写。然后一路下一步就行。

1.2 上传文件

点进刚刚建好的存储桶,随便上传一个文件,我传了一个图片

1.3 查看域名

存储桶列表,找到刚刚建好的存储桶,点配置管理,可以看到我们的访问域名

访问域名+文件路径 就可以访问到我们上传到存储桶的资源

可以直接访问测试一下

2. node自动上传

我们可以在存储桶上传我们的js、css之类的文件、不过我们的文件那么多,一个一个上传明显不合理。要你你也不干。

这时候,这些批量又重复的操作应该由我们的node出马,让我们来通过 node来批量上传我们的资源文件

2.1 获取密钥

在密钥管理下可以新建一个密钥,一会要用

2.2 遍历目录

既然要上传所有静态文件,那么就要先拿到所有静态文件的绝对路径。这里我写了个方法文件,可以遍历指定目录,返回一个数组。

注意,遍历目录的方法是异步的,所以这里使用promise,大概一秒足够遍历完所有文件

代码语言:javascript
复制
1// node fs模块
2const fs = require("fs");
3// node path模块
4const path = require("path");
5
6// 收集所有的文件路径
7const arr = [];
8const fileDisplay = (filePath) => {
9  //根据文件路径读取文件,返回文件列表
10  return new Promise((resolve) => {
11    fs.readdir(filePath, function (err, files) {
12      if (err) return console.error("Error:(spec)", err);
13      files.forEach((filename) => {
14        //获取当前文件的绝对路径
15        const filedir = path.join(filePath, filename);
16        // fs.stat(path)执行后,会将stats类的实例返回给其回调函数。
17        fs.stat(filedir, (eror, stats) => {
18          if (eror) return console.error("Error:(spec)", err);
19          // 是否是文件
20          const isFile = stats.isFile();
21          // 是否是文件夹
22          const isDir = stats.isDirectory();
23          if (isFile) {
24            // 这块我自己处理了多余的绝对路径,第一个 replace 是替换掉那个路径,第二个是所有满足的直接替换掉
25            arr.push(
26              filedir
27                .replace(
28                  "D:lhstudyjiaoshoujiavuegenerator-lh-vuegeneratorsapp",
29                  ""
30                )
31                .replace(//gim, "/")
32            );
33          }
34          // 如果是文件夹
35          if (isDir) fileDisplay(filedir);
36        });
37      });
38    });
39
40    setTimeout(() => {
41      resolve(arr);
42    }, 1000);
43  });
44};
45module.exports = fileDisplay;
46

2.3 编写上传脚本

脚本思路就是,先把cdn上原来旧的文件清理,然后再将新文件逐一上传。 这里封装了两个方法

代码语言:javascript
复制
1const fs = require("fs");
2const path = require("path");
3const COS = require("cos-nodejs-sdk-v5");
4//上面封装的遍历目录方法
5const fileDisplay = require("./fileDispaly");
6//2.1拿到的密钥
7const cos = new COS({
8  SecretId: "xxxxxxxxxxxx",
9  SecretKey: "xxxxxxxxxxxxxxx",
10});
11/* 存储桶名称 */
12const bucket = "hylcdn-1305519392";
13/* 存储桶所在地域 */
14const region = "ap-beijing";
15
16// 需要上传的文件夹地址
17const filePath = path.resolve("build/");
18
19// 批量删除文件,先查后删
20const deleteOldFile = () => {
21  return new Promise((resolve) => {
22    cos.getBucket(
23      {
24        Bucket: bucket,
25        Region: region,
26        Prefix: "static/", //要清理的目录
27        Marker: "static/", //要清理的目录
28        MaxKeys: 1000,
29      },
30      function (listError, listResult) {
31        if (listError) return console.log("list error:", listError);
32        var objects = listResult.Contents.map(function (item) {
33          return { Key: item.Key };
34        });
35        if (objects.length) {
36          cos.deleteMultipleObject(
37            {
38              Bucket: bucket,
39              Region: region,
40              Objects: objects,
41            },
42            function (delError, deleteResult) {
43              if (delError) {
44                console.log(delError);
45              }
46              if (deleteResult?.statusCode === 200) {
47                console.log("清理原static目录成功!");
48                resolve();
49              }
50            }
51          );
52        } else {
53          console.log("目录下无资源,无需删除!");
54          resolve();
55        }
56      }
57    );
58  });
59};
60
61//单个上传文件
62const uploadFile = (pathItem) => {
63  cos.putObject(
64    {
65      Bucket: bucket,
66      Region: region,
67      Key: `static/${pathItem.split("static/")[1]}`, //上传到 存储桶 的路径 *
68      StorageClass: "STANDARD",
69      Body: fs.createReadStream(pathItem), // 被上传的 文件对象
70    },
71    function (err, data) {
72      if (data?.statusCode === 200) {
73        console.log(`上传${pathItem.split("/").pop()}到cdn成功!`);
74      }
75    }
76  );
77};
78
79const playUpload = async () => {
80  // 先删除原来的static
81  await deleteOldFile();
82  // 获取即将上传的所有文件路径
83  const fileData = await fileDisplay(filePath);
84  // 开始逐一上传
85  fileData.forEach((item) => {
86    uploadFile(item);
87  });
88};
89
90playUpload();
91

2.4 效果

运行脚本

3. 修改项目的静态文件指向

项目默认一般是指向根目录,我们把它改成我们的存储桶cdn链接(这里我使用了自定义域名,1.3那个访问域名也可以)

以creat-react-app为例

效果,使用了cdn链接后资源加载的非常快

4. 自动化部署

修改package.json scripts配置

将打包,上传cdn,上传服务器 三个脚本合成一个指令

一条龙服务

附上我上传项目到服务器的脚本配置

代码语言:javascript
复制
1const scpClient = require("scp2")
2const ora = require("ora")
3const server = {
4    host:"xx.xx.xx.xx",//服务器IP
5    port:22,//服务器端口
6    username:"root",//服务器ssh登录用户名
7    password:"xxx",//服务器ssh登录密码
8    path:"/www/wwwroot/my-blog"//服务器web目录
9}
10const loading = ora("正在部署至 " + server.host )
11loading.start()
12scpClient.scp("build/", server ,(err)=>{
13loading.stop()
14    if(err) {
15        console.log("部署失败")
16        throw err
17    }else {
18        console.log("部署成功")
19    }
20})
21

可能遇到的问题

1、产生了额外的流量费,欠费。

因为这个存储桶会产生四种流量费,建议都购买一下

  • 标准存储容量费用:这个开始会自动送你50个G
  • CDN 回源流量费用:这个需要买,一年十块左右
  • 标准存储请求费用:一年一块钱
  • 外网下行流量费用:一个月三块左右
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

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

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1. 对象存储
    • 1.1 新建存储桶
      • 1.2 上传文件
        • 1.3 查看域名
        • 2. node自动上传
          • 2.1 获取密钥
            • 2.2 遍历目录
              • 2.3 编写上传脚本
                • 2.4 效果
                • 3. 修改项目的静态文件指向
                • 4. 自动化部署
                • 可能遇到的问题
                相关产品与服务
                对象存储
                对象存储(Cloud Object Storage,COS)是由腾讯云推出的无目录层次结构、无数据格式限制,可容纳海量数据且支持 HTTP/HTTPS 协议访问的分布式存储服务。腾讯云 COS 的存储桶空间无容量上限,无需分区管理,适用于 CDN 数据分发、数据万象处理或大数据计算与分析的数据湖等多种场景。
                领券
                问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档