I'm making a typescript project for client side javascript code.
Before I was using typescript, I imported a module like this (this is vanilla js in es6)
import * as THREE from 'https://threejs.org/build/three.module.js';
but with typescript, I installed the module with npm install and then import it like this
import * as THREE from 'three';
Problem is, when I then run the compiled js code, I get this browser js error:
Uncaught TypeError: Failed to resolve module specifier "three". Relative references must start with either "/", "./", or "../".
since import * as THREE from 'three'; is now in the compiled js files.
How can I fix this?
Thanks
tsconfig.json
{
"compilerOptions": {
"outDir": "dist/",
"rootDir": "./src",
"sourceMap": false,
"noImplicitAny": true,
"moduleResolution": "Node",
"resolveJsonModule": true,
"module": "ESNext",
"target": "ESNext",
"lib": [
"ESNext", "DOM"
],
"allowJs": false,
"alwaysStrict": true,
"typeRoots": [
"node_modules/@types"
]
},
"include": [
"src/",
"src/**/*.json"
],
"exclude": [
]
}
CodePudding user response:
In order to use this on the client side, a bundler would be needed.
I suggest webpack or snowpack. Snowpack is new and has a lot of very cool features.
CodePudding user response:
This assumes you are using TypeScript to compile isolated ES modules destined for use in the browser, loaded in HTML tags like
<script type="module" src="myCompiledModule.js">. From your question details, it sounds like this is the case.
Although not entirely straightforward, it's relatively simple to accomplish this:
In order to satisfy the compiler, make sure you have installed both typescript and @types/three:
npm install typescript @types/three
Then, add this path mapping to your ./tsconfig.json:
{
...
"compilerOptions": {
"baseUrl": ".",
"paths": {
"https://threejs.org/build/three.module.js": ["node_modules/@types/three"]
},
...
},
...
}
Here's the full config I'm using to test this:
{
"compilerOptions": {
"baseUrl": ".",
"paths": {
"https://threejs.org/build/three.module.js": ["node_modules/@types/three"]
},
"esModuleInterop": true,
"exactOptionalPropertyTypes": true,
"isolatedModules": true,
"lib": [
"esnext",
"dom",
"dom.iterable"
],
"module": "esnext",
"moduleResolution": "node",
"noUncheckedIndexedAccess": true,
"outDir": "dist",
"strict": true,
"target": "esnext",
"useUnknownInCatchVariables": true
},
"include": [
"./src/**/*"
]
}
Now, you'll have the correct types for THREE in the modules where it is imported using the specifier "https://threejs.org/build/three.module.js". For example, when I type THREE.Mesh, TypeScript IntelliSense shows me that it's this type:
class Mesh<TGeometry extends THREE.BufferGeometry = THREE.BufferGeometry, TMaterial extends THREE.Material | THREE.Material[] = THREE.Material | THREE.Material[]>
Here's the example module in my test:
./src/index.ts:
import * as THREE from 'https://threejs.org/build/three.module.js';
console.log(THREE);
Now, when you compile your project using tsc, you'll get this output, which is a valid ECMAScript module and will use the "three" module imported from the hosted URL:
./dist/index.js:
import * as THREE from 'https://threejs.org/build/three.module.js';
console.log(THREE);
CodePudding user response:
Package installed with NPM are usually located in the node_modules folder. This mean you could access the library via it's relative path:
import * as THREE from './node_modules/tree/build/three.module.js';

