[ALOY-1734] JS files imported in "alloy.js" don't have access to Alloy globals as of Titanium 9.0.0
|Fix Version/s||CLI Release 8.1.0|
|Labels||alloy, globals, regression|
Description*Summary:* As of Titanium 9.0.0, a JS files loaded via
importin the "alloy.js" won't have access to globals
_(aka: lodash). This is not an issue if JS files are loaded via the
require()function. *Steps to reproduce:*
Open project file:
Add the following line to the end of the JS file:
console.log("@@@ Alloy = " + (typeof Alloy));
Build and run on Android or iOS.
Notice the following gets logged as undefined.
importstatement into a
require()function call at the top of the "app.js", above where we assign
Alloyglobals. Also note that "var" variables in "app.js" and "alloy.js" no longer have global scope as of Titanium 9.0.0, which is why it wasn't an issue before. The top of the generated "app.js" looks like this.
importstatements are "hoisted". This is in the ES6 specification, which means this is not a babel transpile issue. So,
importstatements will always be executed first within the same JS file. *Possible Fix:* Add an "alloy.bootstrap.js" to the project and assign the Alloy globals there. Bootstrap scripts are loaded before the "app.js", which works-around the problem. This also means we can remove the global Alloy assignment from the generated "app.js". *Work-Around:* Don't
importJS files in the "alloy.js". Use
- Ewan Harris 2020-07-30 Adding the bootstrap file will be the only solution here, bable is adhering to the modules spec by hoisting the import statements like they would if they were actually ran in a JS environment (as opposed to being transpiled) https://exploringjs.com/es6/ch_modules.html#_imports-are-hoisted
- Joshua Quick 2020-07-31
I can think of another solution.
Instead of inserting the "alloy.js" code into the "app.js" template's
__MAPMARKER_ALLOY_JS__, we could keep the "alloy.js" file and require it in instead. https://github.com/appcelerator/alloy/blob/master/Alloy/template/app.js So Alloy's "app.js" code becomes the below.
This means we're no longer generating an "app.js" and we would just copy this file and the developer's "alloy.js" as-is.
//app.js var Alloy = require('/alloy'), _ = Alloy._, Backbone = Alloy.Backbone; global.Alloy = Alloy; global._ = _; global.Backbone = Backbone; // Don't do this anymore. //__MAPMARKER_ALLOY_JS__ // Require the "alloy.js" file instead. require('alloy');
- Hans Knöchel 2020-08-01 Could we also (as a workaround) move not only the Alloy.Globals but the whole alloy.js contents to the bootstrap? Does this affect boot time?
- Joshua Quick 2020-08-03 bq. Could we also (as a workaround) move not only the Alloy.Globals but the whole alloy.js contents to the bootstrap? Does this affect boot time? Yes, that's exactly what I'm suggesting. And it wouldn't effect the boot time. We would simply be loading the "alloy.js" sooner than before (ie: before the "app.js"). A bootstrap script can only add a delay when using its optional async execute function, which we're not going to do in this case. Also, it looks like JS imports being "hoisted" above JS statements is part of the ES6 specification. So, this isn't a babel issue. The babel transpile is doing the correct thing.
- Ewan Harris 2020-08-05 PR: https://github.com/appcelerator/alloy/pull/964 I did some small tests to see how this impacted the startup time of KS-v2 on Android and there's averaged out I'm seeing similar numbers, I'll continue to try collect data and also get some results for iOS
- Ewan Harris 2020-08-06 Available in alloy 1.15.0 and appc CLI 8.1.0-master.9. Appc cli currently only preprod, so internal only
- Satyam Sekhri 2020-08-11 Verified on: Mac OS: 10.15.4 SDK: 9.1.0.v20200810095016 Appc CLI: 8.1.0-master.9 JDK: 11.0.4 Node: 10.17.0