使用 webpack、threejs 示例和 typescript?

Posted

技术标签:

【中文标题】使用 webpack、threejs 示例和 typescript?【英文标题】:Using webpack, threejs examples, and typescript? 【发布时间】:2016-06-28 08:10:48 【问题描述】:

我在让 threejs 的示例(如 EffectComposer 或 Detector)中的东西与 webpack 和 typescript 一起工作时遇到了很多麻烦。

首先,相关的*.d.ts 文件都存在并通过tsd 安装。我的问题是让 webpack 实际上包含默认的threejs 构建之外的文件(即examples/js/ 中的内容)。

从 npm 安装 three 我可以做类似的事情

import THREE = require('three');

效果很好,但缺少上述任何好处。 npm 上还有一些其他的 threejs 包捆绑插件,但我认为它们不适用于 typescript(因为require('three-js')(['EffectComposer']) 被 typescript 编译器拒绝。

有没有人在这个包中得到了一些东西(比如后处理)来使用打字稿?

【问题讨论】:

【参考方案1】:

我设法在webpack.config.js 中找到了一种非常简洁的设置方法。

根据丹的回答:

$ npm install --save-dev imports-loader

事实证明我们实际上并不需要exports-loader,因为three.js 示例将它们的构造函数添加到THREE 对象中。

然后,在webpack.config.js 中,如果模块的路径解析为包含three/examples/js 的任何内容,我们可以添加规则以将var THREE = require('three'); 添加到导入的模块中:

module: 
  rules: [
    ...
    
      test: /three\/examples\/js/,
      use: 'imports-loader?THREE=three'
    
  ]

现在示例模块会在他们期望的时候找到三个全局变量。

然后,让导入示例不那么冗长:

resolve: 
  alias: 
    'three-examples': path.join(__dirname, './node_modules/three/examples/js')
  ,
  ...
,

这里假设webpack.config.jsnode_modules在同一目录下,相应调整。

现在,我们可以像这样使用示例文件:

import * as THREE from 'three';
import 'three-examples/controls/OrbitControls';

为了它的副作用导入模块。

如果您将它与 Typescript 和/或 Babel 一起使用,并且收到有关在 THREE 上找不到示例模块的警告,您可能会在 imports-loader 存储库中找到有用的参考 this issue。

【讨论】:

能否请您在这里提供整个 webpack 配置,在哪里添加解析部分? 我有一堆无关紧要的细节,但在 webpack.js.org/configuration 之后,它位于 module.exports 的顶层,与 module 并列 对我来说它只适用于 'const THREE = require('three');' 它有效,但这个警告真的让我很困扰 - 你找到解决方法了吗? @rpadovani 我不确定您指的是哪个警告。你是说小丑的回答中提到的那个吗?【参考方案2】:

这对我有用。

$ npm install --save-dev exports-loader imports-loader

然后,要使用来自three/examples/js 的东西,我这样做:

const THREE = require('three');
// imports provides THREE to the OrbitControls example
// exports gets THREE.OrbitControls
THREE.OrbitControls = require('imports?THREE=three!exports?THREE.OrbitControls!../../node_modules\/three\/examples\/js\/controls\/OrbitControls');

// use THREE.OrbitControls ...

我认为正确的做法是使用 importsexports 加载器 by config 而不是将它们嵌入到 require 中。当我有一个例子时,我会更新这个答案。

【讨论】:

这仍然有效,尽管我省略了THREE.OrbitControls = 位。在webpack.config 中而不是在代码文件中会很好,但我很难让它工作。 在配置文件中找到了一种方法,请参见下面的答案。【参考方案3】:

我能够将 OrbitControls 与 (webpack v2 + ts-loader) 捆绑在一起,而没有其他加载器。

package.json:

"dependencies": 
    "three": "^0.85.2",
    "@types/three": "^0.84.12",
    "ts-loader": "^2.1.0",
    "typescript": "^2.3.4",
    "webpack": "^2.6.1"
,

入口点.ts:

import * as THREE from "three";

// OrbitControls.js expects a global THREE object
(window as any).THREE = THREE;

// NOTE: OrbitControls must be included with require:
// using "import" cause it to be executed before global THREE becomes available
require("three/examples/js/controls/OrbitControls");

// ... code that uses THREE and THREE.OrbitControls

注意:webpack 可能会发出类似"export 'OrbitControls' (imported as 'THREE') was not found in 'three' 的警告,因为OrbitControls.js 不是正确的 JS 模块。我想我们可以忽略这个警告。

【讨论】:

【参考方案4】:

我将尝试回答您关于在您的 IDE 中集成 TypeScript 和 ThreeJS 的部分问题。

如您所见,大多数组件都托管在DefinitelyTyped 档案中。我确实建议停止使用 tsd 并迁移到 typing

下面列出了typing 将使用的基本typings.json。它获取最新的主要 ThreeJS 和 TypeScript 识别的效果器库。请注意,提交主题标签会随着 .tsd 的发展而变化。


  "ambientDependencies": 
    "three": "github:DefinitelyTyped/DefinitelyTyped/threejs/three.d.ts#c6c3d3e65dd2d7035428f9c7b371ec911ff28542",
    "three-projector": "github:DefinitelyTyped/DefinitelyTyped/threejs/three-projector.d.ts#48f20e97bfaf70fc1a9537b38aed98e9749be0ae",
    "three-detector": "github:DefinitelyTyped/DefinitelyTyped/threejs/three-effectcomposer.d.ts#48f20e97bfaf70fc1a9537b38aed98e9749be0ae",
    "three-effectscomposer": "github:DefinitelyTyped/DefinitelyTyped/threejs/detector.d.ts#48f20e97bfaf70fc1a9537b38aed98e9749be0ae",
    "three-shaderpass": "github:DefinitelyTyped/DefinitelyTyped/threejs/three-shaderpass.d.ts#ee05b1163d8da7f16719f08d52f70ab524f1003a"
  

附件是识别 EffectsComposer 的公共方法的 IDE 的快照。您可能还想尝试使用 TypeScript 的不同模块加载器功能。

【讨论】:

以上是关于使用 webpack、threejs 示例和 typescript?的主要内容,如果未能解决你的问题,请参考以下文章

Threejs核心API

Threejs:与热点交互的全景图

ThreeJS - 错误的光线旋转

没有纹理的 ThreeJs 和 Blender 模型

如何在threejs中从平面发光?

用这种方法,你也可以创建threejs场景