3
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Cesium.js環境構築(Tauri + Reactの場合)

Last updated at Posted at 2025-10-20

はじめに

Tauriはクロスプラットフォーム対応のデスクトップ、モバイルアプリケーション開発フレームワークです。本記事ではTauriでCesium.jsを使ってデスクトップアプリケーションにCesium Globeを表示する方法について説明します。

Tauriのアプリケーション開発ではNode.jsが必要になります。また、TauriはバックエンドにRustを使用するためRustのインストールも必要になります。ただ、Cesiumの表示を行うだけであればRustのコードを記述する必要はありません。

プロジェクト作成

今回の例ではUIテンプレートにReactを使うものとします。

> npm create tauri-app@latest

コマンドを入力すると質問に答える形でプロジェクトの基本設定を行います。本記事では以下のようにしました。

  • Project name : cesium-tauri
  • Language : Typescript / Javascript
  • Package manager : npm
  • UI template : React
  • UI flavor : Typescript

プロジェクトを作成するとプロジェクト名のディレクトリが作成されるので、ディレクトリへ移動してnpm installを一発入れてからnpm run tauri devとコマンドを入力してみます。問題がなければ初期状態のプログラムが実行されるはずです。

image.png

Cesiumの表示

TauriのプロジェクトではビルドツールとしてViteを使用します。

Cesiumのアセットをコピー

node_modules/cesium/Build/Cesium以下にあるCesiumアセットをpublic/cesium/に全てコピーします。

vite-plugin-cesiumを使うべきところかもしれませんが、筆者の環境では正しく動作しませんでした。

vite.config.ts

まずはプロジェクトディレクトリのトップにあるvite.config.tsを以下のように記述します。

import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";

export default defineConfig({
  plugins: [react()],
  server: {
    port: 1420,
    strictPort: true,
    watch: {
      ignored: ["**/src-tauri/**"],
    },
  },
  build: {
    // 最新のJavaScript構文で出力
    target: "esnext",
    // Cesium.jsをコード分割によって初期ロードを最適化
    rollupOptions: {
      output: {
        manualChunks: {
          cesium: ["cesium"],
        },
      },
    },
  },
  optimizeDeps: {
    // 大きなライブラリの初回読み込みを高速化
    include: ["cesium"],
    // 依存関係の事前バンドル時もesnextターゲットを使用
    esbuildOptions: {
      target: "esnext",
    },
  },
});

src-tauri/tauri.conf.json

{
  "$schema": "https://schema.tauri.app/config/2",
  "productName": "cesium-tauri",
  "version": "0.1.0",
  "identifier": "com.yamate.cesium-tauri",
  "build": {
    "beforeDevCommand": "npm run dev",
    "devUrl": "http://localhost:1420",
    "beforeBuildCommand": "npm run build",
    "frontendDist": "../dist"
  },
  "app": {
    "windows": [
      {
        "title": "cesium-tauri",
        "width": 800,
        "height": 600
      }
    ],
    "security": {
      "csp": null,
      // CSPの設定をとりあえずは緩和
      "dangerousDisableAssetCspModification": true
    },
    // 開発中はtrueでいいのか?
    "withGlobalTauri": true
  },
  "bundle": {
    "active": true,
    "targets": "all",
    "icon": [
      "icons/32x32.png",
      "icons/128x128.png",
      "icons/128x128@2x.png",
      "icons/icon.icns",
      "icons/icon.ico"
    ]
  }
}

この辺の設定は改良の余地があるかもしれません。

src/App.tsx

Cesiumを表示する部分になります。

import { useEffect, useRef } from "react";
import * as Cesium from "cesium";
import "cesium/Build/Cesium/Widgets/widgets.css";
import "./App.css";

// Cesiumのベースパスを設定(重要!)
(window as any).CESIUM_BASE_URL = "/cesium/";

// Cesium Ion アクセストークン(自分のトークンに置き換えてください)
// https://ion.cesium.com/tokens で取得できます
Cesium.Ion.defaultAccessToken = "your-access-token"; // アクセストークンは必須

function App() {
  const cesiumContainer = useRef<HTMLDivElement>(null);
  const viewerRef = useRef<Cesium.Viewer | null>(null);

  useEffect(() => {
    if (!cesiumContainer.current) return;

    const initViewer = async () => {
      // Cesium Viewerの初期化
      viewerRef.current = new Cesium.Viewer(cesiumContainer.current as HTMLDivElement, {
        geocoder: false,
        homeButton: true,
        sceneModePicker: true,
        fullscreenButton: false,
      });

      // 地形データを追加(せっかくなのでJapan Regional Terrain)
      try {
        viewerRef.current.terrainProvider = await Cesium.CesiumTerrainProvider.fromIonAssetId(2767062, {
          requestWaterMask: true, // 水面マスク
          requestVertexNormals: true, // 頂点法線を要求
        });
      } catch (error) {
        console.error("Terrain loading error.", error);
      }
    }

    initViewer();

    // クリーンアップ
    return () => {
      if (viewerRef.current) {
        viewerRef.current.destroy();
        viewerRef.current = null;
      }
    };
  }, []);

  return (
    <div className="app-container">
      <div ref={cesiumContainer} className="cesium-container" />
    </div>
  );
}

export default App;

CesiumのコードはinitViewer()の中に記述するとよいでしょう。

src/App.css

@media (prefers-color-scheme: dark) {
  :root {
    /* ウィンドウのマージンの部分をダークモード */
    background-color: #2f2f2f;
  }
}

/* 
ウィンドウのマージンの関係で、コンテナを少し小さくする
100にするとスクロールバーがでてしまう。
(どこかにウィンドウのマージンを0にするところがあるのかも?)
*/
.app-container {
  width: 97vw;
  height: 97vh;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}

.cesium-container {
  flex: 1;
  width: 100%;
  height: 100%;
}

以上が最低限のコードになります。

実行とビルド

ココまでで実行してみます。以下のように表示されれば成功です。

image.png

ビルドを行うには以下のコマンドを実行します。

> npm run tauri build

実行すると、src-tauri/target/release以下に実行ファイルが作成されています。
また、src-tauri/target/release/bundle/以下にmsinsisというフォルダがあり、それぞれに.msiと.exeのインストーラが作成されます。

あくまで筆者の体感ですが、起動はかなり早い気がします。

3
2
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
3
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?