Scratch-guiのデフォルトプロジェクトのアセット置き場を変える方法
※ 当ページには【広告/PR】を含む場合があります。
2020/11/01
以前、
実際にはまだ画像ファイルなどのアセットファイルの置き場所に少し課題がありました。
今回はさらに突っ込んで、このアセットファイルの置き場所を変更するための手順を深堀してみようと思います。
はじめに
以前、Scratch3.0の開発者向けのソースコードプロジェクト
課題としてデフォルトプロジェクトを置き換えただけでは、画像データや音源はscratchの共有アセット置き場(
https://assets.scratch.mit.edu/internalapi/asset

これはscratch3では原則として
scratch.mit.edu
簡単に言ってしまうと、Scratchの公式サイトにアップロードされたファイルは全て問答無用でみんなの財産として扱われます。
この辺がScratchアプリ開発の悩ましい問題で、最近の更新された
ライセンス付きの有料の画材を購入した人がそれを使ってScratch3のアプリを公式サイトから公開してしまった場合、
大抵の場合には、購入した画材の利用規約に従えばよいのですが、中にはクリエイティブ・コモンズなどの面倒なライセンスが付いているものもあります。
Scratch3は三条項BSDライセンス(BSD-3-clause)に基づいているため、開発中のプロジェクト内に色々なライセンスのファイルが存在してくると、そのライセンス同士の衝突する・しないなどアプリ開発とは関係の薄いところに気を配っていかなくてはなりません。
せめて画像置き場は自分専用のストレージにおけると、ライセンスの無用な衝突の問題を分けて考えることができるので、少し気が楽になりそうです。
そんなニーズに応えるためなのか分かりません。
scratch-guiには救済措置としてデフォルトのアセット置き場のURLを変更はできるようになっています。
今回はプライベートのAWS S3のバケット内にプロジェクトのアセットを置いて、そこからScratch3アプリが正常に起動することを検証します。
AWS S3でアセット用のバケットを作成
※この記事ではAWSでのクラウドストレージを利用した方法を紹介します。
他のクラウドストレージやCDNからでも
https://...
AWSを利用するのでなければこの節はスキップして、次に節からお読みください。
まずはAWS S3のコンソールから空のバケットを作成します。
このバケットにとりあえず
project
プロジェクトのファイル(
.sb3
project

外部からアクセスできるようにするためバケットポリシーの追加とCORS設定を行います。

バケットから
[アクセス許可]
[バケットポリシー]
[Cross-Origin Resource Sharing(CORS)]
今回は特定のサイトからのみアクセスはせずに、どこのオリジンからでもGETのみ許可するようにしております。
GETのみを許可する時点でこのプロジェクトは
読み込み専用
アプリの開発も自分専用のクラウドストレージ無いで行いたいときにはここから更に
POST
細かくアクセスコントロールしたい場合には各自の用途に応じた設定に修正してください。
バケットポリシー:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "Accsess Policy 1",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::<バケット名>/*"
}
]
}
CROS設定:
[
{
"AllowedHeaders": [
"*"
],
"AllowedMethods": [
"GET"
],
"AllowedOrigins": [
"*"
],
"ExposeHeaders": [],
"MaxAgeSeconds": 3000
}
]
特にここでは設定していませんが、
AllowedOrigins
さて、この時点でこのバケットからアクセスが可能かcurlで適当なファイルを取得して試してみます。
$ curl https://s3-ap-northeast-1.amazonaws.com/バケット名/project/8c84d0a54dc6d808c08b06f4f3880e62.svg
<svg version="1.1" width="7.579999923706055" height="11.640000343322754" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="3.4549999237060547 1.0399999618530273 7.579999923706055 11.640000343322754">
#...中略
</g>
</svg>
レスポンスが返ってきているようなので、AWS S3からファイルが供給できている状態になりました。
scratch-guiの修正
デフォルトではプロジェクトのプロジェクトファイル・アセットファイルが以下のように配置されている仕様です。
project.json:
https://projects.scratch.mit.edu/[project_id値]
assets:
https://assets.scratch.mit.edu/internalapi/asset/[resource_id.(png|svg|wav)]/get/
これを先程の設定したような任意のクラウドストレージを参照するようにしていきます。
project-fetcher-hoc.jsx
まずはリソースファイルのホスト先の情報が格納されている
project-fetcher-hoc.jsx
scratch-gui/src/lib/project-fetcher-hoc.jsx
このコードの中身に以下の部分を探します。
//...中略
ProjectFetcherComponent.defaultProps = {
assetHost: 'https://assets.scratch.mit.edu',
projectHost: 'https://projects.scratch.mit.edu'
};
//...以下略
この設定がデフォルトのアセット置き場のURLの設定になります。
先程のAWS S3バケットに仕込みなおすと、
//...中略
ProjectFetcherComponent.defaultProps = {
// assetHost: 'https://assets.scratch.mit.edu',
// projectHost: 'https://projects.scratch.mit.edu'
assetHost: 'https://s3-ap-northeast-1.amazonaws.com/<バケットの名前>/project',
projectHost: 'https://s3-ap-northeast-1.amazonaws.com/<バケットの名前>/project'
};
//...以下略
でデフォルトのリソースファイル置き場が変更できました。
storage.js
もう一つ修正すべきなのが、
storage.js
scratch-gui/src/lib/storage.js
デフォルトでは、
//...中略
setProjectHost (projectHost) {
this.projectHost = projectHost;
}
getProjectGetConfig (projectAsset) {
return `${this.projectHost}/${projectAsset.assetId}`;
}
getProjectCreateConfig () {
return {
url: `${this.projectHost}/`,
withCredentials: true
};
}
getProjectUpdateConfig (projectAsset) {
return {
url: `${this.projectHost}/${projectAsset.assetId}`,
withCredentials: true
};
}
setAssetHost (assetHost) {
this.assetHost = assetHost;
}
getAssetGetConfig (asset) {
return `${this.assetHost}/internalapi/asset/${asset.assetId}.${asset.dataFormat}/get/`;
}
getAssetCreateConfig (asset) {
return {
// There is no such thing as updating assets, but storage assumes it
// should update if there is an assetId, and the asset store uses the
// assetId as part of the create URI. So, force the method to POST.
// Then when storage finds this config to use for the "update", still POSTs
method: 'post',
url: `${this.assetHost}/${asset.assetId}.${asset.dataFormat}`,
withCredentials: true
};
}
//...以下略
という部分が、そのままでは
getAssetGetConfig
そこで
AWS S3
//...中略
getAssetGetConfig (asset) {
// return `${this.assetHost}/internalapi/asset/${asset.assetId}.${asset.dataFormat}/get/`;
return `${this.assetHost}/${asset.assetId}.${asset.dataFormat}`;
}
//...以下略
ここらへんはアセット置き場として利用したいクラウドストレージのアクセス方法によって異なるエンドポイントになるかも知れません。
その際は
storage.js
これでScratch-guiをビルドして、デフォルトのプロジェクトを読み込んだ際に、指定したクラウドストレージからリソースが読み込まれていたら設定完了です。

まとめ
今回はスクラッチプロジェクトのアセットファイルの置き場所をカスタマイズする方法を解説しました。
特に今回のテクニックでは、スクラッチアプリは公開したいけれど、そこで利用している一部のライセンス付きの画像のアクセスは制限したい場合に役立つと思います。