本文 AI 產出,尚未審核

Three.js

單元:開發環境與基本設置

主題:安裝與模組載入(ESM / CDN)


簡介

在使用 Three.js 建立 3D 網頁應用時,第一步往往就是把程式庫正確地載入專案
無論是透過 npm 安裝後以 ES Module (ESM) 方式匯入,或是直接使用 CDN 提供的 script 標籤,兩者各有優缺點;選擇適合的載入方式能讓開發流程更順暢、除錯更容易,也能避免因版本不一致而產生的怪異錯誤。

本篇文章將從 環境安裝模組載入實作範例 三個層面說明,並針對常見的陷阱提供 最佳實踐,讓剛踏入 Three.js 世界的你能快速上手、穩定開發。


核心概念

1. 為什麼要使用 ES Module (ESM)?

ES Module 是 ECMAScript 官方規範的模組系統,具備靜態分析、Tree‑shaking(去除未使用程式碼)等特性。
在現代前端開發工具(如 Vite、Webpack、Rollup)中,使用 ESM 能讓程式碼更模組化、維護性更佳

1.1 ESM 的基本語法

// 匯入整個 Three.js 套件
import * as THREE from 'three';

// 只匯入需要的子模組,減少 bundle 大小
import { PerspectiveCamera, Scene, WebGLRenderer } from 'three';
  • import 必須放在檔案最上方,且只能在 type="module" 的腳本中使用。
  • 若要搭配 Three.js 官方的擴充套件(如 OrbitControls),同樣採用 ESM 路徑:
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js';

2. 使用 npm 安裝 Three.js

2.1 建立專案

# 建立資料夾並初始化 npm
mkdir my-threejs-demo
cd my-threejs-demo
npm init -y

2.2 安裝套件

npm install three
# 若需要額外的範例程式(examples)可安裝
npm install three@latest

Tip:安裝完後,node_modules/three 內即包含完整的 ESM 檔案與範例程式碼,直接引用即可。

2.3 建立開發伺服器(以 Vite 為例)

npm install vite --save-dev
# 在 package.json 加入啟動指令
# "scripts": { "dev": "vite" }

建立 index.htmlmain.js,然後執行 npm run dev,即可在瀏覽器看到即時重載的 Three.js 場景。


3. 直接使用 CDN(Content Delivery Network)

如果不想安裝 npm,或是要快速驗證想法,CDN 是最省事的方式
Three.js 官方提供 unpkgjsDelivr 等多個 CDN,且支援 ESM。

3.1 使用 <script type="module"> 載入

<!DOCTYPE html>
<html lang="zh-Hant">
<head>
  <meta charset="UTF-8">
  <title>Three.js CDN 範例</title>
  <style>body{margin:0;overflow:hidden;}</style>
</head>
<body>
  <script type="module">
    // 直接從 CDN 匯入 Three.js 主程式
    import * as THREE from 'https://cdn.jsdelivr.net/npm/three@0.162.0/build/three.module.js';
    // 匯入 OrbitControls(同樣是 ESM)
    import { OrbitControls } from 'https://cdn.jsdelivr.net/npm/three@0.162.0/examples/jsm/controls/OrbitControls.js';

    // 基本場景設定(同下方範例)
    const scene = new THREE.Scene();
    const camera = new THREE.PerspectiveCamera(75, innerWidth / innerHeight, 0.1, 1000);
    const renderer = new THREE.WebGLRenderer({ antialias: true });
    renderer.setSize(innerWidth, innerHeight);
    document.body.appendChild(renderer.domElement);

    const geometry = new THREE.BoxGeometry();
    const material = new THREE.MeshStandardMaterial({ color: 0x0077ff });
    const cube = new THREE.Mesh(geometry, material);
    scene.add(cube);

    const light = new THREE.DirectionalLight(0xffffff, 1);
    light.position.set(5, 10, 7);
    scene.add(light);

    const controls = new OrbitControls(camera, renderer.domElement);
    camera.position.set(2, 2, 5);
    controls.update();

    function animate() {
      requestAnimationFrame(animate);
      cube.rotation.x += 0.01;
      cube.rotation.y += 0.01;
      renderer.render(scene, camera);
    }
    animate();
  </script>
</body>
</html>
  • 優點:不需安裝任何套件,直接在任何支援 ES Module 的瀏覽器跑。
  • 缺點:每次載入都會向 CDN 請求檔案,若網路不穩或 CDN 發生故障,開發體驗會受影響。

4. 完整的「Hello Three.js」範例(ESM 版)

以下示範 npm + ESM 的完整流程,適合想建立可編譯、可部署的專案時使用。

// src/main.js
import * as THREE from 'three';
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js';

// ---------- 初始化渲染器 ----------
const renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);

// ---------- 建立場景與相機 ----------
const scene = new THREE.Scene();
scene.background = new THREE.Color(0x202020);

const camera = new THREE.PerspectiveCamera(
  60,                                 // 視角 (FOV)
  window.innerWidth / window.innerHeight,
  0.1,                                // 近剪裁面
  1000                                 // 遠剪裁面
);
camera.position.set(3, 2, 5);

// ---------- 加入光源 ----------
const ambient = new THREE.AmbientLight(0xffffff, 0.4);
scene.add(ambient);

const directional = new THREE.DirectionalLight(0xffffff, 0.8);
directional.position.set(5, 10, 7);
scene.add(directional);

// ---------- 建立簡易幾何 ----------
const geometry = new THREE.SphereGeometry(1, 32, 32);
const material = new THREE.MeshStandardMaterial({
  color: 0xff6600,
  roughness: 0.5,
  metalness: 0.1
});
const sphere = new THREE.Mesh(geometry, material);
scene.add(sphere);

// ---------- 控制器 ----------
const controls = new OrbitControls(camera, renderer.domElement);
controls.enableDamping = true; // 平滑慣性

// ---------- 窗口尺寸變更 ----------
window.addEventListener('resize', () => {
  const { innerWidth, innerHeight } = window;
  renderer.setSize(innerWidth, innerHeight);
  camera.aspect = innerWidth / innerHeight;
  camera.updateProjectionMatrix();
});

// ---------- 動畫迴圈 ----------
function render() {
  requestAnimationFrame(render);
  controls.update();   // 只在 enableDamping 時需要
  renderer.render(scene, camera);
}
render();

說明

  • import * as THREE from 'three' 會一次匯入所有核心類別。
  • OrbitControls 放在 examples/jsm/controls 目錄下,必須使用 完整的檔案路徑(結尾要 .js)。
  • renderer.setSizecamera.aspect 需要在視窗大小變更時同步更新,否則畫面會被拉伸。

常見陷阱與最佳實踐

陷阱 可能的症狀 解決方法 最佳實踐
忘記在 <script>type="module" Uncaught SyntaxError: Cannot use import statement outside a module 為所有使用 import<script> 標籤加上 type="module" 使用 Vite/Parcel 時,預設已設定為模組,無需手動加
引用舊版 CDN URL 3D 物件不顯示、API 失效 直接使用 https://cdn.jsdelivr.net/npm/three@<最新版本>/build/three.module.js 鎖定版本(如 @0.162.0)避免因新版破壞相容性
範例程式檔案路徑錯誤 (OrbitControlsGLTFLoader 等) Failed to load module script 確認路徑以 examples/jsm/ 開頭,且結尾加 .js 建議在 IDE 中使用 自動補全,減少手寫錯誤
未設定 crossOrigin (載入外部資源如貼圖、模型) 貼圖載入失敗、CORS 錯誤 loader 上設定 loader.setCrossOrigin('anonymous') 或在伺服器端加上 CORS 頭 若使用 Vite,可在 vite.config.js 設定 server.cors:true
過度依賴 CDN,未加離線快取 部署後無法在無網路環境使用 使用 Service WorkerWorkbox 快取 CDN 檔案 在正式專案中,建議把 Three.js 打包進 dist,減少外部依賴

實際應用場景

  1. 快速原型驗證

    • 使用 CDN 直接在 CodePen、JSFiddle 或本機 HTML 中測試概念,省去建置時間。
  2. 企業級 WebGL 專案

    • 透過 npm 安裝、ESM 匯入,配合打包工具(Vite、Webpack)產生最小化的 bundle,確保載入效能與版本可控。
  3. 多模組協作

    • 在大型團隊中,使用 ESM 能讓每個子模組(如 scene-manager.jsui-controls.js)獨立開發、單元測試,最後再由主入口匯入。
  4. 離線或嵌入式設備

    • 把 Three.js 打包成單一檔案(使用 Rollup 的 output.format: 'esm'),搭配本機檔案系統或 Electron,避免依賴外部 CDN。

總結

  • ESM 為現代前端的標準模組系統,提供靜態分析、Tree‑shaking 等優勢;配合 npm 安裝可讓專案更易維護。
  • CDN 則是「零安裝」的速成方案,適合快速驗證想法或教學示範。
  • 正確的 模組路徑type="module" 設定、以及 版本鎖定,是避免常見錯誤的關鍵。
  • 在實務開發中,建議 先以 CDN 起手,確認概念後再轉移至 npm + ESM 的正式開發流程,這樣既能快速迭代,也能確保最終產品的效能與可維護性。

掌握了安裝與模組載入的基礎後,你就可以把注意力放在 場景構建、動畫控制、資源載入 等更具創意的部分,讓 Three.js 成為你打造互動 3D 網頁體驗的強大工具。祝開發順利,玩得開心! 🎉