[TIMOB-24811] LiveView causes multiple instances of same module when requiring using different paths
| GitHub Issue | n/a | 
|---|---|
| Type | Bug | 
| Priority | Critical | 
| Status | Resolved | 
| Resolution | Fixed | 
| Resolution Date | 2017-09-18T22:54:43.000+0000 | 
| Affected Version/s | Release 6.1.0 | 
| Fix Version/s | n/a | 
| Components | n/a | 
| Labels | liveview, titanium | 
| Reporter | Brenton House | 
| Assignee | Feon Sua Xin Miao | 
| Created | 2017-06-06T22:33:08.000+0000 | 
| Updated | 2017-09-21T06:42:59.000+0000 | 
Description
	When requiring a module nodejs style, using index as default, requiring the same file using different paths results in different modules.
_i.e.  require('/test')  vs require('/test/index')_
*Steps to recreate:*
1.  Create a new Titanium app using the CLI
2.  Create a new file:  /lib/test/index.js
var test = {};
module.exports = test;
test.x = 1;
var test = require('/test');
console.error('test.x: ' + test.x);
test.x: 1
8. Change the file: /lib/test/index.js
var test = {};
module.exports = test;
test.x = 2;
test.x: 2 but instead the output is the same as before:  test.x: 1
If you use the following in /controllers/index.js, it works as expected:
var test = require('/test/index');
console.error('test.x: ' + test.x);
var test1 = require('/test');
console.log('test1.x: ' + test1.x);
test1.x = 2;
var test2 = require('/test/index');
console.log('test2.x: ' + test2.x);
test.x: 1
test.x: 2
But with LiveView on, the output is this:
test.x: 1
test.x: 1
This issue should be resolved using cached version of required module. In SDK 5.X.X the second call of require to the same module returns cached module. I'm sure that this will fix it:
- (TiModule *)loadAsFile:(NSString *)path withContext:(KrollContext *)kroll { // 1. If X is a file, load X as JavaScript text. STOP TiModule *module = nil; NSString *filename = path; module = [modules objectForKey:filename]; if (module != nil) { return module; } NSString *data = [self loadFile:filename]; if (data != nil) { // If the file extension is .json, load as JavascriptObject! NSString *ext = [filename pathExtension]; if (ext != nil && [ext isEqual:@"json"]) { module = [self loadJavascriptObject:data fromFile:filename withContext:context]; } module = [self loadJavascriptText:data fromFile:filename withContext:context]; } if (module != nil) { [modules setObject:module forKey:filename]; return module; } // 2. If X.js is a file, load X.js as JavaScript text. STOP filename = [path stringByAppendingString:@".js"]; module = [modules objectForKey:filename]; if (module != nil) { return module; } data = [self loadFile:filename]; if (data != nil) { module = [self loadJavascriptText:data fromFile:filename withContext:context]; } if (module != nil) { [modules setObject:module forKey:filename]; return module; } // 3. If X.json is a file, parse X.json to a JavaScript Object. STOP filename = [path stringByAppendingString:@".json"]; module = [modules objectForKey:filename]; if (module != nil) { return module; } data = [self loadFile:filename]; if (data != nil) { module = [self loadJavascriptObject:data fromFile:filename withContext:context]; } if (module != nil) { [modules setObject:module forKey:filename]; return module; } // failed to load anything! return nil; } - (TiModule *)loadAsDirectory:(NSString *)path withContext:(KrollContext *)kroll { // 1. If X/package.json is a file, TiModule *module = nil; NSString *filename = [path stringByAppendingPathComponent:@"package.json"]; NSString *data = [self loadFile:filename]; if (data != nil) { // a. Parse X/package.json, and look for "main" field. // Just cheat and use TiUtils.jsonParse here, rather than loading the package.json as a JS object... NSDictionary *json = [TiUtils jsonParse:data]; if (json != nil) { id main = [json objectForKey:@"main"]; NSString *mainString = nil; if ([main isKindOfClass:[NSString class]]) { mainString = (NSString *)main; // b. let M = X + (json main field) NSString *m = [[path stringByAppendingPathComponent:mainString] stringByStandardizingPath]; // c. LOAD_AS_FILE(M) return [self loadAsFile:m withContext:context]; } } } // 2. If X/index.js is a file, load X/index.js as JavaScript text. STOP filename = [path stringByAppendingPathComponent:@"index.js"]; module = [modules objectForKey:filename]; if (module != nil) { return module; } data = [self loadFile:filename]; if (data != nil) { module = [self loadJavascriptText:data fromFile:filename withContext:context]; } if (module != nil) { [modules setObject:module forKey:filename]; return module; } // 3. If X/index.json is a file, parse X/index.json to a JavaScript object. STOP filename = [path stringByAppendingPathComponent:@"index.json"]; module = [modules objectForKey:filename]; if (module != nil) { return module; } data = [self loadFile:filename]; if (data != nil) { module = [self loadJavascriptObject:data fromFile:filename withContext:context]; } if (module != nil) { [modules setObject:module forKey:filename]; return module; } return nil; }PR: https://github.com/appcelerator/liveview/pull/105
Fixed in liveview@1.2.1.
Update PR: https://github.com/appcelerator/liveview/pull/108
[~fmiao]Hey Feon do we know when live view 1.2.1 will be released?
PR merged.
[~vvazquezmontero], it'll be shipped with Studio 4.10.0
Thank you [~fmiao] do we have an expected ship that for that?
[~kkolipaka] ^^
[~vvazquezmontero] Studio 4.10.0 RC would be next week.