THREE.js TypeError:Firefox中未定义'global'

时间:2017-12-19 09:54:59

标签: javascript three.js requirejs babeljs commonjs

所以我尝试将threejs作为插入脚本包含在我的代码中。没有webpack,没有browserify,没有requirejs。只是一个简单的gulp / browsersync服务。 我加载一个外部角应用程序并扩展它。现在我需要在代码库中使用自己的THREEjs版本。

它被加载 - 但是在第一行它们尝试设置似乎没有定义的变量'global'。我错过了什么?

//编辑:

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

如果我使用缩小版本,则错误更改为

TypeError:global is undefined * 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()你的最终供应商文件!

3 个答案:

答案 0 :(得分:2)

您在问题中显示的THREE.js部分不是问题。如果我们只关注你一直存在的问题,并消除CommonJS和AMD案例的代码,那么归结为:

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

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

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';
  })));
}());

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

答案 1 :(得分:0)

由于在gulp中工作时“仅仅让babel忽略某些文件”绝非易事,因此针对该错误的快速而肮脏的解决方法是,在第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';

答案 2 :(得分:-1)

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

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

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