Uncaught SyntaxError: Unexpected token "import" - playcanvas-stable.min.js:6

Latests Editor versions all drop the same engine error on old TV (~2018)

Judging by the complaint about the import problem here, how can it be fixed? Maybe there are versions of the engine where no innovations were made here? Where do I get just this playcanvas-stable.min.js file of other engines?

case 2:
							return n = function(t) {
								var e = new URL(window.location.href);
								return e.pathname = t, e.search = "", e.toString()
							}, t.next = 5, Promise.all([import("" + n(i)).then((function(t) {
								return twgsl(i.replace(".js", ".wasm"))
							})), import("" + n(e)).then((function(t) {
								return t.default()
							}))]);
1 Like

You could get older version from here, for example: https://code.playcanvas.com/playcanvas-1.27.4.min.js

the possible version numbers can be found here: Releases · playcanvas/engine · GitHub

Just curious, if you can find out, what browser and version is that TV using?

1 Like

Thanks, so I should not expect that it can be fixed in future versions?

I forgot to say that the project is empty, a starting example. Here - https://playcanv.as/p/f6a62ee2/

This is not a browser, but a web application with the Chromium 53 web engine, if you believe the tables from LG - https://webostv.developer.lge.com/develop/specifications/web-api-and-web-engine

1 Like

After manually correcting this error, the loading screen appeared, but remained at 0 (no errors in the Console or Network)

Games from Explore that are on older engines have a visual problem, shader errors (asm.js and WebGL 1.0)

This game works without any errors - Pong - PLAYCANVAS

I would like to support 2018-2019 TVs, but the problem with eternal loading is also relevant for a TV with WebAssembly and WebGL 2.0 (probably Chromium M69) table from Samsung - https://developer.samsung.com/smarttv/develop/specifications/web-engine-specifications.html

I created an issue for this: Investigate compatibility issues with very old brosers · Issue #6011 · playcanvas/engine · GitHub

1 Like

Hey @robert.ua, the import code above is related to WebGPU instantiation, but that would only be supported on Chrome 113 and later, so I’m curious how you’re hitting that part. Can you share the error you’re getting?

LG TV
But when the code is manually replaced so that there are no errors, there is an eternal download without errors in the console (Loading screen with 0%)

image


“Import” problem appears in versions of chrome up to 62, but after manually fixing that I encountered the problem of eternal loading even without errors in the console, but when interacting with the canvas, errors are pouring in, maybe it will tell something?

Chrome versions from 63 to 72 have this loading problem without “import” problem.

Checked with Browserling

And when I move the mouse and click

Target platforms are TVs, their web engines are outdated at the time of model release and cannot be updated in the future (Samsung, LG).

The problem seems to have appeared in one of the PlayCanvas engine updates, because at least one game loaded and started - Pong - PLAYCANVAS

Can you please try and run this using debug version of the engine, the errors might be more useful. You’ll be also able to inspect the code in the debugger to see why this is failing.

I had a quick look with the debug engine before I run out of gos on the emulator. Looks like it dies without error somewhere in _initProgramLibrary in app.base

2 Likes

Got a Windows machine and downloaded Chromium 62. Looks like the first issue it hits is the use of Object.fromEntries that first hits here: https://github.com/playcanvas/engine/blob/main/src/scene/materials/standard-material-options-builder.js#L70

This wasn’t added tile v73 "fromEntries" | Can I use... Support tables for HTML5, CSS3, etc

1 Like

Looks like polyfiling that was pretty easy.

I’ve got Flappy Bird project working in Chrome 62 https://playcanvas.com/project/1187457/overview/bird-pre-62

  • I added a version of the debug engine with the import for WebGPU removed.
  • Disabled WebGL2 and clustered lighting in the project settings
  • Removed audio as they didn’t want to decode (not sure why)
  • Polyfilled Object.fromEntries

I also noticed that Ammo wouldn’t load due to some code in the ammo.wasm.js itself. That might be tricky to deal with depending on what APIs you need. If you need physics it may be easier to use Cannon.js instead https://playcanvas.com/project/793652/overview/cannonesjs-physics-integration

2 Likes

Just got Food Run working with sound using an older version of Ammo too https://playcanvas.com/project/1187223/overview/food-run-pre-62

:v:

The older version of Ammo won’t support all features from the PlayCanvas Engine but should cover most of the base functionality.

1 Like

Looks like the Object.fromEntires polyfill I’m using is not perfect and this may be better instead: index.js · master · Alfredo Mungo / js-polyfill-object.fromentries · GitLab

1 Like

Did I understand correctly that all this can be fixed with updates from PlayCanvas, if so - how often can updates of such a plan theoretically come out? Or will I still need to modify the build source files in the future?

Thanks a lot for the already provided quick and useful answers :wink:

I can’t speak for the team. I can imagine that supporting 6 year old browsers is not the highest priority for them so this may be fixed over time (if ever)

Realistically, in your position I would keep a fork of the engine that has your modifications in it including the polyfill, rely on using older versions of Ammo and disabling WebGL2.

It maybe possible to monkey patch or stub the functions that are causing issues thinking about it. I may spend sometime trying that tomorrow

1 Like

Played around with it a bit more. I’ve created a patch/polyfill file that correct does Object.fromEntries and now WebGL2 works. It also adds a stub for the import function.

This means that for now, you don’t have to build a custom version of the engine. You can use the one that the build ships with.

I also added a polyfill for promises so that the current version of Ammo used by the Editor can load too.

With this, you should be fine :crossed_fingers: for PlayCanvas to run on those TVs with minimal hacks.

My Food Run project fork has been updated: https://playcanvas.com/project/1187223/overview/food-run-pre-62

Patch file to be loaded before the engine:

/*
    Copyright 2018  Alfredo Mungo <alfredo.mungo@protonmail.ch>

    Permission is hereby granted, free of charge, to any person obtaining a copy
    of this software and associated documentation files (the "Software"), to
    deal in the Software without restriction, including without limitation the
    rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
    sell copies of the Software, and to permit persons to whom the Software is
    furnished to do so, subject to the following conditions:

    The above copyright notice and this permission notice shall be included in
    all copies or substantial portions of the Software.

    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
    AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
    IN THE SOFTWARE.
*/
if (!Object.fromEntries) {
  Object.defineProperty(Object, 'fromEntries', {
    value(entries) {
      if (!entries || !entries[Symbol.iterator]) { throw new Error('Object.fromEntries() requires a single iterable argument'); }

      const o = {};

      Object.keys(entries).forEach((key) => {
        const [k, v] = entries[key];

        o[k] = v;
      });

      return o;
    },
  });
}


if (!window.import) {
  window.import = function() {}
  console.log('Stubbing out import function');
}

// Copyright (c) 2014 Taylor Hakes
// Copyright (c) 2014 Forbes Lindesay

// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:

// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.

// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t():"function"==typeof define&&define.amd?define(t):t()}(0,function(){"use strict";function e(e){var t=this.constructor;return this.then(function(n){return t.resolve(e()).then(function(){return n})},function(n){return t.resolve(e()).then(function(){return t.reject(n)})})}function t(e){return new this(function(t,n){function r(e,n){if(n&&("object"==typeof n||"function"==typeof n)){var f=n.then;if("function"==typeof f)return void f.call(n,function(t){r(e,t)},function(n){o[e]={status:"rejected",reason:n},0==--i&&t(o)})}o[e]={status:"fulfilled",value:n},0==--i&&t(o)}if(!e||"undefined"==typeof e.length)return n(new TypeError(typeof e+" "+e+" is not iterable(cannot read property Symbol(Symbol.iterator))"));var o=Array.prototype.slice.call(e);if(0===o.length)return t([]);for(var i=o.length,f=0;o.length>f;f++)r(f,o[f])})}function n(e,t){this.name="AggregateError",this.errors=e,this.message=t||""}function r(e){var t=this;return new t(function(r,o){if(!e||"undefined"==typeof e.length)return o(new TypeError("Promise.any accepts an array"));var i=Array.prototype.slice.call(e);if(0===i.length)return o();for(var f=[],u=0;i.length>u;u++)try{t.resolve(i[u]).then(r)["catch"](function(e){f.push(e),f.length===i.length&&o(new n(f,"All promises were rejected"))})}catch(c){o(c)}})}function o(e){return!(!e||"undefined"==typeof e.length)}function i(){}function f(e){if(!(this instanceof f))throw new TypeError("Promises must be constructed via new");if("function"!=typeof e)throw new TypeError("not a function");this._state=0,this._handled=!1,this._value=undefined,this._deferreds=[],s(e,this)}function u(e,t){for(;3===e._state;)e=e._value;0!==e._state?(e._handled=!0,f._immediateFn(function(){var n=1===e._state?t.onFulfilled:t.onRejected;if(null!==n){var r;try{r=n(e._value)}catch(o){return void a(t.promise,o)}c(t.promise,r)}else(1===e._state?c:a)(t.promise,e._value)})):e._deferreds.push(t)}function c(e,t){try{if(t===e)throw new TypeError("A promise cannot be resolved with itself.");if(t&&("object"==typeof t||"function"==typeof t)){var n=t.then;if(t instanceof f)return e._state=3,e._value=t,void l(e);if("function"==typeof n)return void s(function(e,t){return function(){e.apply(t,arguments)}}(n,t),e)}e._state=1,e._value=t,l(e)}catch(r){a(e,r)}}function a(e,t){e._state=2,e._value=t,l(e)}function l(e){2===e._state&&0===e._deferreds.length&&f._immediateFn(function(){e._handled||f._unhandledRejectionFn(e._value)});for(var t=0,n=e._deferreds.length;n>t;t++)u(e,e._deferreds[t]);e._deferreds=null}function s(e,t){var n=!1;try{e(function(e){n||(n=!0,c(t,e))},function(e){n||(n=!0,a(t,e))})}catch(r){if(n)return;n=!0,a(t,r)}}n.prototype=Error.prototype;var d=setTimeout;f.prototype["catch"]=function(e){return this.then(null,e)},f.prototype.then=function(e,t){var n=new this.constructor(i);return u(this,new function(e,t,n){this.onFulfilled="function"==typeof e?e:null,this.onRejected="function"==typeof t?t:null,this.promise=n}(e,t,n)),n},f.prototype["finally"]=e,f.all=function(e){return new f(function(t,n){function r(e,o){try{if(o&&("object"==typeof o||"function"==typeof o)){var u=o.then;if("function"==typeof u)return void u.call(o,function(t){r(e,t)},n)}i[e]=o,0==--f&&t(i)}catch(c){n(c)}}if(!o(e))return n(new TypeError("Promise.all accepts an array"));var i=Array.prototype.slice.call(e);if(0===i.length)return t([]);for(var f=i.length,u=0;i.length>u;u++)r(u,i[u])})},f.any=r,f.allSettled=t,f.resolve=function(e){return e&&"object"==typeof e&&e.constructor===f?e:new f(function(t){t(e)})},f.reject=function(e){return new f(function(t,n){n(e)})},f.race=function(e){return new f(function(t,n){if(!o(e))return n(new TypeError("Promise.race accepts an array"));for(var r=0,i=e.length;i>r;r++)f.resolve(e[r]).then(t,n)})},f._immediateFn="function"==typeof setImmediate&&function(e){setImmediate(e)}||function(e){d(e,0)},f._unhandledRejectionFn=function(e){void 0!==console&&console&&console.warn("Possible Unhandled Promise Rejection:",e)};var p=function(){if("undefined"!=typeof self)return self;if("undefined"!=typeof window)return window;if("undefined"!=typeof global)return global;throw Error("unable to locate global object")}();"function"!=typeof p.Promise?p.Promise=f:(p.Promise.prototype["finally"]||(p.Promise.prototype["finally"]=e),p.Promise.allSettled||(p.Promise.allSettled=t),p.Promise.any||(p.Promise.any=r))});

1 Like

Ah crap, turns out Chrome 63 loads the project fine but not Chrome 62 :thinking:

1 Like

Yes, here are the logs from the TV

Hmm, looks like pre v62, you can’t stub out the import statement / function :thinking: It’s back to using a custom version of the engine then unfortunately for now