This commit is contained in:
2025-02-10 00:44:11 +08:00
parent ece733c0e5
commit 1e0c4b8d8c
1640 changed files with 1628924 additions and 0 deletions
@@ -0,0 +1,146 @@
/*
* Tencent is pleased to support the open source community by making Puerts available.
* Copyright (C) 2020 THL A29 Limited, a Tencent company. All rights reserved.
* Puerts is licensed under the BSD 3-Clause License, except for the third-party components listed in the file 'LICENSE' which may
* be subject to their corresponding license terms. This file is subject to the terms and conditions defined in file 'LICENSE',
* which is part of this source code package.
*/
#include "JSModuleLoader.h"
#include "Misc/Paths.h"
#include "Misc/FileHelper.h"
#include "Algo/Reverse.h"
#if (ENGINE_MAJOR_VERSION >= 5)
#include "HAL/PlatformFileManager.h"
#else
#include "HAL/PlatformFilemanager.h"
#endif
namespace PUERTS_NAMESPACE
{
static FString PathNormalize(const FString& PathIn)
{
TArray<FString> PathFrags;
PathIn.ParseIntoArray(PathFrags, TEXT("/"));
Algo::Reverse(PathFrags);
TArray<FString> NewPathFrags;
bool FromRoot = PathIn.StartsWith(TEXT("/"));
while (PathFrags.Num() > 0)
{
FString E = PathFrags.Pop();
if (E != TEXT("") && E != TEXT("."))
{
if (E == TEXT("..") && NewPathFrags.Num() > 0 && NewPathFrags.Last() != TEXT(".."))
{
NewPathFrags.Pop();
}
else
{
NewPathFrags.Push(E);
}
}
}
if (FromRoot)
{
return TEXT("/") + FString::Join(NewPathFrags, TEXT("/"));
}
else
{
return FString::Join(NewPathFrags, TEXT("/"));
}
}
bool DefaultJSModuleLoader::CheckExists(const FString& PathIn, FString& Path, FString& AbsolutePath)
{
IPlatformFile& PlatformFile = FPlatformFileManager::Get().GetPlatformFile();
FString NormalizedPath = PathNormalize(PathIn);
if (PlatformFile.FileExists(*NormalizedPath))
{
AbsolutePath = IFileManager::Get().ConvertToAbsolutePathForExternalAppForRead(*NormalizedPath);
Path = NormalizedPath;
return true;
}
return false;
}
bool DefaultJSModuleLoader::SearchModuleInDir(
const FString& Dir, const FString& RequiredModule, FString& Path, FString& AbsolutePath)
{
FString Extension = FPaths::GetExtension(RequiredModule);
bool IsJs = Extension == TEXT("js") || Extension == TEXT("mjs") || Extension == TEXT("cjs") || Extension == TEXT("json");
if (IsJs && SearchModuleWithExtInDir(Dir, RequiredModule, Path, AbsolutePath))
return true;
return SearchModuleWithExtInDir(Dir, RequiredModule + ".js", Path, AbsolutePath) ||
SearchModuleWithExtInDir(Dir, RequiredModule + ".mjs", Path, AbsolutePath) ||
SearchModuleWithExtInDir(Dir, RequiredModule + ".cjs", Path, AbsolutePath) ||
#if defined(WITH_V8_BYTECODE)
SearchModuleWithExtInDir(Dir, RequiredModule + ".mbc", Path, AbsolutePath) ||
SearchModuleWithExtInDir(Dir, RequiredModule + ".cbc", Path, AbsolutePath) ||
#endif
SearchModuleWithExtInDir(Dir, RequiredModule / "package.json", Path, AbsolutePath) ||
SearchModuleWithExtInDir(Dir, RequiredModule / "index.js", Path, AbsolutePath);
}
bool DefaultJSModuleLoader::SearchModuleWithExtInDir(
const FString& Dir, const FString& RequiredModule, FString& Path, FString& AbsolutePath)
{
return CheckExists(Dir / RequiredModule, Path, AbsolutePath) ||
(!Dir.EndsWith(TEXT("node_modules")) && CheckExists(Dir / TEXT("node_modules") / RequiredModule, Path, AbsolutePath));
}
bool DefaultJSModuleLoader::Search(const FString& RequiredDir, const FString& RequiredModule, FString& Path, FString& AbsolutePath)
{
if (SearchModuleInDir(RequiredDir, RequiredModule, Path, AbsolutePath))
{
return true;
}
if (RequiredDir != TEXT("") && !RequiredModule.GetCharArray().Contains('/') && !RequiredModule.EndsWith(TEXT(".js")) &&
!RequiredModule.EndsWith(TEXT(".mjs")))
{
// 调用require的文件所在的目录往上找
TArray<FString> pathFrags;
RequiredDir.ParseIntoArray(pathFrags, TEXT("/"));
pathFrags.Pop(); // has try in "if (SearchModuleInDir(RequiredDir, RequiredModule, Path, AbsolutePath))"
while (pathFrags.Num() > 0)
{
if (!pathFrags.Last().Equals(TEXT("node_modules")))
{
if (SearchModuleInDir(FString::Join(pathFrags, TEXT("/")), RequiredModule, Path, AbsolutePath))
{
return true;
}
}
pathFrags.Pop();
}
}
return SearchModuleInDir(FPaths::ProjectContentDir() / ScriptRoot, RequiredModule, Path, AbsolutePath) ||
(ScriptRoot != TEXT("JavaScript") &&
SearchModuleInDir(FPaths::ProjectContentDir() / TEXT("JavaScript"), RequiredModule, Path, AbsolutePath));
}
bool DefaultJSModuleLoader::Load(const FString& Path, TArray<uint8>& Content)
{
// return (FPaths::FileExists(FullPath) && FFileHelper::LoadFileToString(Content, *FullPath));
IPlatformFile& PlatformFile = FPlatformFileManager::Get().GetPlatformFile();
IFileHandle* FileHandle = PlatformFile.OpenRead(*Path);
if (FileHandle)
{
int len = FileHandle->Size();
Content.Reset(len + 2);
Content.AddUninitialized(len);
const bool Success = FileHandle->Read(Content.GetData(), len);
delete FileHandle;
return Success;
}
return false;
}
FString& DefaultJSModuleLoader::GetScriptRoot()
{
return ScriptRoot;
}
} // namespace PUERTS_NAMESPACE