如何在TypeScript中使用ThreeJS ES6原生模块?

3
我是直接在浏览器中使用ThreeJS ES6本地模块。这是一个非常酷的功能,您可以在javascript文件中直接使用import ThreeJS,无需任何模块打包工具。
以下是javascript中可行的内容:
import * as THREE from './lib/three.module.js'
import { OrbitControls } from './lib/OrbitControls.js'

现在我想使用Typescript完成这个任务,我已经安装了typescript的定义文件。
npm install --save @types/three 

但是,VS Code仍然找不到类型声明文件: ⚠️ 找不到“../lib/three.module.js”模块的声明文件 ⚠️ 找不到“../lib/OrbitControls.js”模块的声明文件 如评论中所建议,我将导入更改为:
import * as THREE from 'three'
import { OrbitControls } from three/examples/jsm/controls/OrbitControls'

现在已经找到了声明,但是typescript找不到模块!
⚠️ 访问器不能在环境上下文中声明,解析模块说明符“three”失败。
⚠️ 相对引用必须以“/”,“./”或“../”开头。
如何在没有模块打包器的情况下在我的Typescript项目中使用ThreeJs的ES6本地模块?
4个回答

2
您只需创建一个与库同名的.d.ts文件--在您的情况下是./lib/three.module.d.ts。当您使用import * as Three from "./lib/three.module.js"时,Typescript将在模块解析策略中查找兄弟类型文件。在此文件中,您可以简单地export描述模块形状的类型。在您的情况下,您只需要这样做就可以了。
import * as Three from "three";
export = Three;

嗯,这看起来很有前途!.d.ts文件似乎没有立即被捕捉到,但也许是我做错了什么。稍后再调整一下 :) - Peter Ehrlich

2
尝试按以下方式组织您的导入语句:

import * as THREE from 'three'
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls';

1
谢谢,现在类型检查正常了。但是在编译时我遇到了两个问题:一个是“无法在环境上下文中声明访问器”,另一个是“无法解析模块说明符‘three’。相对引用必须以'/'、'./'或'../'开始”。 - Kokodoko
你使用的 TypeScript 版本是什么? - Mugen87
版本3.4.5。经过很多的尝试和错误,我无法让本地模块与TypeScript编译一起工作。所以现在我只安装了 npm install three 并使用一个模块捆绑器。这样可以正常工作。虽然我仍然不知道本地模块是否能够与TypeScript一起工作。 - Kokodoko

1

来自TypeScript Github Issues的Jamesernator提供了另一种可能的解决方案:只需将以下内容添加到您的html中:

<script type="importmap">
            {
                "imports": {
                    "three": "./js/lib/three.module.js"
                 }
            }    
 </script>

浏览器将进行重新映射。不错! https://github.com/microsoft/TypeScript/issues/50600

0

看起来你必须使用别名来声明文件,而别名不支持es6原生的导入语句。文档中根本没有解决这个问题: https://www.typescriptlang.org/docs/handbook/declaration-files/consumption.html

有些人通过添加整个构建流程来解决这个问题,但是这种复杂度对我来说太高了: Typescript declaration file created with alias instead of relative path

相反,我使用了tsc-watch和一个最小的bash脚本: https://www.npmjs.com/package/tsc-watch

$ tsc-watch --onSuccess "./mysed"

$ cat ./mysed
#!/bin/bash

# use *js to capture .mts as well as .js
sed -i "" "s/import \* as THREE from 'three';/import \* as THREE from '.\/lib\/three\.module\.js';/" js/*js;

这将在我的 .ts 中用 import * as THREE from './lib/three.module.js' 替换 import * as THREE from 'three';,允许我在开发中引用带有类型的版本,在生产中引用不带类型的版本。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接