Error encountered in Firefox: THREE.js throws a TypeError because 'global' is undefined

After attempting to integrate three.js into my code as a standalone script without using webpack, browserify or requirejs, I encountered an issue. My setup involves loading an external Angular app and extending it, but now I need my own version of THREE.js within the codebase.

Although the library gets loaded, the first line tries to set a variable 'global' which appears to be undefined. What could I be overlooking?


// edit:

I am utilizing a JavaScript API from another company. It's unclear whether they define the 'global' variable, but Three.js seems to rely on it even though I'm not using it in a node setup. In all the examples, it typically works as a drop-in script.

If I switch to the minified version, the error message changes to

TypeError: global is undefined *three.min.js:2:168

anonymous https://localhost:9000/scripts/three.min.js:2:168

anonymous https://localhost:9000/scripts/three.min.js:2:2*

This issue arises from the initial lines of the three.js file:

function (global, factory) {
  typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
  typeof define === 'function' && define.amd ? define(['exports'], factory) :
(factory((global.THREE = {}))); }(this, (function (exports) { 'use strict'; ...

//EDIT 2:

I have finally identified the cause of this error. When using gulp-babel and including scripts with that snippet at the top, Babel attempts to replace 'THIS' with the current context, which is - unsurprisingly - undefined. This results in Babel literally replacing 'this' with 'undefined'. Therefore, never run babel() on your final vendor files!

Answer №1

There is no issue with the portion of THREE.js you presented in your inquiry. By focusing solely on the problem at hand and removing the code related to CommonJS and AMD scenarios, it can be simplified to this:

(function (global, factory) {
  factory(global.THREE = {}); 
}(this, (function (exports) { 'use strict';
  // ...
})));

This pattern is quite common. The initial anonymous function is invoked with this as its first argument, setting global to the value of this within the global scope. When this snippet runs at the top level, this automatically adopts the value of the global object in the current environment. In Node.js, this object is referred to as global. To verify this, open a Node session and input:

global === this

You should receive true as output. In a browser context, the global object is typically named window. Open the developer console and type:

window === this

Again, you will observe true displayed. Therefore, the purpose of using this within the anonymous function is to acquire a reference to the global object regardless of the execution location. This method eliminates the need to differentiate between window, global, or any other possible global identifiers. It effectively passes this to the function, facilitating access to the global object. This approach is widely utilized and reliable.

Nevertheless, there are circumstances where this mechanism may fail to function correctly. For instance, if the code block mentioned earlier is enveloped within another function that enforces strict mode, then this would become undefined, rendering global also undefined. Consider this example:

(function() {
  "use strict";
  (function(global, factory) {
    console.log("XXX", global); // Output: "XXX undefined"
  }(this, (function(exports) {
    'use strict';
  })));
}());

At times, additional wrapping structures introduced by build processes or code loaders might disrupt the original functionality of the code.

Answer №2

When dealing with gulp, it can be quite tricky to make babel ignore specific files. One workaround for this issue is to simply replace this with window on line 5 of three.js:

(function (global, factory) {
  typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
  typeof define === 'function' && define.amd ? define(['exports'], factory) :
  (factory((global.THREE = {})));
}(window, (function (exports) { 'use strict';

Answer №3

Looking for a solution? Simply include this concise line of code at the top of your script, within the overarching scope:

if (typeof main === "undefined"){main=window;}

This will link the main object to the window object, where all global variables are stored in the browser environment.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Cloning jQuery with varied PHP array value

So, I have the given PHP values: PHP: <?php $names = array("Mike","Sean","Steve"); ?> <script type="text/javascript"> var name_data = <?php echo json_encode($names); ?>; </script> <div class="container"> <div cl ...

What is the best way to initiate the registration page through the @auth0/auth0-react library?

I've hit a roadblock in trying to automatically launch the sign-up (registration) page using @auth0/auth0-react. Previously, I would send mode which worked with auth0-js. So far, I have attempted the following without success: const { loginWithRedir ...

Navigating using Javascript library in Angular 2 framework

I am currently utilizing Parse, an external JS library, within Angular JS 2. Nevertheless, I am encountering issues when attempting to call the function gotoMain() from within a callback function of Parse. It appears that certain elements are not being l ...

Using node-native to authenticate in MongoDB is a surefire way to ensure the

I'm currently facing an issue while attempting to save a document in MongoDB within my Nodejitsu/MongoHQ application. Everything works perfectly locally, but the MongoHQ database requires authentication and it fails even with the correct user/password ...

What is the best way to invoke a function only once in typescript?

Struggling to implement TypeScript in React Native for fetching an API on screen load? I've been facing a tough time with it, especially when trying to call the function only once without using timeouts. Here's my current approach, but it's ...

The function of style.marginRight differs from that of style.marginLeft

One function aligns content to the left while the other doesn't align it to the right function openNavLeft() { document.getElementById("mySidenavLeft").style.width = "100vw"; document.getElementById("main").style.marginLeft = "100vw"; } function ...

Transforming seconds into years, months, weeks, days, hours, minutes, and seconds

Can anyone help me modify Andris’ solution from this post: Convert seconds to days, hours, minutes and seconds to also include years, months, and weeks? I am currently running this code: getDateStrings() { console.log(req_creation_date); const toda ...

Guide for Uploading, presenting, and storing images in a database column with the help of jQuery scripting language

What is the best method for uploading, displaying, and saving an image in a database using jQuery JavaScript with API calls? I am working with four fields in my database: 1. File ID 2. Filename 3. Filesize 4. Filepath ...

Steps to create a personalized material-ui element

I am looking to create a custom time duration component by modifying the TextField component. https://i.stack.imgur.com/fLsFs.png https://i.stack.imgur.com/SdpdH.png If anyone has any advice or assistance, it would be greatly appreciated. Thank you! ...

import JavaScript script from a NPM package installation

I am facing a challenge with my server where I do not have the ability to run npm due to lack of permissions, and only have access to Apache. Currently, I am in need of a JavaScript library that is typically deployed using npm, such as https://github.com/ ...

Tips for Preserving Texture Resolution in Three.js While Adjusting Mesh Scale

I'm currently immersed in a Three.js project that involves a mesh object adorned with a texture from a 64x64 PNG file. Dilemma: Whenever the dimensions of the mesh object are modified, the texture ends up being stretched in both height and width, re ...

Is there a way to bypass the default layout on app router in Next.js and implement our own custom page layout

Utilizing a default layout in layout.jsx, I passed all my other pages as children through props. In the page router, we typically configure the router path to specify which layout to use. However, in this new system, I am facing challenges with coding it. ...

Insert a new class within the container div

I am looking to insert a 'disabled' class within a parent div named 'anchorxx' https://i.sstatic.net/3KRMQ.png The disabled class div can be located anywhere within the anchorXX divs Is it achievable using jquery? I am unsure how to ...

What could be causing the computed property in Vue 2 component to not return the expected state?

I'm encountering an issue with my Vue component where it fails to load due to one of its computed properties being undefined: Error: Cannot read properties of undefined (reading 'map') Here is the snippet of the computed property causing ...

Retrieve the height data from a displacement map by utilizing Three.js

I have a question regarding obtaining the height value from a displacement map. The following code is used to create a visual surface: var myTexture = new THREE.ImageUtils.loadTexture("assets/surface.png"); var surfaceTexture = new THREE.I ...

Observable task queuing

Here's the scenario: In my application, the user can tap a button to trigger a task that takes 2 seconds to complete. I want to set up a queue to run these tasks one after another, in sequence. I am working with Ionic 3 and TypeScript. What would be ...

I'm receiving the error message "Fatal error: Call to a member function query() on a non-object," what could be causing this issue?

Need help with fixing an error on my private server realmeye. The error message I'm receiving is: Fatal error: Call to a member function query() on a non-object in /home/noxus/public_html/realmeye/index.php on line 112 =========================== ...

What could be causing my JavaScript loop to replace existing entries in my object?

Recently, I encountered an issue with an object being used in nodejs. Here is a snippet of the code: for(var i = 0; i < x.length; i++) { var sUser = x[i]; mUsers[sUser.userid] = CreateUser(sUser); ++mUsers.length; ...

The process of updating UseContext global state in React Native and ensuring that the change is reflected across all screens

Struggling with updating global state values using React useContext on different screens? Attempting to change theme color in the App, but changes only appear on the current screen and not carried over to others? Looking for assistance in resolving this ...

Exploring the use of leaflets within LitElement

I have been working on a project involving LitElement components and I am looking to incorporate Leaflet into it. However, I am encountering difficulties with displaying the map properly. After installing Leaflet through npm in my project, I created a clas ...