1. Import Maps для ES-модулів без збірки
Import map — це блок <script type="importmap">
у вашому HTML, який зіставляє «голі» специфікатори модулів
(наприклад 'three') з реальними URL-адресами. Усі
сучасні браузери підтримують це нативно:
<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">
// ✅ Працює прямо в браузері — бандлер не потрібен
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. Типи TypeScript без tsc
Мовний сервер TypeScript у VS Code (Pylance / tsserver) читає
визначення типів навіть для звичайних файлів .js,
якщо додати jsconfig.json або коментар
// @ts-check. Встановіть пакет типів локально (лише
для редактора — він не постачається користувачам) і вкажіть на
нього у своєму конфігу:
# У директорії вашого проєкту: npm install --save-dev three @types/three # Це встановлює лише в node_modules — нічого не пакується й не постачається
// jsconfig.json — вмикає типи у VS Code для файлів .js
{
"compilerOptions": {
"checkJs": true,
"strict": false,
"moduleResolution": "bundler",
"types": ["three"]
},
"include": ["**/*.js"],
"exclude": ["node_modules"]
}
Тепер VS Code знає повне дерево типів Three.js. Ви отримуєте
автодоповнення, документацію при наведенні та помилки типів у
файлах JavaScript — без tsconfig.json і без кроку
компіляції.
3. JSDoc як альтернатива типізованому JavaScript
Якщо потрібна нульова залежність від Node.js (жодного
package.json), можна додати типи через анотації
JSDoc і посилатися на визначення типів із 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);
}
Посилання на типи через CDN працюють у VS Code
1.88+ із рушієм
"typescript.preferences.useAliasesForRenames". VS Code завантажує
файл .d.ts один раз і кешує його. Саме такий підхід
використовується в усіх симуляціях на цьому сайті — жодних
інструментів збірки, повний IntelliSense.
4. Типові пастки з типами в проєктах на Three.js
document.getElementById('canvas') повертає
HTMLElement | null. Конструктор
WebGLRenderer у Three.js очікує
HTMLCanvasElement, а не
HTMLElement | null. Явно приведіть тип:
canvas as HTMLCanvasElement або використайте
перевірку-охоронець:
if (!(el instanceof HTMLCanvasElement)) return;
scene.getObjectByName('mesh') повертає
Object3D | undefined. Якщо ви знаєте, що це
Mesh, використайте приведення типу:
scene.getObjectByName('mesh') as THREE.Mesh | undefined
і обробіть випадок undefined перед доступом до геометрії чи
матеріалу.
mesh.material.color не компілюється, бо базовий
тип Material не має властивості
color. Потрібно звузити до конкретного типу:
(mesh.material as
THREE.MeshStandardMaterial).color.set('#ff0000')
або одразу оголосити mesh як
THREE.Mesh<THREE.BufferGeometry,
THREE.MeshStandardMaterial>.
event.target в обробнику подій — не об'єкт
Three.js
Raycaster властивість
object перетину типізована як
Object3D, а не як конкретний підтип mesh.
Використайте
intersection.object instanceof THREE.Mesh як
перевірку типу перед доступом до властивостей, специфічних для
mesh.
ShaderMaterial.uniforms типізовано як
{ [uniform: string]: IUniform } — дуже широко.
Визначте типізовану константу і розгорніть її в матеріал, щоб
отримати автодоповнення для конкретних імен ваших uniform-ів:
const uniforms = { uTime: { value: 0 } } as const.
5. Рекомендації щодо строгого режиму
Навіть у налаштуванні лише з JSDoc увімкнення
"strict": true у jsconfig.json ловить
вищезгадані пастки з null/undefined ще на етапі редагування. Для
проєктів на Three.js найкорисніші саме такі підопції строгого
режиму:
-
strictNullChecks— ловить усі проблеми з| null | undefined, описані вище -
noImplicitAny— вимагає анотацій типів для параметрів функцій, вловлюючи проблемуObject3DпротиMeshпрямо в місці виклику