2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

ローカル開発用にmemfsでOPFSを使用したファイルストレージを作ると便利

Last updated at Posted at 2023-07-29

OPFS(Origin Private File System)を使うとブラウザの中だけでストレージを利用でき、ローカルの開発環境でのみ実際に画像のアップロードをしたくないケースなどでいい感じに使える。

実装にはmemfsを使う。memfsにはcrudfsというOPFS(a.k.a File System Access API)のCRUDラッパーが実装されている。さらに、それをget/putだけに抽象化したcasfsというラッパーも用意されており、これを使うとファイルストレージ的にOPFSを扱うにあたっては非常に便利。

以下が実装例。

import { FsaCrud } from "memfs/lib/fsa-to-crud";
import { CrudCas } from "memfs/lib/crud-to-cas";
import { IFileSystemDirectoryHandle } from "memfs/lib/fsa/types";
import uuid4 from "uuid4";

class InBrowserImageStorage {
  async uploadImage(file: File): Promise<string> {
    const buffer = await file.arrayBuffer();
    const manager = await this.getOPFSManager();
    return await manager.put(Buffer.from(buffer));

  }

  async getImage(fileName: string): Promise<string> {
    const manager = await this.getOPFSManager();
    const file = await manager.get(fileName);
    const blob = new Blob([file]);
    return URL.createObjectURL(blob);
  }

  private async getOPFSManager() {
    // ここの型はいい感じにできないものか...
    const dir =
      (await navigator.storage.getDirectory()) as unknown as IFileSystemDirectoryHandle;
    const crud = new FsaCrud(dir);
    return new CrudCas(crud, {
      async hash(blob: Uint8Array): Promise<string> {
        return createHash("sha1").update(blob).digest("hex");
      },
    });
  }
}

あとはinterfaceで抽象化して、実際のアップロードを行う実装と NODE_ENV かなんかで切り替えればよさそう。

interface ImageStorage {
  uploadImage(file: File): Promise<string>;
  getImage(fileName: string): Promise<string>;
}

class InBrowserImageStorage implements ImageStorage {
  // ...
}

class RemoteImageStorage implements ImageStorage {
  // ...
}

export const imageStorage: ImageStorage =
  NODE_ENV === "production"
    ? new RemoteImageStorage()
    : new InBrowserImageStorage()
2
1
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
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?