LoginSignup
2
0

More than 3 years have passed since last update.

node.jsからAmazonS3へファイルアップロード

Last updated at Posted at 2019-11-08

確認した環境

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`ファイルが存在する前提

})();

2
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0