[AC-837] Ti.include does not work in Alloy project
GitHub Issue | n/a |
---|---|
Type | Bug |
Priority | n/a |
Status | Resolved |
Resolution | Won't Fix |
Resolution Date | 2014-05-15T14:22:17.000+0000 |
Affected Version/s | n/a |
Fix Version/s | n/a |
Components | n/a |
Labels | n/a |
Reporter | Fix Please |
Assignee | Shak Hossain |
Created | 2014-05-14T17:15:37.000+0000 |
Updated | 2016-03-08T07:37:07.000+0000 |
Description
{color:red}
[ERROR] : TiExceptionHandler: (main) [605,605] ----- Titanium Javascript Runtime Error -----
[ERROR] : TiExceptionHandler: (main) [0,605] - In alloy/controllers/Empty.js:16,1
[ERROR] : TiExceptionHandler: (main) [0,605] - Message: Uncaught ReferenceError: module is not defined
[ERROR] : TiExceptionHandler: (main) [0,605] - Source: module.exports = Controller;
[ERROR] : V8Exception: Exception occurred at alloy/controllers/Empty.js:16: Uncaught ReferenceError: module is not defined
{color}
<Alloy>
<Window class="container">
<Label id="label" onClick="doClick">Hello, World</Label>
</Window>
</Alloy>
Ti.include('Empty.js');
function doClick(e) {
alert($.label.text);
}
$.index.open();
*Empty.js* is just an empty file.
Ti.include should be deprecated and removed as soon as possible. It was a solution to a problem that has long been solved. Using it with Alloy is weird, like putting Diesel in a Petrol car - just wrong. If you are wanting to include large sections of code in-line then re-think and convert them to CommonJS or Widgets or anything.
BTW What is with "Please Fix"? This is a community of people - use names.
{quote} ...is weird, ...just wrong, ...use names... {quote} Hey man, take it easy. Ok? The 'Ti.include' is a documented language/framework construction. I don't see any restrictions in the documentation. And it *must* work if so.
You are correct the documentation does not show any indication that you should not use it and more specifically it should not be used with Alloy. However if you delve into the logic of how Alloy works it does not make sense to continue supporting. It is an anti-pattern, as I said - solved a problem until better solutions came alone; CommonJS, Alloy & Alloy plus CommonJS to name a few examples. My frustration is not aimed at you. It is targeted towards having this relic removed so it does not contribute to apps not struggling; to scale, being memory efficient, managing true re-usability. My aim is to make sure that newbie do not have their future developments slowed down by having to work around the problems that this and those others I referred to with not continue to be used by new developers only to find out this (and those others) have held them back. I have a significant amount of experience of helping developers bring their apps up to a better level and solving the problems that this and other things have caused. So whilst you appear to not agree with me trust me that I have been there done that, bought the t-shirt and done the same for hundreds of developers. With the mobile world moving so fast and new features and techniques coming along to help things - this one is just such an anti-pattern relic. So this is why I have added comments to this bug report, not because I like adding comments - but in order to help.
Malcolm, 1. Do you mean that commonly used 'javascript module' pattern is an "anti-pattern"? 2. Alloy is not a revolutionary technique. It's just yet another MVC framework. 3. There are a lot of common words in your post. Could you be a bit more specific? Could you provide at least a couple of points on (include VS CommonJS)? 4. More specific question. For instance I have 3d party javascript module. Am I right that you suggest me to rewrite it instead of just including?
Thanks ;)
Yes.
#* http://en.wikipedia.org/wiki/Anti-pattern #* A commonly used process, structure or pattern of action that despite initially appearing to be an appropriate and effective response to a problem, typically has more bad consequences than beneficial results, and #* A good alternative solution exists that is documented, repeatable and proven to be effective.Never said it was
#* Pointed out it was much better than include. #* It is more than "just another MVC" it is the Titanium MVC #* without it app development is slower and not well planned #* it teaches and respectfully forces you to become better at being a developer #* yes there are other MVC for other languages - but MVCs are used for very good reasons #* it never stops being enhanced - the next dot release has some great improvements and extra features that help you be better #* and that never stopsInclude dumps code directly into the flow of the code in which the include reference is used;
#* this includes functions, variables and many other potential scope creep issues #* In the wrong hands (most peoples) code inside 'include' is bloated and not functionally specific #* often times large numbers of unrelated functions are thrown inside and whilst only one is needed - all appear in memory #* CommonJS (and Alloy) when used correctly manages self scope, re-usability, global state - but not being global in of itself #* Debugging and removing any memory leaks are aided by this true separation #* also finding and plugging those leaks is much simpler #* memory is only taken up when required not all at once #* speed of app start-up, window loads and other performance tuning measures are simplifiedYES, might sound harsh - and you might say how am I meant to do that;
#* but 'include' is a cheat when dumping a third-party library #* if you look hard enough almost everything will have a CommonJS equivalent #* if not - a perfect learning experience to read and convert the code yourself #* relying on third-party libraries without understanding them will set you up for a fall when they no longer work with everything else that moved on. You have jumped to Alloy - good choice - right direction, but hanging on to include is going back in the wrong direction. Two steps forward, 2 steps back.{quote} a perfect learning experience to read and convert the code yourself {quote} Are you kidding? I'm about real software development and business, not about learning and art. Again, you've written a bunch of words, but there are almost no details. I can see just common words. Sorry. {quote} *In the wrong hands* (most peoples) code inside 'include' ... CommonJS (and Alloy) *when used correctly* ... {quote} Seems, it's my turn to refer the wiki: http://en.wikipedia.org/wiki/Demagogy
"I'm about real software development and business" Just not about real names.
Btw, {quote} FP> 1. Do you mean that commonly used 'javascript module' pattern is an "anti-pattern"? MH> Yes. {quote} Douglas Crockford and Richard Cornford are not agree. ;) Malcolm, seems, you should give them a couple of your lessons. lol
I incorrectly read number 1 as include, given that was your whole point previously, I failed to notice that you swapped it to javascript module, rather than continuing your weird love of include. My point was related to your insistence that include is great. But again; Anti-pattern is a commonly used process, structure or pattern of action that despite initially appearing to be an appropriate and effective response to a problem, typically has more bad consequences than beneficial results, and a good alternative solution exists that is documented, repeatable and proven to be effective. To again BE clear, anything is considered an anti-pattern if you test against the logic above. If you insist on using something that whilst was previously a good solution but the side effects out way the benefits whilst the same time better solutions exist that are clearly better on many levels - anti-pattern. This is true even if I had meant javascript module if it fails those tests. As to not providing any details; the 10+ reasons against listed above - all aimed at pointing out how you can be better and by extension so can your apps. This is the point where we differ "Are you kidding? I'm about real software development and business, not about learning and art.". Firstly interesting take on what I said, plus where did art come into it. But your "real software development" is "not about learning" not a lot to say here, the mobile software development is a moving target - but you are not about learning.
{quote} I incorrectly read number 1 as include, given that was your whole point previously, I failed to notice that you swapped it to javascript module {quote} Ok, now you read correctly. If so, the question was about the 'javascript module': Is it pattern or anti-pattern? {quote} ...continuing your weird love of include. My point was related to your insistence that include is great. {quote} I didn't say that. Could you show a quote, please? I just said that in my case 'include' would solve the task in a couple of minutes. Your suggestion to rewrite 3d party module looks like a joke for me. It's hours and hours of development and further support of the code. Unfortunately the 'Ti.include' does not work as expected. That's why I've opened the bug item. {quote} 10+ reasons against listed above {quote} Let's count: {color:blue}1. MVCs are used for very good reasons it never stops being enhanced - the next dot release has some great improvements and extra features that help you be better{color} Here is nothing about the 'include VS require'. And it's not even MVC specific. Usually the main goal of *any* development is to make a new release better than the previous one. {color:blue}2. Include dumps code directly into the flow of the code in which the include reference is used. this includes functions, variables and many other potential scope creep issues{color} Partially accepted. Because of it depends on how particular code is written. {color:blue}3. In the wrong hands (most peoples) code inside 'include' is bloated and not functionally specific often times large numbers of unrelated functions are thrown inside and whilst only one is needed - all appear in memory{color} Do you mean one can't do the same using the CommonJS? Seems it's not about 'include VS require' again. {color:blue}4. CommonJS (and Alloy) when used correctly manages self scope, re-usability, global state - but not being global in of itself{color} I've already pointed to the 'when used correctly'. Can't one use the 'include' correctly? {color:blue}5. Debugging and removing any memory leaks are aided by this true separation also finding and plugging those leaks is much simpler{color} Accepted. But again, just partially. Because of it depends on how particular code is written. In the both 'include VS require' cases. {color:blue}6. memory is only taken up when required not all at once{color} Accepted. But... Ok, I don't want to discuss this in depth. Just... Whether you will agree that memory management depends not only on code itself but on the environment where the code is being executed as well? {color:blue}7. speed of app start-up, window loads and other performance tuning measures are simplified{color} Ok, start-up could be a bit faster. But on the other hand later something will be slower. So it depends on what you wanna achieve for particular app. Sometimes it's much more preferable to have a delay on start-up rather than later during execution. And in general Alloy code is slower than 'classic' code. It's slower because of its nature. So... Seems we have 7 points in total. And almost nothing regarding the 'include VS require'. What "10+" are you talking about? {quote} But your "real software development" is "not about learning" not a lot to say here, the mobile software development is a moving target - but you are not about learning. {quote} Demagogy is detected again. ;)
What do you think 'javascript module' is this context - you haven't said - you swapped from include to module - not sure if you are referring to CommonJS module or something else. {color:blue}The problem you have with the question "include vs require" is two fold;{color} 1. one I never said "require" is better than include - I said "require, Alloy, Widgets or anything is better than "include" 2. As I have stated so many times "include" is a relic waiting to be killed off, there is nothing for include, only ever against - this is my argument. Again for the record "include" WAS a solution to a problem that has side effects in both use and function when better solutions exist. In case you are not getting it; using a horse and cart to travel a hundred miles is an anti-pattern to using a car, train, plane or other faster, safer, more suitable method of transport. But travelling in a horse and cart is fun - so you travel that way for nostalgic reasons. Whilst you clearly cannot count as I stopped counting at 11, you also failed to realise that some you counted were related to specific questions you asked - check your number 1 above, look back to your number 1 you asked and see how they match - question to answer. So hard to be they "include vs require" argument you keep pushing as something that is a valid question to ask. {color:blue}Nice to see you accept all the points you managed to count - even if you misunderstood the premise of some of them, put this test to all your own comments;{color} "CommonJS CAN allow stupidity, but whilst learning about CommonJS coding styles tend to follow the guidelines. Include has no guidelines and tend to promote convenience over planning, manageability, re-use etc." {color:blue}I want to deal with point 7 specifically;{color} It is well documented that users will not wait for apps to load if they take too long, long can be 5 seconds or less. A well tuned start-up process is one of the key factors to having your app used beyond download. So WHATEVER technique you use - this is key. I disagree that Alloy code is slower that Titanium (ignoring the fact Alloy code is still Titanium). Yes there are a few processing overheads. But again Alloy promotes modularisation of code and features, beyond simple CommonJS. You app can start-up with 5% of what it might and then only ever bring in additional code when truly required - and then cached. Alloy optimises elements of code that you add, so boost there. Having converted several very large apps into Alloy, the differences are amazing. In addition to the performance boosts Alloy provides - it helps structure your presentation and code - aids readability and re-usability. {color:blue}Expand on "And in general Alloy code is slower than 'classic' code. It's slower because of its nature."{color} Where do you get that information from? You keep trying to insult me with {color:blue}Demagogy{color}, ignoring your wish to insult people you again are confusing things. You may not know me and that is fine, however my credentials are public and for all to see; 1) #1 expert on the Q&A, does not say I know everything but does show that not only do I now a good deal, what I know has been of helps to so many people on so many subjects that my solutions are usually the accepted ones. 2) Named by Appcelerator as "The Oracle" a title I love for all the obvious ego stroking reasons as well as the value placed upon my contributions to the community as a whole by the creators of the software we both use. 3) Being influential in a community does not mean I am a Demagogue, trying to point out how others can be better does not mean I am a Demagogue, saying things you do not want to here does not make me a Demagogue. Only you doing what I say WITHOUT a reasoned decision makes me a Demagogue in YOUR eyes, for those who choose not to listen or to listen and agree - I am not a Demagogue. You know based on the wiki definition your referred to. Finally - whoever said converting a library of code to CommonJS will takes hours? Took me 20 seconds to convert moment.js to a CommonJS module (Alloy provides it now though). UrbanAirship module to 5 minutes - because I took the time to review the code. My name is Malcolm Hollingsworth my name is public, my profile is public, my reputation is public. So "Fix Me" what about you. At best your name is a veiled insult at worst a means to hide your identity.
Malcolm, you're wasting your time...
{quote} What do you think 'javascript module' is this context - you haven't said {quote} Hmm... I just expected that as an expert you should know such a commonly used and well-known pattern... https://www.google.com/search?q=javascript+module+pattern
I have to say, that this is not an issue, or a bug. Although Ti.Include is documented it is out of scope of using it within a commonJS framework. This method was used previously in the global scope method of coding application before the adoption of commonJS. Include, should not actually be supported and as Alloy is an MVC framework built on top of the main Titanium commonJS framework, it is not going to work. Without a context of what you are trying to achieve with the empty.js, then cannot suggest a solution. Here I would say that this should have been a question in the Q & A, not a Jira. Please understand, the answers Malcolm has given here should have been handled in the Q & A as you have raised a bug report, which isn't a bug. If you wish to raise this in the Q & A, then I am sure quite a few people will happily help you resolve your application architecture is and resolve what you require empty.js to actually be performing. Hope this helps and will end the ongoing discussion in an inappropriate place.
{quote} Please understand, the answers Malcolm has given here should have been handled in the Q & A as you have raised a bug report, which isn't a bug. {quote} It IS a bug. And even more, I'd say there are at least 2 bugs, not just one: 1. The statement does not work as documented and expected. 2. The error message is weird and useless. imho
OK... Really! who are you .... You have two senior, experienced Titanium dev's both of which have now told you that ti.include should not be used. If you wish to use it, carry on and expect errors, it is there only to enable backward compatibility. IT IS NOT A BUG ..... include is not part of the commonJS specification, use require ... Now you can accept this or not, you're choice ...
Trevor, perhaps I'm not as senior as you, but in my world it's a bug if something does not work as documented/expected. A BUG. Either in the code or in the documentation. ;)
{quote} Really! who are you .... You have two senior, experienced Titanium dev's... {quote} Relax and don't worry, Trevor. I was not going to participate in your dick-size contest. :)
Guys, this is done. Let's stop the bickering. Here are some facts, devoid of sentiment. 1.
Ti.include()
is an antipattern in Alloy. If you are using it for any reason, you are willingly opening your code up to unexpected issues and behaviors, much like you are encountering Mr. Fix Please. 2. This antipattern is not well-documented enough, you are absolutely right Mr. Fix Please. The reason veterans in this thread have so adamantly been defending that position is because they know I've defined this antipattern for a long time. It is *my* fault for not more formally codifying it. I'll aim to improve the visibility of this statement in the near future. 3. Despite the above,Ti.include()
should technically work right if you use it correctly. 4. Referring to immediately invoked function expressions (IIFE) as a "javascript module" in the context of a conversation aboutTi.include()
versus CommonJS indicates that you are trying to win an argument rather than learn. In Titanium, the commonjs implementation makes the formerly necessary IIFE syntax for scoping completely obsolete. While it is of course valid syntax, it is rarely suitable in modern, best practice Titanium code. 5. Alloy code generates traditional Titanium code. it is not slower or different. In many cases it is faster due to the fact that its code generation and APIs have encapsulated best practices for performance. I would welcome specific, practical examples where Alloy is slowing you down beyond a purely anecdotal "Alloy must be slower because it's a framework" (paraphrase). 6. I understand the frustration with attempting to import legacy code into Alloy and having problems. My concern is that I can't jeopardize the stability, performance, and clarity of Alloy for the sake of some edge cases like this. It's an edge case on an antipattern, not one I can responsibly spend a great deal of time on. But just to show I'm not all negative and cold, in the strictest sense of the word, disregarding the context above, this is in fact a bug report. I can't reproduce it on Mac OSX, so let me spin up a Windows VM and see if it happens there. All I ask in return is that the misery and ire in this thread comes to an end. Understand that these guys were trying to help and everything just escalated a bit too quickly on both sides. -- Tony, the peacemakerSo here's the deal. The only situation in which
Ti.include()
will fail with this error is on Android when you attempt to include a *controller*. If you need to include a 3rd party library, put it in the *lib* folder and everything works fine. So for example, if you put *Empty.js* in the lib folder instead of the controllers folder, this works without error. UsingTi.include()
on a controller is undoubtedly always going to have unexpected behavior, since as is in fact well-documented, controllers at runtime are a composite of a number of files. Again, I have to reiterate that what everyone in this thread was saying is correct and that when at all possibleTi.include()
should be avoided. I'm marking this as "won't fix" as future effort around this will entail documenting thatTi.include()
should not be used in Alloy. Also, the information I gave above gives a pretty simple way to avoid it. I hope this brings this situation to a close.Seems like TC-4124 is a better place to have a conversation about TC-4124.
Sure
[~tlukasavage] [~ngupta] let's officially deprecate and remove this in 3.3.0 (Ti.include) and make this official.
For my laziness I tried once to put a complex util library using Ti.include inside a commonJS module. Then I started getting errors about missing functions in the included file. I think it's because Ti.include is evaluated asynchronously, so it may happen that the function is called even before the file is loaded into memory. I spent around 10 minutes to convert it to CommonJS and require it and never used Ti.include since then