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

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

安装七牛云 Node.js SDK:

npm install qiniu --save

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

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

声明常量:

// 授权秘钥
const accessKey = '{你的七牛云 AccessKey}'
const secretKey = '{你的七牛云 SecretKey}'

// 存储空间名称
const bucket = '{你的 Bucket 名称}'

// 要上传的资源目录
const staticPath = 'dist/static'

// 上传后的文件前缀
const prefix = 'static'

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

// 创建鉴权对象
const mac = new qiniu.auth.digest.Mac(accessKey, secretKey)

// 创建并修改配置对象(Zone_z0=华东 Zone_z1=华北 Zone_z2=华南 Zone_na0=北美)
const config = new qiniu.conf.Config()
config.zone = qiniu.zone.Zone_z2

// 创建额外内容对象
const putExtra = new qiniu.form_up.PutExtra()

// 创建表单上传对象
const formUploader = new qiniu.form_up.FormUploader(config)

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

// 文件上传方法
function uploadFile (localFile) {
  // 配置上传到七牛云的完整路径
  const key = localFile.replace(staticPath, prefix)
  const options = {
    scope: bucket + ":" + key
  }
  const putPolicy = new qiniu.rs.PutPolicy(options)
  // 生成上传凭证
  const uploadToken = putPolicy.uploadToken(mac)
  // 上传文件
  formUploader.putFile(uploadToken, key, localFile, putExtra, function(respErr,
    respBody, respInfo) {
    if (respErr) throw respErr
    console.log('已上传: ', respBody.key)
  })
}

定义上传文件夹的方法:

// 目录上传方法
function uploadDirectory (dirPath) {
  fs.readdir(dirPath, function (err, files) {
    if (err) throw err
    // 遍历目录下的内容
    files.forEach(item => {
      let path = `${dirPath}/${item}`
      fs.stat(path, function (err, stats) {
        if (err) throw err
        // 是目录就接着遍历 否则上传
        if (stats.isDirectory()) uploadDirectory(path)
        else uploadFile(path, item) 
      })
    })
  })
}

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

fs.exists(staticPath, function (exists) {
  if (!exists) {
    console.log('目录不存在!')
  }
  else {
    console.log('开始上传...')
    uploadDirectory(staticPath)
  }
})

运行脚本:

node build/deploy.js

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