diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 4e52fa6248..96ecb432c5 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -49,6 +49,8 @@ jobs: workflow: build_v8.yml name: v8_bin path: unity/native_src/ + - name: Use Xcode 12.0 for x86 + run: sudo xcode-select -switch "/Applications/Xcode_12.app" - name: Build run: | cd unity/native_src @@ -69,6 +71,8 @@ jobs: workflow: build_v8.yml name: v8_bin path: unity/native_src/ + - name: Use Xcode 12.0 for x86 + run: sudo xcode-select -switch "/Applications/Xcode_12.app" - name: Build run: | cd unity/native_src diff --git a/.github/workflows/build_v8.yml b/.github/workflows/build_v8.yml index 65872cfe04..e5742f91d7 100644 --- a/.github/workflows/build_v8.yml +++ b/.github/workflows/build_v8.yml @@ -107,6 +107,8 @@ jobs: runs-on: macos-10.15 steps: - uses: actions/checkout@v2 + - name: Use Xcode 12.0 to use SDK 10.15 + run: sudo xcode-select -switch "/Applications/Xcode_12.app" - name: Run build script run: | cd $GITHUB_WORKSPACE @@ -121,6 +123,8 @@ jobs: runs-on: macos-10.15 steps: - uses: actions/checkout@v2 + - name: Use Xcode 12.0 to use SDK 10.15 + run: sudo xcode-select -switch "/Applications/Xcode_12.app" - name: Run build script run: | cd $GITHUB_WORKSPACE @@ -135,6 +139,8 @@ jobs: runs-on: macos-10.15 steps: - uses: actions/checkout@v2 + - name: Use Xcode 12.0 to use SDK 10.15 + run: sudo xcode-select -switch "/Applications/Xcode_12.app" - name: Run build script run: | cd $GITHUB_WORKSPACE diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 822ebe66c5..9715a5e6d5 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -47,6 +47,8 @@ jobs: workflow: build_v8.yml name: v8_bin path: unity/native_src/ + - name: Use Xcode 12.0 for x86 + run: sudo xcode-select -switch "/Applications/Xcode_12.app" - name: Build run: | cd unity/native_src @@ -67,6 +69,8 @@ jobs: workflow: build_v8.yml name: v8_bin path: unity/native_src/ + - name: Use Xcode 12.0 for x86 + run: sudo xcode-select -switch "/Applications/Xcode_12.app" - name: Build run: | cd unity/native_src diff --git a/unity/Assets/Puerts/Src/Editor/CJSImporter.cs b/unity/Assets/Puerts/Src/Editor/CJSImporter.cs new file mode 100644 index 0000000000..ce642e96b8 --- /dev/null +++ b/unity/Assets/Puerts/Src/Editor/CJSImporter.cs @@ -0,0 +1,21 @@ +#if UNITY_2018_1_OR_NEWER +using System.IO; +using UnityEditor.Experimental.AssetImporters; +using UnityEngine; + +[ScriptedImporter(1, "cjs")] +public class CJSImporter : ScriptedImporter +{ + public override void OnImportAsset(AssetImportContext ctx) + { + TextAsset subAsset = new TextAsset(File.ReadAllText(ctx.assetPath)); + ctx.AddObjectToAsset("text", subAsset); + ctx.SetMainObject(subAsset); + +#if ENABLE_CJS_AUTO_RELOAD + Puerts.JsEnv.ClearAllModuleCaches(); +#endif + } +} + +#endif diff --git a/unity/Assets/Puerts/Src/JsEnv.cs b/unity/Assets/Puerts/Src/JsEnv.cs index 09cbbd469c..a8c6435ad3 100644 --- a/unity/Assets/Puerts/Src/JsEnv.cs +++ b/unity/Assets/Puerts/Src/JsEnv.cs @@ -172,6 +172,22 @@ public TResult Eval(string chunk, string chunkName = "chunk") #endif } + public void ClearModuleCache () + { + Eval("global.clearModuleCache()"); + } + + public static void ClearAllModuleCaches () + { + lock (jsEnvs) + { + foreach (var jsEnv in jsEnvs) + { + jsEnv.ClearModuleCache(); + } + } + } + public void AddLazyStaticWrapLoader(Type type, Func lazyStaticWrapLoader) { #if THREAD_SAFE @@ -597,4 +613,4 @@ internal void ReleasePendingJSFunctions() } } } -} \ No newline at end of file +} diff --git a/unity/Assets/Puerts/Src/Loader.cs b/unity/Assets/Puerts/Src/Loader.cs index a10daaf277..6df5c275fa 100644 --- a/unity/Assets/Puerts/Src/Loader.cs +++ b/unity/Assets/Puerts/Src/Loader.cs @@ -30,12 +30,20 @@ public DefaultLoader(string root) this.root = root; } + private string PathToUse(string filepath) + { + return filepath.EndsWith(".cjs") ? + filepath.Substring(0, filepath.Length - 4) : + filepath; + } + public bool FileExists(string filepath) { #if PUERTS_GENERAL return File.Exists(Path.Combine(root, filepath)); #else - return UnityEngine.Resources.Load(filepath) != null; + string pathToUse = this.PathToUse(filepath); + return UnityEngine.Resources.Load(pathToUse) != null; #endif } @@ -45,7 +53,8 @@ public string ReadFile(string filepath, out string debugpath) debugpath = Path.Combine(root, filepath); return File.ReadAllText(debugpath); #else - UnityEngine.TextAsset file = (UnityEngine.TextAsset)UnityEngine.Resources.Load(filepath); + string pathToUse = this.PathToUse(filepath); + UnityEngine.TextAsset file = (UnityEngine.TextAsset)UnityEngine.Resources.Load(pathToUse); debugpath = System.IO.Path.Combine(root, filepath); #if UNITY_EDITOR_WIN || UNITY_STANDALONE_WIN debugpath = debugpath.Replace("/", "\\"); @@ -54,4 +63,4 @@ public string ReadFile(string filepath, out string debugpath) #endif } } -} \ No newline at end of file +} diff --git a/unity/Assets/Puerts/Src/Resources/puerts/cjsload.js.txt b/unity/Assets/Puerts/Src/Resources/puerts/cjsload.js.txt index bcd5205fd3..3dc4421099 100644 --- a/unity/Assets/Puerts/Src/Resources/puerts/cjsload.js.txt +++ b/unity/Assets/Puerts/Src/Resources/puerts/cjsload.js.txt @@ -53,6 +53,7 @@ var global = global || (function () { return this; }()); return searchModuleInDirWithExt(dir, requiredModule); } else { return searchModuleInDirWithExt(dir, requiredModule + ".js") + || searchModuleInDirWithExt(dir, requiredModule + ".cjs") || searchModuleInDirWithExt(dir, requiredModule + "/index.js") || searchModuleInDirWithExt(dir, requiredModule + "/package.json"); } diff --git a/unity/Assets/Puerts/Src/Resources/puerts/modular.js.txt b/unity/Assets/Puerts/Src/Resources/puerts/modular.js.txt index 6047567773..dc8ffa8036 100644 --- a/unity/Assets/Puerts/Src/Resources/puerts/modular.js.txt +++ b/unity/Assets/Puerts/Src/Resources/puerts/modular.js.txt @@ -16,8 +16,9 @@ var global = global || (function () { return this; }()); return {fullPath: path, debugPath: debugPath, script: context} } - let tmpModuleStorage = []; - + let moduleCache = Object.create(null); // key to sid + let tmpModuleStorage = []; // sid to module + function addModule(m) { for (var i = 0; i < tmpModuleStorage.length; i++) { if (!tmpModuleStorage[i]) { @@ -32,18 +33,22 @@ var global = global || (function () { return this; }()); return tmpModuleStorage[id]; } - let moduleCache = Object.create(null); let buildinModule = Object.create(null); function executeModule(fullPath, script, debugPath, sid) { sid = (typeof sid == 'undefined') ? 0 : sid; let fullPathInJs = fullPath.replace(/\\/g, '\\\\'); let fullDirInJs = (fullPath.indexOf('/') != -1) ? fullPath.substring(0, fullPath.lastIndexOf("/")) : fullPath.substring(0, fullPath.lastIndexOf("\\")).replace(/\\/g, '\\\\'); - let executeScript = "(function() { var __filename = '" - + fullPathInJs + "', __dirname = '" - + fullDirInJs + "', module = puerts.getModuleBySID(" + sid + "), exports = module.exports; module.filename = __filename ; (function (exports, require, console, prompt) { " - + script + "\n})(exports, puerts.genRequire('" - + fullDirInJs + "'), puerts.console); return module.exports})()"; - return puerts.evalScript(executeScript, debugPath); + let exports = {}; + let module = puerts.getModuleBySID(sid); + module.exports = exports; + let wrapped = puerts.evalScript( + // Wrap the script in the same way NodeJS does it. It is important since IDEs (VSCode) will use this wrapper pattern + // to enable stepping through original source in-place. + "(function (exports, require, module, __filename, __dirname) { " + script + "\n});", + debugPath + ) + wrapped(exports, puerts.genRequire(fullDirInJs), module, fullPathInJs, fullDirInJs) + return module.exports; } function genRequire(requiringDir) { @@ -75,6 +80,9 @@ var global = global || (function () { return this; }()); return m.exports; } } + require.clearModuleCache = () => { + localModuleCache = Object.create(null); + } return require; } @@ -92,4 +100,11 @@ var global = global || (function () { return this; }()); puerts.registerBuildinModule = registerBuildinModule; global.require = genRequire(""); -}(global)); \ No newline at end of file + + function clearModuleCache () { + tmpModuleStorage = []; + moduleCache = Object.create(null); + global.require.clearModuleCache(); + } + global.clearModuleCache = clearModuleCache; +}(global));