From b6201752a2e3a5237d41064d004c75fa3e2167c8 Mon Sep 17 00:00:00 2001 From: buxxi Date: Sun, 16 Oct 2022 20:00:53 +0200 Subject: [PATCH 1/3] Support having the node_helpers being ESM modules --- js/app.js | 49 ++++++++++++++++++++++++++++++++----------------- 1 file changed, 32 insertions(+), 17 deletions(-) diff --git a/js/app.js b/js/app.js index bd3f81d25f..fcf680d51d 100644 --- a/js/app.js +++ b/js/app.js @@ -102,9 +102,9 @@ function App() { * Loads a specific module. * * @param {string} module The name of the module (including subpath). - * @param {Function} callback Function to be called after loading + * @returns {Promise} A promise that resolves as soon as the module is loaded. */ - function loadModule(module, callback) { + async function loadModule(module) { const elements = module.split("/"); const moduleName = elements[elements.length - 1]; let moduleFolder = `${__dirname}/../modules/${module}`; @@ -113,19 +113,11 @@ function App() { moduleFolder = `${__dirname}/../modules/default/${module}`; } - const helperPath = `${moduleFolder}/node_helper.js`; - - let loadHelper = true; - try { - fs.accessSync(helperPath, fs.R_OK); - } catch (e) { - loadHelper = false; - Log.log(`No helper found for module: ${moduleName}.`); - } + const helperPath = resolveHelperPath(moduleFolder); - if (loadHelper) { - const Module = require(helperPath); - let m = new Module(); + if (helperPath) { + const ModuleHelper = await import(helperPath); + let m = new ModuleHelper.default(); if (m.requiresVersion) { Log.log(`Check MagicMirror² version for node helper '${moduleName}' - Minimum version: ${m.requiresVersion} - Current version: ${global.version}`); @@ -141,9 +133,11 @@ function App() { m.setPath(path.resolve(moduleFolder)); nodeHelpers.push(m); - m.loaded(callback); + return new Promise((resolve, reject) => { + m.loaded(resolve); + }); } else { - callback(); + Log.log(`No helper found for module: ${moduleName}.`); } } @@ -162,7 +156,7 @@ function App() { function loadNextModule() { if (modules.length > 0) { const nextModule = modules[0]; - loadModule(nextModule, function () { + loadModule(nextModule).then(() => { modules = modules.slice(1); loadNextModule(); }); @@ -200,6 +194,27 @@ function App() { return segmentsA.length - segmentsB.length; } + /** + * Resolves the path to the node_helper for either CommonJS or ESM depending on the file extension + * + * @param {string} moduleFolder the folder that should contain the node_helper + * @returns {string} the path to the node_helper that should be used, or undefined if none exists + */ + function resolveHelperPath(moduleFolder) { + for (const extension of ["js", "mjs"]) { + const helperPath = `${moduleFolder}/node_helper.${extension}`; + + try { + fs.accessSync(helperPath, fs.R_OK); + return helperPath; + } catch (e) { + // The current extension may not have been found, try the next instead + } + } + + return undefined; + } + /** * Start the core app. * From 46446e03ce41a2e1bf32ae3431ffb01b6aa5607c Mon Sep 17 00:00:00 2001 From: buxxi Date: Sun, 16 Oct 2022 20:10:53 +0200 Subject: [PATCH 2/3] revert some changes to make the minimal amount needed --- js/app.js | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/js/app.js b/js/app.js index fcf680d51d..426519c663 100644 --- a/js/app.js +++ b/js/app.js @@ -102,9 +102,9 @@ function App() { * Loads a specific module. * * @param {string} module The name of the module (including subpath). - * @returns {Promise} A promise that resolves as soon as the module is loaded. + * @param {Function} callback Function to be called after loading */ - async function loadModule(module) { + function loadModule(module, callback) { const elements = module.split("/"); const moduleName = elements[elements.length - 1]; let moduleFolder = `${__dirname}/../modules/${module}`; @@ -116,28 +116,28 @@ function App() { const helperPath = resolveHelperPath(moduleFolder); if (helperPath) { - const ModuleHelper = await import(helperPath); - let m = new ModuleHelper.default(); - - if (m.requiresVersion) { - Log.log(`Check MagicMirror² version for node helper '${moduleName}' - Minimum version: ${m.requiresVersion} - Current version: ${global.version}`); - if (cmpVersions(global.version, m.requiresVersion) >= 0) { - Log.log("Version is ok!"); - } else { - Log.warn(`Version is incorrect. Skip module: '${moduleName}'`); - return; + import(helperPath).then(function (ModuleHelper) { + let m = new ModuleHelper.default(); + + if (m.requiresVersion) { + Log.log(`Check MagicMirror² version for node helper '${moduleName}' - Minimum version: ${m.requiresVersion} - Current version: ${global.version}`); + if (cmpVersions(global.version, m.requiresVersion) >= 0) { + Log.log("Version is ok!"); + } else { + Log.warn(`Version is incorrect. Skip module: '${moduleName}'`); + return; + } } - } - m.setName(moduleName); - m.setPath(path.resolve(moduleFolder)); - nodeHelpers.push(m); + m.setName(moduleName); + m.setPath(path.resolve(moduleFolder)); + nodeHelpers.push(m); - return new Promise((resolve, reject) => { - m.loaded(resolve); + m.loaded(callback); }); } else { Log.log(`No helper found for module: ${moduleName}.`); + callback(); } } @@ -156,7 +156,7 @@ function App() { function loadNextModule() { if (modules.length > 0) { const nextModule = modules[0]; - loadModule(nextModule).then(() => { + loadModule(nextModule, function () { modules = modules.slice(1); loadNextModule(); }); From 9e6ef3a9a0139151d252b60bc5c2827b48252118 Mon Sep 17 00:00:00 2001 From: buxxi Date: Sun, 16 Oct 2022 20:39:26 +0200 Subject: [PATCH 3/3] Use a different loader method for commonjs and esm --- js/app.js | 43 ++++++++++++++++++++++++++++--------------- 1 file changed, 28 insertions(+), 15 deletions(-) diff --git a/js/app.js b/js/app.js index 426519c663..c295687906 100644 --- a/js/app.js +++ b/js/app.js @@ -113,11 +113,9 @@ function App() { moduleFolder = `${__dirname}/../modules/default/${module}`; } - const helperPath = resolveHelperPath(moduleFolder); - - if (helperPath) { - import(helperPath).then(function (ModuleHelper) { - let m = new ModuleHelper.default(); + resolveHelperLoader(moduleFolder) + .then(function (ModuleHelper) { + let m = new ModuleHelper(); if (m.requiresVersion) { Log.log(`Check MagicMirror² version for node helper '${moduleName}' - Minimum version: ${m.requiresVersion} - Current version: ${global.version}`); @@ -134,11 +132,11 @@ function App() { nodeHelpers.push(m); m.loaded(callback); + }) + .catch(function (err) { + Log.log(`No helper found for module: ${moduleName}.`); + callback(); }); - } else { - Log.log(`No helper found for module: ${moduleName}.`); - callback(); - } } /** @@ -195,24 +193,39 @@ function App() { } /** - * Resolves the path to the node_helper for either CommonJS or ESM depending on the file extension + * Resolves a loader for the node_helper using either CommonJS or ESM depending on the file extension * * @param {string} moduleFolder the folder that should contain the node_helper - * @returns {string} the path to the node_helper that should be used, or undefined if none exists + * @returns {Promise} a promise that contains the loaded module */ - function resolveHelperPath(moduleFolder) { - for (const extension of ["js", "mjs"]) { + function resolveHelperLoader(moduleFolder) { + const loaders = { + js: commonJSHelperLoader, + mjs: ESMHelperLoader + }; + + for (const extension in loaders) { const helperPath = `${moduleFolder}/node_helper.${extension}`; try { fs.accessSync(helperPath, fs.R_OK); - return helperPath; + + return loaders[extension](helperPath); } catch (e) { // The current extension may not have been found, try the next instead } } - return undefined; + return Promise.reject(); + } + + async function commonJSHelperLoader(helperPath) { + return require(helperPath); + } + + async function ESMHelperLoader(helperPath) { + let module = await import(helperPath); + return module.default; } /**