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

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

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

安装七牛云 Node.js SDK:

1
npm install qiniu --save

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

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

声明常量:

1
2
3
4
5
6
7
8
9
10
11
12
// 授权秘钥
const accessKey = '{你的七牛云 AccessKey}'
const secretKey = '{你的七牛云 SecretKey}'

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

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

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

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

1
2
3
4
5
6
7
8
9
10
11
12
// 创建鉴权对象
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)

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// 文件上传方法
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)
})
}

定义上传文件夹的方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// 目录上传方法
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 方法开始上传:

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

运行脚本:

1
node build/deploy.js

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