Как импортировать загрузчик Three.js в проект Angular 6

Я хочу расширить определения типов, импортированные в проект ng6 с использованием Three.js (@types/three/index), с набором функций, которые будут напрямую присоединены к тому же «пространству имен». Что-то вроде: THREE.myFunction(). Я не хочу объявлять THREE как any, чтобы подавить проверку типов и линтер, и я предполагаю, что можно было бы обернуть ванильную функцию JS, которая расширяет THREE, используя класс / функцию TS и затем воспользовавшись typings.d.ts.

Импорт загрузчика

Прежде всего, я хотел бы импортировать в свой проект загрузчик THREE.js, который обычно определяет ванильную функцию, расширяющую THREE.

Я пытаюсь импортировать _6 _ в службу ng, и я не уверен, как это сделать правильно.

Что я сделал до сих пор:

  1. npm install three --save
  2. npm install @types/three --save-dev
  3. import * as THREE from 'three';
  4. добавить BinaryLoader в новый массив angular.json scripts

angular.json

        "scripts": [
          "./node_modules/three/examples/js/loaders/BinaryLoader.js"
        ]

Пока все хорошо, но теперь мне нужно создать бинарный загрузчик:

import * as THREE from 'three';
// import { BinaryLoader } from 'three';
// import 'three/examples/js/loaders/BinaryLoader';

export class ThreeManagerService {
   const loader = new THREE.BinaryLoader();
   ...

и мне нужно найти способ как-то добавить BinaryLoader к @types/three/index. Таким образом я смогу расширить определения типов, чтобы создать новый тип THREE.BinaryLoader. Возможно ли такое сделать?

Я получил следующее предупреждение:

ПРЕДУПРЕЖДЕНИЕ в ./src/app/shared/three-manager.service.ts 24: 25-43 "экспорт 'BinaryLoader' (импортированный как 'THREE') не был найден в 'three'

Предупреждения типа Silencing Type и транспилятор TS

Обходной путь, чтобы избавиться от предупреждений, и ошибка может быть примерно такой:

import * as THREEJS from 'three';
declare const THREE: any;

export class ThreeManagerService {
   const loader = new THREE.BinaryLoader();

Дело в том, что я считаю этот обходной путь очень уродливым «исправлением». Я хотел бы как можно больше использовать систему типов.

РЕДАКТИРОВАТЬ: Получите примеры для хорошей игры с Intellisense и Typescript

Ожидая полного переписывания примеров для совместимости с модулями и пространствами имен ES6, можно было бы определить локальный модуль, который раскрывает и дополняет глобальный, в /src/node_modules/three-extras/index.ts:

import * as THREE from 'three';

declare global {
   interface Window {
      THREE: typeof THREE;
   }
}

window.THREE = THREE;

require('three/examples/js/controls/OrbitControls');
require('three/examples/js/loaders/GLTFLoader');

через: https://github.com/mrdoob/three.js/issues/9562#issuecomment-386522819

Связанные и полезные ответы SO:


person sentenza    schedule 06.05.2018    source источник
comment
Вы уверены, что BinaryLoader определен внутри файла three.js? Я так не думаю   -  person HariV    schedule 08.05.2018
comment
@HariV да, этот загрузчик, как и многие другие, является частью библиотеки three.js и был определен в качестве примера. На самом деле, продолжается обсуждение того факта, что многие сценарии, определенные как простые сценарии ES5, не были разделены на модули на этот билет репозитория Three.js на Github.   -  person sentenza    schedule 08.05.2018
comment
После долгого чтения я нашел этот комментарий особенно полезным. По-видимому, существует совместимый с ES6 перенос Three.js под названием трехполный. Таким образом, его можно использовать для загрузки загрузчиков или элементов управления в виде модулей. Ура!   -  person sentenza    schedule 08.05.2018


Ответы (3)


Наконец-то я нашел два рабочих решения (=> обходные пути, если быть точным).

Использование загрузчика импорта Webpack

[...] import-loader - это плагин Webpack, позволяющий вводить глобальную переменную в область вашего модуля. Таким образом, глобальное (!) пространство имен вашего контекста выполнения по-прежнему остается полностью чистым, но во время «компиляции» Webpack сможет выяснить, где искать привязку для модуля, который поставляется только с глобальной переменной.

Через этот билет three.js

import "imports?THREE=three!loaders/BinaryLoader";

Используя этот импорт, мы говорим Webpack использовать THREE в качестве глобальной переменной, определенной модулем npm 'three', и BinaryLoader не будет привязан к какой-либо переменной.

Используйте три полных, чтобы предоставить пространство имен THREE

Проект трехкратный расширяет пространство имен, определенное стандартной библиотекой three.js, добавляя несколько «примеров» как загрузчики и элементы управления. Используя его вместо классического пакета three npm, можно будет получить полную поддержку пространств имен ES6 для наиболее распространенных и полезных классов, которые обычно являются частью подавляющего большинства этих проектов, основанных на three.js.

npm install --save three-full

А затем вы можете импортировать все пространство имен:

import * as THREE from 'three-full';
...
const loader = new THREE.ColladaLoader();  
person sentenza    schedule 09.05.2018
comment
Вы не представляете, как долго я боролся с этим. Я везде искал ответы! Большое спасибо! - person K-Dawg; 13.08.2019
comment
Я подозреваю, что @ K-Dawg, как и я, и я уверен, что бесчисленное множество других, ожидали, что смогут использовать three.js, как и большинство других пакетов NPM. Я ошеломлен своей забывчивостью о том, что библиотеки создания сетки сложны, и, к счастью, такие инструменты, как yarn / npm, упростили это для нас. В любом случае, спасибо за полный ответ, который предлагает ряд решений. Карма дает вам много голосов. - person Jacksonkr; 22.05.2021

Я хочу сделать то же самое с помощью небольшой вспомогательной библиотеки - я нашел вот эту: https://www.npmjs.com/package/ng-three

person Devin McQueeney    schedule 26.11.2018

Два шага, установите пакет, а затем типы.

  1. npm install three --save
  2. npm install @ types / three --save-dev

И затем в вашем компоненте просто импорт выглядит следующим образом: import * as THREE from 'three';

У вас все готово к типам и комплектации.

person GeoRover    schedule 11.06.2021