0%

使用 Node.js 部署静态资源到七牛云

在最近的一个项目中,为了缩短加载时间,同时减轻服务器的压力,我们决定将前端静态资源全数放到七牛云上。更新内容时只需上传 static 目录下的所有文件(使用 webpack 打包),然后发布 index.html 到网站根目录即可。

我决定使用 Node.js 上传资源,方便之后和 webpack 的打包脚本整合到一起,优化工作流。

安装七牛云 Node.js SDK:

1
npm install qiniu --save

新建一个脚本 build/deploy.js,引入相关包。fs 用于读取文件和文件夹。

1
const fs = require('fs')
2
const qiniu = require('qiniu')

声明常量:

1
// 授权秘钥
2
const accessKey = '{你的七牛云 AccessKey}'
3
const secretKey = '{你的七牛云 SecretKey}'
4
5
// 存储空间名称
6
const bucket = '{你的 Bucket 名称}'
7
8
// 要上传的资源目录
9
const staticPath = 'dist/static'
10
11
// 上传后的文件前缀
12
const prefix = 'static'

配置 Bucket 所在的区域,然后生成上传对象 formUploader,同时实例化上传时需要的 macputExtra 对象。mac 用于验证身份,putExtra 用于在上传时传额外参数。

1
// 创建鉴权对象
2
const mac = new qiniu.auth.digest.Mac(accessKey, secretKey)
3
4
// 创建并修改配置对象(Zone_z0=华东 Zone_z1=华北 Zone_z2=华南 Zone_na0=北美)
5
const config = new qiniu.conf.Config()
6
config.zone = qiniu.zone.Zone_z2
7
8
// 创建额外内容对象
9
const putExtra = new qiniu.form_up.PutExtra()
10
11
// 创建表单上传对象
12
const formUploader = new qiniu.form_up.FormUploader(config)

定义上传单个文件的方法:

1
// 文件上传方法
2
function uploadFile (localFile) {
3
  // 配置上传到七牛云的完整路径
4
  const key = localFile.replace(staticPath, prefix)
5
  const options = {
6
    scope: bucket + ":" + key
7
  }
8
  const putPolicy = new qiniu.rs.PutPolicy(options)
9
  // 生成上传凭证
10
  const uploadToken = putPolicy.uploadToken(mac)
11
  // 上传文件
12
  formUploader.putFile(uploadToken, key, localFile, putExtra, function(respErr,
13
    respBody, respInfo) {
14
    if (respErr) throw respErr
15
    console.log('已上传: ', respBody.key)
16
  })
17
}

定义上传文件夹的方法:

1
// 目录上传方法
2
function uploadDirectory (dirPath) {
3
  fs.readdir(dirPath, function (err, files) {
4
    if (err) throw err
5
    // 遍历目录下的内容
6
    files.forEach(item => {
7
      let path = `${dirPath}/${item}`
8
      fs.stat(path, function (err, stats) {
9
        if (err) throw err
10
        // 是目录就接着遍历 否则上传
11
        if (stats.isDirectory()) uploadDirectory(path)
12
        else uploadFile(path, item) 
13
      })
14
    })
15
  })
16
}

在脚本的最后,执行 uploadDirectory 方法开始上传:

1
fs.exists(staticPath, function (exists) {
2
  if (!exists) {
3
    console.log('目录不存在!')
4
  }
5
  else {
6
    console.log('开始上传...')
7
    uploadDirectory(staticPath)
8
  }
9
})

运行脚本:

1
node build/deploy.js

相关环境:macOS 10.13 / Node.js 8.9 / npm 5.6