Uppy 使ってみた
今のプロジェクトでは Nuxt.js を用いて開発を行っているため、Nuxt 絡みでGWになにか作りたいなと思っていました。
そこで、見つけた Uppy ( https://uppy.io/ ).
このブログで使っている画像を毎度 CyberDuck でアップロードして、URLをコピペして。。みたいなことをしていて、若干のツラミがあったため、今回は Uppy を使って S3 へ画像をアップロードするツールを作ってみました。
その過程で、いくつかUppy 特有の使い勝手みたいなところがあったので、本記事でご紹介します。
大まかなしくみ
この Uppy はフロントエンド側で Uppy のライブラリを用いて UIを作っていく部分と、Companion と呼ばれる画像を実際にアップロードするバックエンド処理に分かれています。
今現在の Uppy 使ってみた系の記事では、フロントエンド側の実装が語られる一方で、バックエンド側は XHRをベースにした画像アップロードをしているものしか見かけず、実際にS3に画像をアップロードしようとすると、少し苦しむ部分があるかもしれません。
今回は、S3に実際にアップロードできるところまで、本記事で紹介していきます。
クライアント(Nuxt)側について
Nuxtのプロジェクトは用意できている前提で進めてしまいますが、まず以下のパッケージを追加します。
$ yarn add @uppy/core @uppy/dashboard @uppy/aws-s3
その上で、ざっくりと vue ファイルを作っていきます。 テンプレート部分はこんな感じ。特に変わったことはしていないです。
<template>
<section class="section">
<div class="columns is-mobile">
<b-button id="select-files">Upload new image</b-button>
</div>
</section>
</template>
そして、js 部分は以下。
import Uppy from '@uppy/core'
import Dashboard from '@uppy/dashboard'
import AwsS3 from '@uppy/aws-s3'
export default {
data() {
return {
uppyId: 'uppy-trigger'
}
},
mounted() {
const uppy = Uppy({
allowMultipleUploads: true,
restrictions: {
allowedFileTypes: ['image/*']
}
})
.use(Dashboard, {
trigger: '#select-files'
})
.use(AwsS3, {
companionUrl: process.env.COMPANION_URL
})
}
}
フロント側はこれだけで S3 にアップロードする準備ができてしまいます。 超簡単でビビります。
バックエンド(Uppy/Companion)について
フロント側のコードを用意していて、少し謎なのが companionUrl
なのですが Uppy では Companion について、以下のようなドキュメントがあります。
https://uppy.io/docs/companion/
めちゃくちゃざっくり意訳をすると、ユーザーが様々なリソース(Instagram, Dropbox…) からファイルを選択し、それをさらなるリソース(Dropbox, S3, OneDrive…) にバイパスさせるための仕組みのようです。
これがなぜ必要になってくるかというと、上記フロント側のコードを見てもわかるように S3 に画像をアップロードするにあたり、クレデンシャル情報は一切書きませんし、フロント側で出力するわけにも行きません。
そこで、このコンパニオンにクレデンシャル情報をもたせ、リソースのアップロードをバイパスさせることで、様々なリソースへのアップロードを可能にするようです。
ということで、このコンパニオンを用意していきます。
heroku にコンパニオンを用意する
https://github.com/transloadit/uppy/tree/master/packages/%40uppy/companion#deploy-to-heroku
とても丁寧にメンテされているドキュメントがありますので、こちらを参考にしてください。
まずは README に書かれているる通り、heroku にアプリケーションをデプロイします。
別段 heroku でなくとも node.js が動く軽量なサーバーをすぐに用意できそうであれば、そちらでもいいかもです。
その後、このアプリケーションに対し、クレデンシャル情報をセットしていきます。
クレデンシャルをセットしていく
https://uppy.io/docs/companion/#Configure-Standalone
こちらに設定可能なクレデンシャルのキーが書かれているので必要に応じて設定していきます。 今回、S3に画像をアップロードしていくにあたっては以下の情報で十分です。
- COMPANION_AWS_ACL
- COMPANION_AWS_BUCKET
- COMPANION_AWS_EXPIRES
- COMPANION_AWS_KEY
- COMPANION_AWS_REGION
- COMPANION_AWS_SECRET
- COMPANION_AWS_USE_ACCELERATE_ENDPOINT
- COMPANION_DATADIR
- 特に何もディレクトリを切ってないので
.
で設定
- 特に何もディレクトリを切ってないので
- COMPANION_DOMAIN
- heroku でデプロイしたドメインを設定
- COMPANION_SECRET
- ランダムな文字列を決め、セットしてあげればOK
ドキュメントにも一応各キーの説明が書かれてるんですが、文脈が不足しており、意味わからんwというものも多かったです。(解釈が違う。というときには教えて下さい 🙏
S3バケット に CORS の設定をする
あとは、フロント側のURLを CORSで許可するようにします。
<?xml version="1.0" encoding="UTF-8"?>
<CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
<CORSRule>
<AllowedOrigin>https://xxxxx.herokuapp.com</AllowedOrigin>
<AllowedMethod>GET</AllowedMethod>
<AllowedMethod>POST</AllowedMethod>
<MaxAgeSeconds>3000</MaxAgeSeconds>
<AllowedHeader>Authorization</AllowedHeader>
<AllowedHeader>x-amz-date</AllowedHeader>
<AllowedHeader>x-amz-content-sha256</AllowedHeader>
<AllowedHeader>content-type</AllowedHeader>
</CORSRule>
<CORSRule>
<AllowedOrigin>*</AllowedOrigin>
<AllowedMethod>GET</AllowedMethod>
<MaxAgeSeconds>3000</MaxAgeSeconds>
</CORSRule>
</CORSConfiguration>
こんな感じで指定してあげれば、フロント側からアップロードできるようになっているかと思います。
まとめ
Uppy を見つけたときは、めちゃくちゃお手軽そうに見えたのですが、いざ使ってみようとすると準備物が多く、なかなか手間取りましたw
特に Companion の考え方を理解するまでに時間がかかってしまった。。 一方でここまで組み込めれば、S3 だけじゃなく他のサービスへのアップロードも簡単に行えたり、アップロードの対象に WebCamera を加えたり、外部URLを加えたり。というのも簡単にできるようになるので、初期投資としてはありだったのかもしれません。
個人的には、画像をリサイズしたり、軽くしたりということもやっていきたいので、ちょいちょいいじっていきたいと思います。