How to import a Three.js loader into an Angular 6 project












4















I want to extend the type definitions imported into an ng6 project using Three.js (@types/three/index) with a set of functions that will be directly attached to the same "namespace". Something like: THREE.myFunction(). I don't want to declare THREE as any to suppress the type checking and the linter, and I guess that it would be possible to wrap a vanilla JS function that extend THREE using a TS class/function and then taking advantage of typings.d.ts.



Importing a loader



First of all, I would like to import a THREE.js loader into my project, and that's normally defined a vanilla function that extends THREE.



I'm trying to import the BinaryLoader into a ng service and I'm not sure about how to do it in the right way.



What I have done so far:




  1. npm install three --save

  2. npm install @types/three --save-dev

  3. import * as THREE from 'three';

  4. add the BinaryLoader to the new angular.json scripts array


angular.json



        "scripts": [
"./node_modules/three/examples/js/loaders/BinaryLoader.js"
]


So far so good, but now I need to create a binary loader:



import * as THREE from 'three';
// import { BinaryLoader } from 'three';
// import 'three/examples/js/loaders/BinaryLoader';

export class ThreeManagerService {
const loader = new THREE.BinaryLoader();
...


and I have to find the way to add the BinaryLoader to @types/three/index somehow. In that way I should be able to extend the type definitions in order to be able to create a new type THREE.BinaryLoader. Is it possible to do something like that?



The warning I got is:




WARNING in ./src/app/shared/three-manager.service.ts
24:25-43 "export 'BinaryLoader' (imported as 'THREE') was not found in 'three'




Silencing Type warnings and the TS transpiler



A workaround to get rid of the warnings and the error might be something like that:



import * as THREEJS from 'three';
declare const THREE: any;

export class ThreeManagerService {
const loader = new THREE.BinaryLoader();


the fact is that I consider this workaround a very ugly "fix". I would like to use the type system as much as possible.



EDIT: Get examples to play nice with Intellisense & Typescript



While waiting for a complete rewriting of the examples to be compatible with the ES6 modules and namespaces it could be possible to define a local module that exposes and augments the global, in /src/node_modules/three-extras/index.ts:



import * as THREE from 'three';

declare global {
interface Window {
THREE: typeof THREE;
}
}

window.THREE = THREE;

require('three/examples/js/controls/OrbitControls');
require('three/examples/js/loaders/GLTFLoader');


via: https://github.com/mrdoob/three.js/issues/9562#issuecomment-386522819



Related and useful SO answers:




  • https://stackoverflow.com/a/42602169/1977778

  • https://stackoverflow.com/a/42623509/1977778










share|improve this question

























  • Are you sure BinaryLoader is defined inside three.js file? I don't think so

    – HariV
    May 8 '18 at 9:17













  • @HariV yes, this loader, like many others, is part of the three.js library and it has been defined as an "example". Actually, there's an ongoing discussion about the fact that many scripts defined as simple ES5 scripts haven't been modularised on this ticket of the Three.js Github repository.

    – sentenza
    May 8 '18 at 13:54













  • After a lot of reading I found this comment particularly useful. Apparently, there's a an ES6-compliant porting of Three.js named three-full. So, it should be possible to use it to load the loaders or controls as modules. Hooray!

    – sentenza
    May 8 '18 at 14:09
















4















I want to extend the type definitions imported into an ng6 project using Three.js (@types/three/index) with a set of functions that will be directly attached to the same "namespace". Something like: THREE.myFunction(). I don't want to declare THREE as any to suppress the type checking and the linter, and I guess that it would be possible to wrap a vanilla JS function that extend THREE using a TS class/function and then taking advantage of typings.d.ts.



Importing a loader



First of all, I would like to import a THREE.js loader into my project, and that's normally defined a vanilla function that extends THREE.



I'm trying to import the BinaryLoader into a ng service and I'm not sure about how to do it in the right way.



What I have done so far:




  1. npm install three --save

  2. npm install @types/three --save-dev

  3. import * as THREE from 'three';

  4. add the BinaryLoader to the new angular.json scripts array


angular.json



        "scripts": [
"./node_modules/three/examples/js/loaders/BinaryLoader.js"
]


So far so good, but now I need to create a binary loader:



import * as THREE from 'three';
// import { BinaryLoader } from 'three';
// import 'three/examples/js/loaders/BinaryLoader';

export class ThreeManagerService {
const loader = new THREE.BinaryLoader();
...


and I have to find the way to add the BinaryLoader to @types/three/index somehow. In that way I should be able to extend the type definitions in order to be able to create a new type THREE.BinaryLoader. Is it possible to do something like that?



The warning I got is:




WARNING in ./src/app/shared/three-manager.service.ts
24:25-43 "export 'BinaryLoader' (imported as 'THREE') was not found in 'three'




Silencing Type warnings and the TS transpiler



A workaround to get rid of the warnings and the error might be something like that:



import * as THREEJS from 'three';
declare const THREE: any;

export class ThreeManagerService {
const loader = new THREE.BinaryLoader();


the fact is that I consider this workaround a very ugly "fix". I would like to use the type system as much as possible.



EDIT: Get examples to play nice with Intellisense & Typescript



While waiting for a complete rewriting of the examples to be compatible with the ES6 modules and namespaces it could be possible to define a local module that exposes and augments the global, in /src/node_modules/three-extras/index.ts:



import * as THREE from 'three';

declare global {
interface Window {
THREE: typeof THREE;
}
}

window.THREE = THREE;

require('three/examples/js/controls/OrbitControls');
require('three/examples/js/loaders/GLTFLoader');


via: https://github.com/mrdoob/three.js/issues/9562#issuecomment-386522819



Related and useful SO answers:




  • https://stackoverflow.com/a/42602169/1977778

  • https://stackoverflow.com/a/42623509/1977778










share|improve this question

























  • Are you sure BinaryLoader is defined inside three.js file? I don't think so

    – HariV
    May 8 '18 at 9:17













  • @HariV yes, this loader, like many others, is part of the three.js library and it has been defined as an "example". Actually, there's an ongoing discussion about the fact that many scripts defined as simple ES5 scripts haven't been modularised on this ticket of the Three.js Github repository.

    – sentenza
    May 8 '18 at 13:54













  • After a lot of reading I found this comment particularly useful. Apparently, there's a an ES6-compliant porting of Three.js named three-full. So, it should be possible to use it to load the loaders or controls as modules. Hooray!

    – sentenza
    May 8 '18 at 14:09














4












4








4








I want to extend the type definitions imported into an ng6 project using Three.js (@types/three/index) with a set of functions that will be directly attached to the same "namespace". Something like: THREE.myFunction(). I don't want to declare THREE as any to suppress the type checking and the linter, and I guess that it would be possible to wrap a vanilla JS function that extend THREE using a TS class/function and then taking advantage of typings.d.ts.



Importing a loader



First of all, I would like to import a THREE.js loader into my project, and that's normally defined a vanilla function that extends THREE.



I'm trying to import the BinaryLoader into a ng service and I'm not sure about how to do it in the right way.



What I have done so far:




  1. npm install three --save

  2. npm install @types/three --save-dev

  3. import * as THREE from 'three';

  4. add the BinaryLoader to the new angular.json scripts array


angular.json



        "scripts": [
"./node_modules/three/examples/js/loaders/BinaryLoader.js"
]


So far so good, but now I need to create a binary loader:



import * as THREE from 'three';
// import { BinaryLoader } from 'three';
// import 'three/examples/js/loaders/BinaryLoader';

export class ThreeManagerService {
const loader = new THREE.BinaryLoader();
...


and I have to find the way to add the BinaryLoader to @types/three/index somehow. In that way I should be able to extend the type definitions in order to be able to create a new type THREE.BinaryLoader. Is it possible to do something like that?



The warning I got is:




WARNING in ./src/app/shared/three-manager.service.ts
24:25-43 "export 'BinaryLoader' (imported as 'THREE') was not found in 'three'




Silencing Type warnings and the TS transpiler



A workaround to get rid of the warnings and the error might be something like that:



import * as THREEJS from 'three';
declare const THREE: any;

export class ThreeManagerService {
const loader = new THREE.BinaryLoader();


the fact is that I consider this workaround a very ugly "fix". I would like to use the type system as much as possible.



EDIT: Get examples to play nice with Intellisense & Typescript



While waiting for a complete rewriting of the examples to be compatible with the ES6 modules and namespaces it could be possible to define a local module that exposes and augments the global, in /src/node_modules/three-extras/index.ts:



import * as THREE from 'three';

declare global {
interface Window {
THREE: typeof THREE;
}
}

window.THREE = THREE;

require('three/examples/js/controls/OrbitControls');
require('three/examples/js/loaders/GLTFLoader');


via: https://github.com/mrdoob/three.js/issues/9562#issuecomment-386522819



Related and useful SO answers:




  • https://stackoverflow.com/a/42602169/1977778

  • https://stackoverflow.com/a/42623509/1977778










share|improve this question
















I want to extend the type definitions imported into an ng6 project using Three.js (@types/three/index) with a set of functions that will be directly attached to the same "namespace". Something like: THREE.myFunction(). I don't want to declare THREE as any to suppress the type checking and the linter, and I guess that it would be possible to wrap a vanilla JS function that extend THREE using a TS class/function and then taking advantage of typings.d.ts.



Importing a loader



First of all, I would like to import a THREE.js loader into my project, and that's normally defined a vanilla function that extends THREE.



I'm trying to import the BinaryLoader into a ng service and I'm not sure about how to do it in the right way.



What I have done so far:




  1. npm install three --save

  2. npm install @types/three --save-dev

  3. import * as THREE from 'three';

  4. add the BinaryLoader to the new angular.json scripts array


angular.json



        "scripts": [
"./node_modules/three/examples/js/loaders/BinaryLoader.js"
]


So far so good, but now I need to create a binary loader:



import * as THREE from 'three';
// import { BinaryLoader } from 'three';
// import 'three/examples/js/loaders/BinaryLoader';

export class ThreeManagerService {
const loader = new THREE.BinaryLoader();
...


and I have to find the way to add the BinaryLoader to @types/three/index somehow. In that way I should be able to extend the type definitions in order to be able to create a new type THREE.BinaryLoader. Is it possible to do something like that?



The warning I got is:




WARNING in ./src/app/shared/three-manager.service.ts
24:25-43 "export 'BinaryLoader' (imported as 'THREE') was not found in 'three'




Silencing Type warnings and the TS transpiler



A workaround to get rid of the warnings and the error might be something like that:



import * as THREEJS from 'three';
declare const THREE: any;

export class ThreeManagerService {
const loader = new THREE.BinaryLoader();


the fact is that I consider this workaround a very ugly "fix". I would like to use the type system as much as possible.



EDIT: Get examples to play nice with Intellisense & Typescript



While waiting for a complete rewriting of the examples to be compatible with the ES6 modules and namespaces it could be possible to define a local module that exposes and augments the global, in /src/node_modules/three-extras/index.ts:



import * as THREE from 'three';

declare global {
interface Window {
THREE: typeof THREE;
}
}

window.THREE = THREE;

require('three/examples/js/controls/OrbitControls');
require('three/examples/js/loaders/GLTFLoader');


via: https://github.com/mrdoob/three.js/issues/9562#issuecomment-386522819



Related and useful SO answers:




  • https://stackoverflow.com/a/42602169/1977778

  • https://stackoverflow.com/a/42623509/1977778







angular three.js angular-cli angular6






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited May 8 '18 at 14:55







sentenza

















asked May 6 '18 at 11:25









sentenzasentenza

7051735




7051735













  • Are you sure BinaryLoader is defined inside three.js file? I don't think so

    – HariV
    May 8 '18 at 9:17













  • @HariV yes, this loader, like many others, is part of the three.js library and it has been defined as an "example". Actually, there's an ongoing discussion about the fact that many scripts defined as simple ES5 scripts haven't been modularised on this ticket of the Three.js Github repository.

    – sentenza
    May 8 '18 at 13:54













  • After a lot of reading I found this comment particularly useful. Apparently, there's a an ES6-compliant porting of Three.js named three-full. So, it should be possible to use it to load the loaders or controls as modules. Hooray!

    – sentenza
    May 8 '18 at 14:09



















  • Are you sure BinaryLoader is defined inside three.js file? I don't think so

    – HariV
    May 8 '18 at 9:17













  • @HariV yes, this loader, like many others, is part of the three.js library and it has been defined as an "example". Actually, there's an ongoing discussion about the fact that many scripts defined as simple ES5 scripts haven't been modularised on this ticket of the Three.js Github repository.

    – sentenza
    May 8 '18 at 13:54













  • After a lot of reading I found this comment particularly useful. Apparently, there's a an ES6-compliant porting of Three.js named three-full. So, it should be possible to use it to load the loaders or controls as modules. Hooray!

    – sentenza
    May 8 '18 at 14:09

















Are you sure BinaryLoader is defined inside three.js file? I don't think so

– HariV
May 8 '18 at 9:17







Are you sure BinaryLoader is defined inside three.js file? I don't think so

– HariV
May 8 '18 at 9:17















@HariV yes, this loader, like many others, is part of the three.js library and it has been defined as an "example". Actually, there's an ongoing discussion about the fact that many scripts defined as simple ES5 scripts haven't been modularised on this ticket of the Three.js Github repository.

– sentenza
May 8 '18 at 13:54







@HariV yes, this loader, like many others, is part of the three.js library and it has been defined as an "example". Actually, there's an ongoing discussion about the fact that many scripts defined as simple ES5 scripts haven't been modularised on this ticket of the Three.js Github repository.

– sentenza
May 8 '18 at 13:54















After a lot of reading I found this comment particularly useful. Apparently, there's a an ES6-compliant porting of Three.js named three-full. So, it should be possible to use it to load the loaders or controls as modules. Hooray!

– sentenza
May 8 '18 at 14:09





After a lot of reading I found this comment particularly useful. Apparently, there's a an ES6-compliant porting of Three.js named three-full. So, it should be possible to use it to load the loaders or controls as modules. Hooray!

– sentenza
May 8 '18 at 14:09












2 Answers
2






active

oldest

votes


















3














I've finally reached two working solutions (=> workarounds to be precise).



Using Webpack's imports-loader




[...] import-loader is a Webpack plugin allows you to inject a global variable into your module's scope. So the global (!) namespace of your execution context still remains completely clean, but during "compilation", Webpack will be able to figure out where to lookup the binding for a module that only comes with a global variable.




Via this three.js ticket



import "imports?THREE=three!loaders/BinaryLoader";


Using this import we tell Webpack to use THREE as a global variable defined by the npm module 'three' and the BinaryLoader wont be binded to any variable.



Use three-full to provide the THREE namespace



The project three-full extends the namespace defined by the standard three.js library adding several "examples" like loaders and controls. Using it instead of the classical three npm package it will be possible to have full support to ES6 namespaces for the most common and useful classes that usually are part of the great majority of those projects based on three.js.



npm install --save three-full


And then you can import the entire namespace:



import * as THREE from 'three-full';
...
const loader = new THREE.ColladaLoader();





share|improve this answer
























  • See also stackoverflow.com/a/36324615/1977778

    – sentenza
    May 13 '18 at 9:20



















0














How using a little helper library, i'm looking to do the same - I found this one: https://www.npmjs.com/package/ng-three






share|improve this answer























    Your Answer






    StackExchange.ifUsing("editor", function () {
    StackExchange.using("externalEditor", function () {
    StackExchange.using("snippets", function () {
    StackExchange.snippets.init();
    });
    });
    }, "code-snippets");

    StackExchange.ready(function() {
    var channelOptions = {
    tags: "".split(" "),
    id: "1"
    };
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function() {
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled) {
    StackExchange.using("snippets", function() {
    createEditor();
    });
    }
    else {
    createEditor();
    }
    });

    function createEditor() {
    StackExchange.prepareEditor({
    heartbeatType: 'answer',
    autoActivateHeartbeat: false,
    convertImagesToLinks: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    imageUploader: {
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    },
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    });


    }
    });














    draft saved

    draft discarded


















    StackExchange.ready(
    function () {
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f50199133%2fhow-to-import-a-three-js-loader-into-an-angular-6-project%23new-answer', 'question_page');
    }
    );

    Post as a guest















    Required, but never shown

























    2 Answers
    2






    active

    oldest

    votes








    2 Answers
    2






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    3














    I've finally reached two working solutions (=> workarounds to be precise).



    Using Webpack's imports-loader




    [...] import-loader is a Webpack plugin allows you to inject a global variable into your module's scope. So the global (!) namespace of your execution context still remains completely clean, but during "compilation", Webpack will be able to figure out where to lookup the binding for a module that only comes with a global variable.




    Via this three.js ticket



    import "imports?THREE=three!loaders/BinaryLoader";


    Using this import we tell Webpack to use THREE as a global variable defined by the npm module 'three' and the BinaryLoader wont be binded to any variable.



    Use three-full to provide the THREE namespace



    The project three-full extends the namespace defined by the standard three.js library adding several "examples" like loaders and controls. Using it instead of the classical three npm package it will be possible to have full support to ES6 namespaces for the most common and useful classes that usually are part of the great majority of those projects based on three.js.



    npm install --save three-full


    And then you can import the entire namespace:



    import * as THREE from 'three-full';
    ...
    const loader = new THREE.ColladaLoader();





    share|improve this answer
























    • See also stackoverflow.com/a/36324615/1977778

      – sentenza
      May 13 '18 at 9:20
















    3














    I've finally reached two working solutions (=> workarounds to be precise).



    Using Webpack's imports-loader




    [...] import-loader is a Webpack plugin allows you to inject a global variable into your module's scope. So the global (!) namespace of your execution context still remains completely clean, but during "compilation", Webpack will be able to figure out where to lookup the binding for a module that only comes with a global variable.




    Via this three.js ticket



    import "imports?THREE=three!loaders/BinaryLoader";


    Using this import we tell Webpack to use THREE as a global variable defined by the npm module 'three' and the BinaryLoader wont be binded to any variable.



    Use three-full to provide the THREE namespace



    The project three-full extends the namespace defined by the standard three.js library adding several "examples" like loaders and controls. Using it instead of the classical three npm package it will be possible to have full support to ES6 namespaces for the most common and useful classes that usually are part of the great majority of those projects based on three.js.



    npm install --save three-full


    And then you can import the entire namespace:



    import * as THREE from 'three-full';
    ...
    const loader = new THREE.ColladaLoader();





    share|improve this answer
























    • See also stackoverflow.com/a/36324615/1977778

      – sentenza
      May 13 '18 at 9:20














    3












    3








    3







    I've finally reached two working solutions (=> workarounds to be precise).



    Using Webpack's imports-loader




    [...] import-loader is a Webpack plugin allows you to inject a global variable into your module's scope. So the global (!) namespace of your execution context still remains completely clean, but during "compilation", Webpack will be able to figure out where to lookup the binding for a module that only comes with a global variable.




    Via this three.js ticket



    import "imports?THREE=three!loaders/BinaryLoader";


    Using this import we tell Webpack to use THREE as a global variable defined by the npm module 'three' and the BinaryLoader wont be binded to any variable.



    Use three-full to provide the THREE namespace



    The project three-full extends the namespace defined by the standard three.js library adding several "examples" like loaders and controls. Using it instead of the classical three npm package it will be possible to have full support to ES6 namespaces for the most common and useful classes that usually are part of the great majority of those projects based on three.js.



    npm install --save three-full


    And then you can import the entire namespace:



    import * as THREE from 'three-full';
    ...
    const loader = new THREE.ColladaLoader();





    share|improve this answer













    I've finally reached two working solutions (=> workarounds to be precise).



    Using Webpack's imports-loader




    [...] import-loader is a Webpack plugin allows you to inject a global variable into your module's scope. So the global (!) namespace of your execution context still remains completely clean, but during "compilation", Webpack will be able to figure out where to lookup the binding for a module that only comes with a global variable.




    Via this three.js ticket



    import "imports?THREE=three!loaders/BinaryLoader";


    Using this import we tell Webpack to use THREE as a global variable defined by the npm module 'three' and the BinaryLoader wont be binded to any variable.



    Use three-full to provide the THREE namespace



    The project three-full extends the namespace defined by the standard three.js library adding several "examples" like loaders and controls. Using it instead of the classical three npm package it will be possible to have full support to ES6 namespaces for the most common and useful classes that usually are part of the great majority of those projects based on three.js.



    npm install --save three-full


    And then you can import the entire namespace:



    import * as THREE from 'three-full';
    ...
    const loader = new THREE.ColladaLoader();






    share|improve this answer












    share|improve this answer



    share|improve this answer










    answered May 9 '18 at 13:40









    sentenzasentenza

    7051735




    7051735













    • See also stackoverflow.com/a/36324615/1977778

      – sentenza
      May 13 '18 at 9:20



















    • See also stackoverflow.com/a/36324615/1977778

      – sentenza
      May 13 '18 at 9:20

















    See also stackoverflow.com/a/36324615/1977778

    – sentenza
    May 13 '18 at 9:20





    See also stackoverflow.com/a/36324615/1977778

    – sentenza
    May 13 '18 at 9:20













    0














    How using a little helper library, i'm looking to do the same - I found this one: https://www.npmjs.com/package/ng-three






    share|improve this answer




























      0














      How using a little helper library, i'm looking to do the same - I found this one: https://www.npmjs.com/package/ng-three






      share|improve this answer


























        0












        0








        0







        How using a little helper library, i'm looking to do the same - I found this one: https://www.npmjs.com/package/ng-three






        share|improve this answer













        How using a little helper library, i'm looking to do the same - I found this one: https://www.npmjs.com/package/ng-three







        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered Nov 26 '18 at 22:06









        Devin McQueeneyDevin McQueeney

        6601726




        6601726






























            draft saved

            draft discarded




















































            Thanks for contributing an answer to Stack Overflow!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid



            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.


            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f50199133%2fhow-to-import-a-three-js-loader-into-an-angular-6-project%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            Popular posts from this blog

            Lallio

            Unable to find Lightning Node

            Futebolista