1.4.0 升级 1.4.2 后提示TypeError: Cannot set property 'protobuf' of undefined

由于项目需求引入pomelo,包含在pomelo-client.js,protobuf.js,protocol.js 在1.4.0中没有问题,升级1.4.2后,在没有删除自动生成的library,local,temp时也是没问题的,然而,删除重新打开项目后就会报TypeError错误,具体信息如下

TypeError: Cannot set property ‘protobuf’ of undefined
at Object.require.protobuf: “})(typeof(window) == “undefined” ? module.exports : (this.protobuf = {}), this)” (assets/pomelo/protobuf.js:37:1)
at s (file:///E:/work/CslEleven/test/library/bundle.project.js?001:1:262)
at file:///E:/work/CslEleven/test/library/bundle.project.js?001:1:313
at Object.require.pomelo-client.events (assets/pomelo/pomelo-client.js:1)
at s (file:///E:/work/CslEleven/test/library/bundle.project.js?001:1:262)
at e (file:///E:/work/CslEleven/test/library/bundle.project.js?001:1:433)
at file:///E:/work/CslEleven/test/library/bundle.project.js?001:1:451

对比1.4.0与1.4.2两个版本的temp和library,发现在1.4.2中 pomelo的js文件中“this” 被替换成了“undefined”,从而导致错误
源代码与1.4.0:
(typeof window == “undefined” ? module.exports : this.protobuf = {}, this);
1.4.2:
(typeof window == “undefined” ? module.exports : undefined.protobuf = {}, undefined);

现在手动把 temp 和 library 中 bundle.project.js,中错误的 “undefined” 改回 “this”,项目已正常,但是总不能这么玩吧,官方大神给看看吧

导入为插件了吗?
如果导入了,麻烦发个 demo 上来看看。

嗯,大神,是导入了pomelo插件,在1.3.3,1.4.0都正常,1.4.2有问题,开发环境是windows。 test.zip (11.8 KB)

我打开你的项目,没看到你有导入为插件。
第三方库最好别直接放到项目里,也别 require。请参考 http://www.cocos.com/docs/creator/scripting/plugin-scripts.html
进行相关配置。

大神,问题是这个demo在1.3.3,1.4.0都正常,1.4.2有问题,打开就报错。我们一直在关注creator,项目在1.4.0开发已经快结束了,由于官方升级了1.4.2,我们就紧跟着脚步做了升级,就有了上面的问题。这次demo就写了一个脚本test.js,代码如下,也是在1.4.0正常,1.4.2有问题,导入插件也是有问题,麻烦大神给看看。test2.zip (1.6 KB):

(function (exports, global) {
    var Test = exports;

    Test.init = function (opts) {
    };

    Test.encode = function (key, msg) {
        return {};
    };

    Test.decode = function (key, msg) {
        return {};
    };

    // exports to support for components
    module.exports = Test;
    if (typeof (window) != "undefined") {
        window.test = Test;
    }

})(typeof (window) == "undefined" ? module.exports : (this.test = {}), this);

为什么 1.4 可以,不太清楚,可能是 1.4 的 browserify 有 bug
单就现在的版本来说,你这个脚本的写法有问题
如果要导入为插件,怎么会直接访问 module.exports?UMD 一般都要判断 module 的。
如果不导入为插件,脚本最外层怎么会有 this?这里不是浏览器,浏览器的 scope 才有 this。你要获取 global 的话,直接用 window 就好了。
也就是说你可以

(function (exports, global) {
    var Test = exports;

    Test.init = function (opts) {

    };

    Test.encode = function (key, msg) {
        return {};
    };

    Test.decode = function (key, msg) {
        return {};
    };

    // exports to support for components
    module.exports = Test;
    if (typeof (window) != "undefined") {
        window.test = Test;
    }

})(typeof (window) == "undefined" ? module.exports : (window.test = {}), window);

谢谢大神的回复,按你的修改确实没问题,js确实了解的不够深入,我们用的pomelo第三方库有大量的这样的用法

关于this,我还是在 1.4.0和1.4.2做了验证,新建了一个脚本 require test.js 并在test.js最后打印this的值,在1.4.2版本中this确实是undefined,但在1.4.0中this是Object,浏览器和模拟器调试都是同样的结果,具体原因我们也没能力去检查,会不会和browserify有关? 希望官方有余力时候,能检查一下,我们也想知道原因。

我们现在的做法是电脑上装了1.4.0,1.4.2两个版本的creator,删除工程自动生成文件及目录,先用1.4.0打开项目,然后再切换到1.4.2版本开发,目前没有什么问题

我个人觉得普通脚本的 scope 中 this 编译为 undefined 挺好的,能暴露出不少编写错误。我不打算改回 1.4 的 window,毕竟在脚本里写 this.foo = ‘bar’ 如果就会变成全局变量,也挺危险的,我不希望用户这样滥用。
你这里的问题是要用普通脚本模拟插件脚本的环境,自然各种膈应……

参考帖子 http://forum.cocos.com/t/protobuf-typeerror-cannot-read-property-navigator-of-undefined/45558

谢谢大神,已经GET到