【Docker対応】scratch-guiとscratch-vmをインストールして独自の拡張機能を作成する開発環境を整える


※ 当ページには【広告/PR】を含む場合があります。
2020/08/18
2022/03/08

今回は
弊社のプログラミング教育事業の一環として利用しているScratch3.0のエクステンションを自作するDockerでの環境づくりに関して解説します。

(※2022/3月更新)GUIのデスクトップScratchアプリ開発環境であった
「scratch-gui」とそのコアライブラリエンジンであった「scratch-vm」は長らく分離されたプロジェクトでした。

そのため、別々にプロジェクトをダウンロード、ローカルビルド、ビルド後はscratch-vmの出力物をscratch-guiにパッケージリンクさせるという手間が掛かりました。

最近のscratch-guiではようやくscratch-vmの機能が統合され、ローカルでのパッケージリンクが不要となりました。

ということで、この主要なscratch-guiのアップデートを受けて、このブログもそれに合わせて修正しています。


合同会社タコスキングダム|蛸壺の技術ブログ【効果的学習法】Dockerをこれから学びたい人のためのオススメ書籍&教材特集

scratch-gui/vmの開発用Dockerコンテナの準備

まずはScratch3.0をビルドするためのベースとなるDockerイメージを構築していきます。

なお、本記事の内容では
dockerおよびdocker-composeを手元のPC上で利用できることを前提としております。

これらのインストール方法・使い方などは解説しませんので、他のサイトなどで検索ください。

参考で手元のDebianOSでのインストール状況は、

            
            $ docker --version
Docker version 19.03.8, build afacb8b7f0
$ docker-compose --version
docker-compose version 1.16.1, build 6d1ac21
        
です。

Dockerfileとdocker-compose.yml

早速Scratch3.0開発用のDockerイメージをビルドしていきましょう。

首題の通りで軽量な開発環境が好ましいので
alpineベースで利用します。

ほぼ
公式の'node'イメージで動作しますのでどれを引っ張ってきても動作するはずです。

Node.jsのバージョンはversion12以降のもので良いでしょう。

Dockerfile

今回は至ってシンプルなdockerfileファイルです。

ポイントとしては
webpackをグローバルにnpmインストールして利用する使い方をします。

これはScratch3.0がwebpackでパッケージビルドされるためです。

            
            FROM node:12.22-alpine3.11

WORKDIR /usr/src/app

ENV NODE_ENV=development

RUN apk update && apk upgrade && apk add --no-cache \
    bash git openssh python2 curl

RUN npm i -g webpack webpack-cli webpack-dev-server
        

docker-compose.yml

続いてdocker-compose.ymlです。

生のDockerコマンドをオプション付で叩いてもいいのですが、プロジェクト毎に毎回長いコマンドオプションが覚えてられないので
docker-composeは大変重宝します。

            
            version: '3'

services:
  app:
    image: scratch3:12.22-alpine3.11
    build: .
    user: "node:node"
    environment:
      NODE_ENV: development
    ports:
      - 8073:8073
      - 8601:8601
    volumes:
        - ./:/usr/src/app
    tty: true
        
なお、docker-composeでのサービス名はappとしています。

また、イメージのタグ名
12.16-alpine3.11はnode-alpineのベースイメージのタグと合わせておくと、後々アップグレードする際にわかりやすくなると思います。

Dockerイメージのビルド・起動・停止

初回はこのイメージをビルドする必要があります。

Dockerfileとdocker-compose.ymlのあるルートディレクトリにおいて以下のコマンド、

            
            $ docker-compose build
Building app
Step 1/5 : FROM node:12.22-alpine3.11
 ---> 927d03058714
Step 2/5 : WORKDIR /usr/src/app
 ---> Using cache
 ---> 135d504707ce
#中略
+ webpack-cli@3.3.12
+ webpack-dev-server@3.11.0
+ webpack@4.44.1
added 919 packages from 358 contributors in 71.123s
Removing intermediate container 279a1bd8a793
 ---> 5fa04a01f765
Successfully built 5fa04a01f765
Successfully tagged scratch3:12.22-alpine3.11
        
のようにやることでイメージビルドができます。

完成したイメージは以下で確認できます。

            
            $ docker images
REPOSITORY                       TAG                   IMAGE ID            CREATED             SIZE
tcnct/scratch3                   12.22-alpine3.11      5fa04a01f765        22 minutes ago      216MB
node                             12.22-alpine3.11      927d03058714        6 months ago        88.1MB
#以下略
        
webpack系のパッケージで容量が多少モリモリになっています。

この程度なら許容範囲内かと思います。

このイメージからコンテナ起動して、インタラクティブモードで入って、コンテナ停止、を以下で行ってみましょう。

            
            #👇コンテナを起動
$ docker-compose up -d
Creating network "scracth3dckr_default" with the default driver
Creating scracth3dckr_app_1 ...
Creating scracth3dckr_app_1 ... done
#👇appサービスにインタラクティブモードにbashから入る
$ docker-compose exec app bash
#👇コンテナ内で色々と作業
bash-5.0$ whoami
node
bash-5.0$ node --version
v12.16.1
bash-5.0$ npm --version
6.13.4
bash-5.0$ yarn --version
1.22.0
#👇作業が終わったらコンテナから抜ける
bash-5.0$ exit
exit
#👇コンテナを停止・破棄
$ docker-compose down
Stopping scracth3dckr_app_1 ... done
Removing scracth3dckr_app_1 ... done
Removing network scracth3dckr_default
        
基本的にはDockerコンテナ内に入ってのアプリ開発作業はこのような流れになると思います。

以上がnodejsおよびnpmパッケージを利用できるalpine-dockerコンテナの構築のお話です。

ただこれだけどまだ全然Scratch3.0自体がビルドできません。

以降の後半ではこのコンテナ内でScratch3.0のエクステンションを追加するためにライブラリ群を整備してみる内容を説明していきます。


合同会社タコスキングダム|蛸壺の技術ブログ【効果的学習法】Dockerをこれから学びたい人のためのオススメ書籍&教材特集

scratch-guiのソースビルド&インストール

冒頭でも説明しましたが、長らく別々で開発環境として手動で紐付けしなければならなかったscratch-guiscratch-vmは、現在完全に独立したプロジェクトになりました。

まず先にscratch-guiの導入手順から説明しましょう。

Githubレポジトリ公式で述べられている手順を参考にscratch-guiのビルドを行っていきます。

scratch-guiのインストール

まずはscratch-gui(メインアプリにあたるグラフィカルユーザーインターフェース)をプロジェクトごとクローンしましょう。

            
            $ git clone --depth 1 https://github.com/llk/scratch-gui.git
Cloning into 'scratch-gui'...
remote: Enumerating objects: 1001, done.
remote: Counting objects: 100% (1001/1001), done.
remote: Compressing objects: 100% (966/966), done.
remote: Total 1001 (delta 61), reused 682 (delta 20), pack-reused 0
Receiving objects: 100% (1001/1001), 15.35 MiB | 99.00 KiB/s, done.
Resolving deltas: 100% (61/61), done.
        
で、プロジェクトをローカルにクローンすることができます。

プロジェクトをダウンロードした段階でルートディレクトリからのファイル構造は、

            
            $ tree -L 2
.
├── Dockerfile
├── docker-compose.yml
├── package.json
└── scratch-gui
    ├── LICENSE
    ├── README.md
    ├── TRADEMARK
    ├── docs
    ├── package-lock.json
    ├── package.json
    ├── prune-gh-pages.sh
    ├── renovate.json5
    ├── src
    ├── test
    ├── static
    └── webpack.config.js
        
のようになっていると思います。

scratch-guiの起動する

続いて
scratch-guiフォルダに移り、scratch-guiの中から作業します。

ここでもパッケージインストールします。

            
            $ cd scratch-gui
$ yarn install
yarn install v1.22.0
info No lockfile found.
warning package-lock.json found. Your project contains lock files generated by tools other than Yarn. It is advised not to mix package managers in order to avoid resolution inconsistencies caused by unsynchronized lock files. To clear this warning, remove package-lock.json.
[1/4] Resolving packages...
warning @babel/cli > chokidar@2.1.8: Chokidar 2 will break on node v14+. Upgrade to chokidar 3 with 15x less dependencies.
#...中略
[4/4] Building fresh packages...
success Saved lockfile.
Done in 89.77s.
        
では、このフォルダにとどまってscratch-guiを試しに起動させます。

            
            $ yarn start
webpack-dev-server
10% building 6/6 modules 0 activeℹ 「wds」: Project is running at http://0.0.0.0:8601/
ℹ 「wds」: webpack output is served from /
ℹ 「wds」: Content not from webpack is served from /usr/src/app/scratch-gui/build
65% building 581/631 modules 50 active ...sion-worker.js!/usr/src/app/scratch-gui/node_modules/babel-loader/lib/index.js??ref--4!/usr/src/app/scratch-gui/node_modules/scratch-vm/src/extension-support/extension-worker.js(node:189) DeprecationWarning: Tapable.apply is deprecated. Call apply on the plugin directly instead
ℹ 「wdm」: Hash: 969023fad960bd8371c2
Version: webpack 4.44.1
#中略
        [./node_modules/scratch-vm/src/util/log.js] 84 bytes {main} [built]
        [./node_modules/webpack/buildin/global.js] (webpack)/buildin/global.js 472 bytes {main} [built]
            + 5 hidden modules
ℹ 「wdm」: Compiled successfully.
        
これでwebpackのパッケージビルド後に、webpack-dev-serverでlocalhost側へSPAが送りだされます。

http://0.0.0.0:8601/にブラウザでアクセスすると、

合同会社タコスキングダム|蛸壺の技術ブログ

でscratch-gui(Scratch3.0)が起動出来ていれば完了です。


合同会社タコスキングダム|蛸壺の技術ブログ【効果的学習法】Dockerをこれから学びたい人のためのオススメ書籍&教材特集

scratch-vmのソースビルド&インストール

冒頭でも説明しましたが、長らく別々で開発環境として手動で紐付けしなければならなかったscratch-guiscratch-vmは、現在完全に独立したプロジェクトになりました。

scratch-guiはスクラッチアプリを作る総合開発環境ですので、スクラッチアプリの完成物だけをコンパクトに開発したい場合にはscratch-vmのお世話になります。

こちらではscratch-vmの導入手順から説明しましょう。

Githubレポジトリ公式で述べられている手順を参考にscratch-vmのビルドを行っていきます。

scratch-vmのインストール

scratch-vm(必須のライブラリ)もプロジェクトごとクローンすることが可能です。

            
            $ git clone --depth 1 https://github.com/llk/scratch-vm.git
Cloning into 'scratch-vm'...
remote: Enumerating objects: 488, done.
remote: Counting objects: 100% (488/488), done.
remote: Compressing objects: 100% (367/367), done.
remote: Total 488 (delta 119), reused 313 (delta 100), pack-reused 0
Receiving objects: 100% (488/488), 7.92 MiB | 125.00 KiB/s, done.
Resolving deltas: 100% (119/119), done.
        
で、プロジェクトをローカルにクローンすることができます。

ひとまず2つのプロジェクトをダウンロードした段階でルートディレクトリからのファイル構造は、

            
            $ tree -L 2
.
├── Dockerfile
├── docker-compose.yml
├── package.json
└── scratch-vm
    ├── LICENSE
    ├── README.md
    ├── TRADEMARK
    ├── docs
    ├── package-lock.json
    ├── package.json
    ├── src
    ├── test
    └── webpack.config.js
        
のようになっていると思います。

なおscratch-vmの中身を弄る必要がなければ、npmパッケージをそのまま利用する方が楽でしょう。

            
            $ yarn add scratch-vm -S
        

scratch-vmアプリのビルド&起動

まずは
scratch-vmフォルダに移って、パッケージをインストールします。

            
            $ cd scratch-vm
$ yarn install
yarn install v1.22.0
info No lockfile found.
warning package-lock.json found. Your project contains lock files generated by tools other than Yarn. It is advised not to mix package managers in order to avoid resolution inconsistencies caused by unsynchronized lock files. To clear this warning, remove package-lock.json.
[1/4] Resolving packages...
warning nets > request@2.88.2: request has been deprecated, see https://github.com/request/request/issues/3142
#...中略
[3/4] Linking dependencies...
[4/4] Building fresh packages...
success Saved lockfile.
Done in 87.16s.
        
scratch-vmを使ったスクラッチアプリ開発は基本的にJavascriptになります。

例えば、scratch-gui内のvmの利用方法などが使い方の参考になるでしょう。

            
            //...中略
import VM from 'scratch-vm';

//...中略

const vmManagerHOC = function (WrappedComponent) {
    class VMManager extends React.Component {
        constructor (props) {
            super(props);
            bindAll(this, [
                'loadProject'
            ]);
        }
        //...中略
        render () {
            const {
                /* eslint-disable no-unused-vars */
                fontsLoaded,
                loadingState,
                locale,
                messages,
                isStarted,
                onError: onErrorProp,
                onLoadedProject: onLoadedProjectProp,
                onSetProjectUnchanged,
                projectData,
                /* eslint-enable no-unused-vars */
                isLoadingWithId: isLoadingWithIdProp,
                vm,
                ...componentProps
            } = this.props;
            return (
                <WrappedComponent
                    isLoading={isLoadingWithIdProp}
                    vm={vm}
                    {...componentProps}
                />
            );
        }
    }

    VMManager.propTypes = {
        //...中略
        //👇vmがscratch-vmのインスタンスとなる
        vm: PropTypes.instanceOf(VM).isRequired
    };

    //...中略

    return connect(
        mapStateToProps,
        mapDispatchToProps,
        mergeProps
    )(VMManager);
};

export default vmManagerHOC;
        
見ての通り、スクラッチアプリの本体というべきvmインスタンスがscratch-guiでも随所に見て取ることができます。

scratch-vmに関しては技術的なドキュメントは少なく、主にソースコードを読み込んで理解していくしかありません。

ローカルインストールが正常完了したら、カスタマイズしたscratch-vmを他のプロジェクトでも利用できるように、以下のコマンドでライブラリリンクを作成することもできます。

            
            $ cd scratch-vm
$ yarn link
yarn link v1.22.0
success Registered "scratch-vm".
info You can now run `yarn link "scratch-vm"` in the projects where you want to use this package and it will be used instead.
Done in 0.06s.
        
これをscratch関連の任意のプロジェクトに紐付けする場合、

            
            $ cd my-scratch-project
$ yarn link scratch-vm
        
とすることも可能です。


合同会社タコスキングダム|蛸壺の技術ブログ【効果的学習法】Dockerをこれから学びたい人のためのオススメ書籍&教材特集

まとめ

scratch3.0はオンライン版のSPAアプリで利用するのが主流になっています。

今回のようにオフラインでも利用できるようにする方法は、やり方のハードルも高く倦厭されがちかも知れません。

ただし、自作のエクステンションが作成できたり、nodeパッケージが利用できたりと、scratchのプログラミングにかなりの自由度が広がる点で大いにメリットがあると思います。

参考のサイト

Scratch Japan Wliki | Scratch 3.0の拡張機能を作ってみよう

Qiita | Scratch 3.0でオリジナルブロックをつくろう

Scratch 3.0 の Extension(拡張機能) を試してみた