1. Import Maps dla modułów ES bez budowania
Import map to blok <script type="importmap"> w
twoim HTML, który mapuje gołe specyfikatory modułów (jak
'three') na rzeczywiste adresy URL. Wszystkie
nowoczesne przeglądarki obsługują to natywnie:
<script type="importmap">
{
"imports": {
"three": "https://cdn.jsdelivr.net/npm/three@0.160/build/three.module.js",
"three/addons/": "https://cdn.jsdelivr.net/npm/three@0.160/examples/jsm/"
}
}
</script>
<script type="module">
// ✅ Działa bezpośrednio w przeglądarce — bundler niepotrzebny
import * as THREE from 'three';
import { OrbitControls } from 'three/addons/controls/OrbitControls.js';
const renderer = new THREE.WebGLRenderer({ antialias: true });
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(60, innerWidth / innerHeight, 0.1, 1000);
// ...
</script>
2. Typy TypeScript bez tsc
Serwer językowy TypeScript w VS Code (Pylance / tsserver) czyta
definicje typów nawet dla zwykłych plików .js,
jeśli dodasz jsconfig.json lub komentarz
// @ts-check. Zainstaluj pakiet typów lokalnie
(tylko dla edytora — nie jest dostarczany użytkownikom) i wskaż
na niego w swojej konfiguracji:
# W katalogu twojego projektu: npm install --save-dev three @types/three # To instaluje tylko do node_modules — nic nie jest pakowane ani wysyłane
// jsconfig.json — włącza typy w VS Code dla plików .js
{
"compilerOptions": {
"checkJs": true,
"strict": false,
"moduleResolution": "bundler",
"types": ["three"]
},
"include": ["**/*.js"],
"exclude": ["node_modules"]
}
Teraz VS Code zna całe drzewo typów Three.js. Otrzymujesz
autouzupełnianie, dokumentację po najechaniu kursorem oraz błędy
typów w swoich plikach JavaScript — bez
tsconfig.json i bez kroku kompilacji.
3. JSDoc jako alternatywa dla typowanego JavaScriptu
Jeśli chcesz zerowej zależności od Node.js (żadnego
package.json), możesz dodać typy poprzez adnotacje
JSDoc i odwołać się do definicji typów z CDN:
// @ts-check
/// <reference types="https://cdn.jsdelivr.net/npm/@types/three/index.d.ts" />
/** @type {import('three').PerspectiveCamera} */
const camera = new THREE.PerspectiveCamera(60, innerWidth / innerHeight, 0.1, 1000);
/**
* @param {import('three').Mesh} mesh
* @param {import('three').Vector3} direction
* @returns {void}
*/
function moveMesh(mesh, direction) {
mesh.position.add(direction);
}
Odwołania do typów przez CDN działają w
VS Code 1.88+ z silnikiem
"typescript.preferences.useAliasesForRenames". VS Code pobiera
plik .d.ts raz i go buforuje. To podejście
stosowane jest we wszystkich symulacjach na tej stronie — bez
narzędzi do budowania, pełny IntelliSense.
4. Typowe pułapki typów w projektach Three.js
document.getElementById('canvas') zwraca
HTMLElement | null. Konstruktor
WebGLRenderer w Three.js oczekuje
HTMLCanvasElement, a nie
HTMLElement | null. Rzutuj jawnie:
canvas as HTMLCanvasElement lub użyj asercji
null wewnątrz strażnika:
if (!(el instanceof HTMLCanvasElement)) return;
scene.getObjectByName('mesh') zwraca
Object3D | undefined. Jeśli wiesz, że to
Mesh, użyj asercji typu:
scene.getObjectByName('mesh') as THREE.Mesh | undefined
i obsłuż przypadek undefined przed dostępem do geometrii lub
materiału.
mesh.material.color nie kompiluje się, ponieważ
bazowy typ Material nie ma właściwości
color. Musisz zawęzić do konkretnego typu:
(mesh.material as
THREE.MeshStandardMaterial).color.set('#ff0000')
lub od razu zadeklarować mesh jako
THREE.Mesh<THREE.BufferGeometry,
THREE.MeshStandardMaterial>.
event.target w handlerze zdarzenia to nie
obiekt Three.js
Raycaster właściwość
object przecięcia jest typowana jako
Object3D, a nie konkretny podtyp mesha. Użyj
intersection.object instanceof THREE.Mesh jako
strażnika typu przed dostępem do właściwości specyficznych
dla mesha.
ShaderMaterial.uniforms jest typowane jako
{ [uniform: string]: IUniform } — bardzo
szeroko. Zdefiniuj typowaną stałą i rozszerz ją w materiale,
by uzyskać autouzupełnianie dla swoich konkretnych nazw
uniformów:
const uniforms = { uTime: { value: 0 } } as const.
5. Zalecenia dotyczące trybu ścisłego
Nawet w konfiguracji opartej wyłącznie na JSDoc włączenie
"strict": true w jsconfig.json wychwytuje
powyższe pułapki null/undefined już na etapie edycji. Dla
projektów Three.js najbardziej przydatne są następujące
podopcje trybu ścisłego:
-
strictNullChecks— wychwytuje wszystkie powyższe problemy z| null | undefined -
noImplicitAny— wymusza adnotacje typów dla parametrów funkcji, wychwytując problemObject3DkontraMeshjuż w miejscu wywołania