THREE.js TypeError: 'global' is undefined in Firefox

THREE.js TypeError: 'global' is undefined in Firefox

所以我尝试将 threejs 作为插入脚本包含到我的代码中。没有 webpack,没有 browserify,没有 requirejs。只是一个简单的 gulp/browsersync 发球。 我加载了一个外部 angular 应用程序并对其进行了扩展。现在我需要在代码库中拥有自己的三个版本。

它已加载 - 但就在第一行,他们试图设置似乎未定义的变量 'global'。我错过了什么?


// 编辑:

我正在使用另一家公司的 js api。我不知道他们是否设置了 'global' var,但 Threejs 肯定会尝试使用 var 'global' 尽管我没有在节点设置中使用它。但在所有示例中,它只是作为一个插入式脚本使用。

如果我使用缩小版,错误会变为

类型错误:全局未定义 *three.min.js:2:168

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

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

这源自 three.js 文件的以下第一行:

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'; ...

//编辑 2:

我终于找到了导致这一切的错误。 如果你正在使用 gulp-babel 并在顶部包含带有该片段的脚本,babel 会尝试用当前上下文替换 THIS,当然,这是未定义的。这就是为什么 bable 从字面上用 undefined 替换它。所以:永远不要 babel() 你的最终供应商文件!

这是你需要的吗?只需在全局范围内的代码的最前面添加这一行:

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

这会将 global 对象引用到 window 对象,这是包含浏览器中所有全局变量的对象。

你在问题中显示的THREE.js部分没有问题。如果我们只关注您遇到的问题,并删除 CommonJS 和 AMD 案例的代码,则归结为:

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

这是一个常见的模式。请注意,第一个匿名函数是使用 this 作为第一个参数调用的。因此 global 设置为 this 在全局 space 中的值。如果上面的代码在顶级执行上下文中执行,那么 this 将自动具有您 运行 代码所在环境的全局对象的值。在 Node 中,该对象被命名为 global。所以打开一个节点会话并输入:

global === this

你会得到 true。在浏览器中,全局对象被命名为 window。在调试中打开控制台并输入:

window === this

你会得到 true。所以带有匿名函数的代码片段所做的是它使用 this 获取对全局对象的引用 而不管代码在何处执行 。它不必检查 window 是否存在或 global 是否存在,或 self 或其他任何东西。相反,它只是将 this 传递给匿名函数,并通过这种方式自动获取对全局对象的引用。这种方法没有错。它非常常见并且通常有效。

但是,可能会阻止代码正常工作。例如,如果上面的代码包含在另一个函数中并且该函数使用 "use strict",那么 this 将是未定义的,并且 global 也将是未定义的。这是一个例子:

(function() {
  "use strict";
  (function(global, factory) {
    console.log("XXX", global); // You'll get "XXX undefined" here
  }(this, (function(exports) {
    'use strict';
  })));
}());

有时,构建过程或代码加载工具会添加此类包装代码,然后它们会弄乱原始代码。

因为在 gulp 中工作时 "just getting babel to ignore certain files" 绝不是微不足道的,一个快速而肮脏的修复方法是在 5 日将 thiswindow 交换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';