7

我想使用 Three.js ( @types/three/index) 扩展导入到 ng6 项目中的类型定义,其中包含一组将直接附加到相同“命名空间”的函数。类似的东西:THREE.myFunction()我不想声明 THREEany来抑制类型检查和 linter,我想可以包装一个使用 TS 类/函数扩展 THREE 的 vanilla JS 函数,然后利用typings.d.ts.

导入加载器

首先,我想在我的项目中导入一个 THREE.js 加载器,这通常定义了一个扩展的 vanilla 函数THREE

我正在尝试将其导入BinaryLoaderng 服务,但我不确定如何以正确的方式进行操作。

到目前为止我做了什么:

  1. npm install three --save
  2. npm install @types/three --save-dev
  3. import * as THREE from 'three';
  4. 将 BinaryLoader 添加到新的angular.json scripts数组

角.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’(导入为‘三’)

静音类型警告和 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 答案:

4

3 回答 3

8

我终于找到了两个可行的解决方案(准确地说是=> 变通方法)。

使用 Webpack 的 imports-loader

[...] import-loader是一个 Webpack 插件,允许您将全局变量注入模块的作用域。所以!你的执行上下文的 global ( ) 命名空间仍然完全干净,但是在“编译”期间,Webpack 将能够找出在哪里查找仅带有全局变量的模块的绑定。

通过这个 three.js 票

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

使用此导入,我们告诉 WebpackTHREE用作由 npm 模块定义的全局变量,'three'并且 BinaryLoader 不会绑定到任何变量。

使用三满提供THREE命名空间

项目three-full扩展了标准 three.js 库定义的命名空间,添加了几个“示例”,如加载器和控件。使用它而不是经典的threenpm 包,可以完全支持 ES6 命名空间,用于最常见和最有用的类,这些类通常是绝大多数基于 three.js 的项目的一部分。

npm install --save three-full

然后你可以导入整个命名空间:

import * as THREE from 'three-full';
...
const loader = new THREE.ColladaLoader();  
于 2018-05-09T13:40:02.030 回答
0

如何使用一个小助手库,我希望做同样的事情 - 我找到了这个:https ://www.npmjs.com/package/ng-three

于 2018-11-26T22:06:55.623 回答
0

两个步骤,安装包,然后安装类型。

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

然后在您的组件中导入为: import * as THREE from 'three';

你已经设置好了类型和包。

于 2021-06-11T19:24:12.880 回答