首页 > 解决方案 > Three.js 与打字稿自动完成

问题描述

我有一个使用 Typescript 和 Three.js 的 Node.js 项目。要导入模块,我使用 commonjs 语法,我通过

{
  "compilerOptions": {
    "module": "commonjs"
  }
}

在我的tsconfig.json. 我通过 NPM 下载的 Three.js 有一个像这样的打字稿文件:

const THREE = require('three');
const scene = new THREE.Scene();

编译得很好,但我没有得到任何自动完成。我不认为这特定于所使用的编辑器,因为 Visual Studio Code 以及带有 YouCompleteMe 的 Neovim 都不起作用。如果我使用 ES6 模块语法,两者都可以工作:

import * as THREE from 'node_modules/three/src/Three';
const scene = new THREE.Scene();

但是,在这里,如果不提供库的实际路径,我就无法让它工作(这是稍后使用 webpack 时的问题)。我忘记配置什么来获得自动完成(或没有明确定义路径的 ES6 语法,此时我对这两种解决方案都很好)?

编辑

正如对已接受答案的评论中所述,我无法找到我的错误,但在尝试创建一个最小的工作项目时找到了一个可行的解决方案。因此,我将在此处发布此内容,以防对其他人有所帮助。如果您有同样的问题,请仍然阅读答案,因为它是正确的。

我的源文件(在src/main.ts):

import * as THREE from 'three';
const scene = new THREE.Scene();

package.json(使用 webpack 测试是否可以在那里解析库):

{
  "devDependencies": {
    "@types/node": "^12.0.4",
    "three": "^0.105.2",
    "ts-loader": "^6.0.2",
    "typescript": "^3.5.1",
    "webpack": "^4.32.2",
    "webpack-cli": "^3.3.2"
  }
}

tsconfig.json

{
  "compilerOptions": {
      "baseUrl": ".",
      "paths": { "*": ["types/*"] },
    "target": "es6",
    "module": "es6",
    "outDir": "./dist",
    "rootDir": "./src",
    "strict": true,
    "moduleResolution": "node",
    "esModuleInterop": true,
    "sourceMap": true
  },
  "include": [
    "src/**/*.ts"
  ],
  "exclude": [
    "node_modules/"
  ]
}

webpack.config.js

const path = require('path');

module.exports = {
    entry: './src/main.ts',
    output: {
        filename: 'bundle.js',
        path: path.resolve(__dirname, 'dist')
    },
    resolve: {
        extensions: [ '.ts', '.js' ]
    },
    module: {
        rules : [
            { test: /\.ts$/, use: [ 'ts-loader' ], exclude: /node_modules/ }
        ]
    }
};

标签: node.jstypescriptthree.js

解决方案


您的文件three中安装了哪个版本?package.json确保它是0.101或以后,因为那是 TypeScript 支持开始的时候。我建议您使用最新的(撰写本文时为 105 个),因为它会在每个版本中获取更新的定义文件。

然后,在您的 .ts 文件中,您可以使用以下命令导入它:

import * as THREE from "three";

// After importing, THREE is available for auto-complete.
var lala = new THREE.WebGLRenderer();

编辑:

您可能需要在文件中执行路径映射.tsconfig以强制编译器找到正确的模块地址。我从来没有这样做过,但是 Typescript 文档建议是这样的:

{
  "compilerOptions": {
    "baseUrl": ".", // This must be specified if "paths" is.
    "paths": {
      "three": ["node_modules/three/src/Three"] // relative to "baseUrl"
    }
  }
}

更新 r126

截至修订版r126,Three.js 已将 Typescript 声明文件移至单独的存储库。如果您正在使用r126或更高版本,则必须npm install @types/three作为第二步运行。确保您安装的版本针对@types/three您的 Three.js 版本。例如:

"three": "0.129.0",
"@types/three": "^0.129.1",

推荐阅读