確認した環境
node.js: 10.17.0
s3-client: 4.4.2
s3-clientのインストール
s3-clientをインストールします。
npm i s3-client
s3クライアントのインスタンスを作成
import s3 from "s3-client";
const client = s3.createClient({
s3Options: {
accessKeyId: ここにS3のアクセスキーID,
secretAccessKey: ここにs3のシークレットキー,
}
})
s3へアップロード
s3-clientのreadmeによるアップロードのサンプルは以下です。
var params = {
localFile: "some/local/file",
s3Params: {
Bucket: "s3 bucket name",
Key: "some/remote/file",
// other options supported by putObject, except Body and ContentLength.
// See: http://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/S3.html#putObject-property
},
};
var uploader = client.uploadFile(params);
uploader.on('error', function(err) {
console.error("unable to upload:", err.stack);
});
uploader.on('progress', function() {
console.log("progress", uploader.progressMd5Amount,
uploader.progressAmount, uploader.progressTotal);
});
uploader.on('end', function() {
console.log("done uploading");
});
サンプルのままだと使いづらいんで、Promiseオブジェクトでラップし、async/awaitが使えるようにします。
const uploadFileToS3 = (bucketName, remoteDir, localFilePath) => {
return new Promise(async (resolve, reject) => {
const fileName = localFilePath.split('/').pop()
const params = {
localFile: localFilePath,
s3Params: {
Bucket: bucketName,
Key: remoteDir + '/' + fileName // S3はオブジェクトストレージなのでフォルダの概念はないが、オブジェクトキーにスラッシュ区切りのパス名をつけることで、それをフォルダと解釈する
},
};
const uploader = await client.uploadFile(params);
uploader.on('error', (err) => {
reject(err.stack)
});
uploader.on('end', function () {
resolve()
});
});
}
これで、async/awaitを使えるようになりました。
(async () => {
await uploadFileToS3(s3のbacket名, s3のフォルダ名, ローカルのファイルパス)
})();
フォルダをまるごとアップロードしたい場合は、以下を使用します。
const uploadS3Dir = async (bucketName, localDir, remoteDir = null) => {
return new Promise(async (resolve, reject) => {
var params = {
localDir,
deleteRemoved: false, // default false, whether to remove s3 objects
// that have no corresponding local file.
s3Params: {
Bucket: bucketName,
Prefix: remoteDir,
// See: http://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/S3.html#putObject-property
},
};
var uploader = client.uploadDir(params);
uploader.on('error', err => {
reject(err.stack)
});
uploader.on('end', () => {
resolve()
});
});
}
s3のファイルリスト取得
S3バケット名を指定し、そこにある全てのファイルリストを再帰的に取得します。
const listS3Objects = async (bucketName, remoteDir = null) => {
return new Promise(async (resolve, reject) => {
var params = {
recursive: true, // これをfalseにすると1階層のみの取得となる
s3Params: {
Bucket: bucketName,
Prefix: remoteDir,
// See: https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/S3.html#listObjects-property
},
};
const finder = client.listObjects(params);
let objects = []
finder.on('data', function (data) {
objects = data
});
finder.on('error', err => {
reject(err.stack)
});
finder.on('end', () => {
resolve(objects)
});
});
}
s3にあるファイルの削除
S3バケット名と、オブジェクトキー文字列の配列を指定し、ファイルを削除します。
// objectKeys: [ remoteFile1, remoteFile2, ...]
const deleteS3Objects = async (bucketName, objectKeys) => {
return new Promise(async (resolve, reject) => {
var params = {
Bucket: bucketName,
Delete: {
Objects: objectKeys.map(k => ({ Key: k }))
}
};
const deleter = client.deleteObjects(params);
deleter.on('error', err => {
reject(err.stack)
});
deleter.on('end', () => {
resolve()
});
});
}
サンプル
S3のバケットをいったん空にしてファイルをアップロードするサンプルです。
// ここに上記の各関数を記述
(async () => {
const configs = {
acckey: S3のアクセスキーID,
seckey: S3のシークレットキー,
bucket: S3のバケット名,
}
const client = s3.createClient({
s3Options: {
accessKeyId: configs.acckey,
secretAccessKey: configs.seckey,
}
})
// 既存のobjectを削除
const list = await listS3Objects(configs.bucket)
const keys = list.Contents.map(i => i.Key)
//console.log(keys)
if (keys.length > 0) await deleteS3Objects(configs.bucket, keys)
await uploadFileToS3(configs.bucket, 'foo', './bar.txt') // このプログラムの実行フォルダ直下に、`bar.txt`ファイルが存在する前提
})();