@@ -166,18 +166,9 @@ void Module::RequireCallbackImpl(const v8::FunctionCallbackInfo<v8::Value>& args
166166
167167 string moduleName = ConvertToString (args[0 ].As <String>());
168168 string callingModuleDirName = ConvertToString (args[1 ].As <String>());
169-
170- JEnv env;
171- JniLocalRef jsModulename (env.NewStringUTF (moduleName.c_str ()));
172- JniLocalRef jsCallingModuleDirName (env.NewStringUTF (callingModuleDirName.c_str ()));
173- JniLocalRef jsModulePath (env.CallStaticObjectMethod (MODULE_CLASS, RESOLVE_PATH_METHOD_ID, (jstring) jsModulename, (jstring) jsCallingModuleDirName));
174-
175- // cache the required modules by full path, not name only, since there might be some collisions with relative paths and names
176- string modulePath = ArgConverter::jstringToString ((jstring) jsModulePath);
177-
178169 auto isData = false ;
179170
180- auto moduleObj = LoadImpl (isolate, modulePath , isData);
171+ auto moduleObj = LoadImpl (isolate, moduleName, callingModuleDirName , isData);
181172
182173 if (isData)
183174 {
@@ -217,40 +208,64 @@ void Module::Load(const string& path)
217208 }
218209}
219210
220- Local<Object> Module::LoadImpl (Isolate *isolate, const string& path , bool & isData)
211+ Local<Object> Module::LoadImpl (Isolate *isolate, const string& moduleName, const string& baseDir , bool & isData)
221212{
213+ auto pathKind = GetModulePathKind (moduleName);
214+ auto cachePathKey = (pathKind == ModulePathKind::Global) ? moduleName : (baseDir + " *" + moduleName);
215+
222216 Local<Object> result;
223217
224- auto it = m_loadedModules.find (path);
218+ DEBUG_WRITE (" >>LoadImpl cachePathKey=%s" , cachePathKey.c_str ());
219+
220+ auto it = m_loadedModules.find (cachePathKey);
225221
226222 if (it == m_loadedModules.end ())
227223 {
228- if (Util::EndsWith (path, " .js" ) || Util::EndsWith (path, " .so" ))
229- {
230- isData = false ;
231- result = LoadModule (isolate, path);
232- }
233- else if (Util::EndsWith (path, " .json" ))
224+ JEnv env;
225+ JniLocalRef jsModulename (env.NewStringUTF (moduleName.c_str ()));
226+ JniLocalRef jsBaseDir (env.NewStringUTF (baseDir.c_str ()));
227+ JniLocalRef jsModulePath (env.CallStaticObjectMethod (MODULE_CLASS, RESOLVE_PATH_METHOD_ID, (jstring) jsModulename, (jstring) jsBaseDir));
228+
229+ auto path = ArgConverter::jstringToString ((jstring) jsModulePath);
230+
231+ auto it2 = m_loadedModules.find (path);
232+
233+ if (it2 == m_loadedModules.end ())
234234 {
235- isData = true ;
236- result = LoadData (isolate, path);
235+ if (Util::EndsWith (path, " .js" ) || Util::EndsWith (path, " .so" ))
236+ {
237+ isData = false ;
238+ result = LoadModule (isolate, path, cachePathKey);
239+ }
240+ else if (Util::EndsWith (path, " .json" ))
241+ {
242+ isData = true ;
243+ result = LoadData (isolate, path);
244+ }
245+ else
246+ {
247+ string errMsg = " Unsupported file extension: " + path;
248+ throw NativeScriptException (errMsg);
249+ }
237250 }
238251 else
239252 {
240- string errMsg = " Unsupported file extension: " + path;
241- throw NativeScriptException (errMsg);
253+ auto & cacheEntry = it2->second ;
254+ isData = cacheEntry.isData ;
255+ result = Local<Object>::New (isolate, *cacheEntry.obj );
242256 }
243257 }
244258 else
245259 {
246- isData = Util::EndsWith (path, " .json" );
247- result = Local<Object>::New (isolate, *it->second );
260+ auto & cacheEntry = it->second ;
261+ isData = cacheEntry.isData ;
262+ result = Local<Object>::New (isolate, *cacheEntry.obj );
248263 }
249264
250265 return result;
251266}
252267
253- Local<Object> Module::LoadModule (Isolate *isolate, const string& modulePath)
268+ Local<Object> Module::LoadModule (Isolate *isolate, const string& modulePath, const string& moduleCacheKey )
254269{
255270 Local<Object> result;
256271
@@ -262,7 +277,7 @@ Local<Object> Module::LoadModule(Isolate *isolate, const string& modulePath)
262277 moduleObj->Set (ConvertToV8String (" filename" ), fullRequiredModulePath);
263278
264279 auto poModuleObj = new Persistent<Object>(isolate, moduleObj);
265- TempModule tempModule (this , modulePath, poModuleObj);
280+ TempModule tempModule (this , modulePath, moduleCacheKey, poModuleObj);
266281
267282 TryCatch tc;
268283
@@ -469,6 +484,18 @@ void Module::SaveScriptCache(const ScriptCompiler::Source& source, const std::st
469484 File::WriteBinary (cachePath, source.GetCachedData ()->data , length);
470485}
471486
487+ Module::ModulePathKind Module::GetModulePathKind (const std::string& path)
488+ {
489+ ModulePathKind kind;
490+ switch (path[0 ])
491+ {
492+ case ' .' : kind = ModulePathKind::Relative; break ;
493+ case ' /' : kind = ModulePathKind::Absolute; break ;
494+ default : kind = ModulePathKind::Global; break ;
495+ }
496+ return kind;
497+ }
498+
472499jclass Module::MODULE_CLASS = nullptr ;
473500jmethodID Module::RESOLVE_PATH_METHOD_ID = nullptr ;
474501
0 commit comments