How to declare reference to an existing namespace which is available from JavaScript bundle at runtime
Asked Answered
A

3

1

I am writing a plugin for existing JavaScript app - Forge Autodesk.Viewing

After version 6 they have included THREE.js inside of their app bundle.

Right now I'm able to use it with my plugin like this:

declare var THREE:any; 

but I lose all types, so I install three.js by:

npm install --save three

I'm able to use THREE, and import it, but I don't need to Import it as I already have it in my main app. What I need to do is to reference types, so I tried to do something like this:

    declare var THREE:THREE;
//Cannot use namespace 'THREE' as a type.

Then I tried to:

/// <reference types='three' /> which works fine, but:

        const planes:THREE.Plane[] = []; //this line is okey

        planes.push(new THREE.Plane()); //but this says
        
        //'THREE' refers to a UMD global, 
        // but the current file is a module. 
        // Consider adding an import instead.

Tsc insists that we should import it:

import * as THREE from 'three'; 

It compiles without any issues, but when I launch the app it crash, because it's trying to get one more instance of THREE.js, which I do not provide because I have it inside main app.

How to declare the correct reference and keep types to an namespace which is available at main JavaScript application?

Asepsis answered 6/10, 2019 at 21:14 Comment(0)
A
0

If you have issue such as:

'THREE' refers to a UMD global, but the current file is a module. Consider adding an import instead.

(about UMD)

You may try to use option in tsconfig.json:

"compilerOptions": {
    "allowUmdGlobalAccess": true,

(about config options)

This will give compiler access to UMD global, so you do not need to import or reference such modules in that case.

And it's exact the case with three.js They alredy add THREE namespace as module to UMD global scope. So if you need to include this module you should import. If you want only reference you could use this option. If typescript doesn't recognize this option in config just update your typescript.

npm install typescript

Thank you dear SalientBrain and dear Petr Broz for your attention and help.

Asepsis answered 16/10, 2019 at 13:34 Comment(0)
M
0

Ypu need to import THREE module: Like this:

import * as THREE from 'three'; // or import THREE from 'three';

or

var THREE = require('Three').

and use webpack or other module loader (!)

If you want to manually include THREEJS distribution file and use TS bindings (type definitions) without modules (not recommended) - you can include Three.d.ts file to your project (with other THREEJS d.ts files) and use it with three slashes ref. For example:

/// <reference path="..\..\node_modules\@types\three\index.d.ts" />

Note: don't import THREE namespace with "import" or "require" in this case.

Merlenemerlin answered 7/10, 2019 at 10:49 Comment(1)
As I said - it doesn't valid. I already have THREE in main application. I do not need to include it inside my extension. Only types required.Asepsis
F
0

There's a TypeScript definition file (.d.ts) for Forge Viewer that you should be able to use together with a THREE.js definition file: https://forge.autodesk.com/blog/typescript-definitions-forge-viewer-and-nodejs-client-sdk-now-available.

Fullerton answered 7/10, 2019 at 14:59 Comment(2)
If you read article which you referes, you might notice that it's require to install @types/three. But this types is obsolete and included in 'three' from this june. And as I write I have these types. What I need is to reference THREE namespace.Asepsis
I'm aware of that. However, Forge Viewer is based on an old version of three.js (I believe it's R71) which does not include the TypeScript definitions yet. That's why you'd have to bring the types in separately using something like @types/three.Fullerton
A
0

If you have issue such as:

'THREE' refers to a UMD global, but the current file is a module. Consider adding an import instead.

(about UMD)

You may try to use option in tsconfig.json:

"compilerOptions": {
    "allowUmdGlobalAccess": true,

(about config options)

This will give compiler access to UMD global, so you do not need to import or reference such modules in that case.

And it's exact the case with three.js They alredy add THREE namespace as module to UMD global scope. So if you need to include this module you should import. If you want only reference you could use this option. If typescript doesn't recognize this option in config just update your typescript.

npm install typescript

Thank you dear SalientBrain and dear Petr Broz for your attention and help.

Asepsis answered 16/10, 2019 at 13:34 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.