Jerome Reinländer
Jerome Reinländer

Reputation: 1257

Three.js with typescript autocomplete

I have a Node.js project that uses Typescript and Three.js. To import modules, I use the commonjs syntax, which I configured via

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

in my tsconfig.json. I downloaded Three.js via NPM have a typescript file like this:

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

which compiles fine, but I do not get any autocomplete. I don't think this specific to the editor used, as both Visual Studio Code as well as Neovim with YouCompleteMe don't work. Both work if I use the ES6 module syntax:

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

Here however I cannot get it to work without giving the actual path to the library (which is a problem later on when using webpack). What did I forget to configure to get autocomplete (or the ES6 syntax without explicitly defining the path, at this point I am fine with both solutions)?

EDIT

As mentioned in the comments to accepted answer, I was not able to find my mistake, but found a working solution while trying to create a minimal working project. So I will post this here, in case it might help someone else. If you have the same problem, please still read the answer, as it is correct.

My source file (in src/main.ts):

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

package.json (with webpack to test if the library can be resolved there):

{
  "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/ }
        ]
    }
};

Upvotes: 2

Views: 1758

Answers (1)

M -
M -

Reputation: 28482

What version of three is installed in your package.json file? Make sure it's 0.101 or later, since that's when TypeScript support began. I recommend you use the latest (105 as of this writing), since it gets updated definition files on each release.

Then, in your .ts files, you can import it with:

import * as THREE from "three";

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

Edit:

You might need to perform path-mapping in your .tsconfig file to force the compiler to find the correct module address. I've never had to do this, but the Typescript documentation suggests something like this:

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

Update r126

As of revision r126, Three.js has moved Typescript declaration files to a separate repository. If you're using r126 or later, you'll have to run npm install @types/three as a second step. Make sure you install the version of @types/three that targets your version of Three.js. For example:

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

Upvotes: 5

Related Questions