SAP / yeoman-ui

Provide rich user experience for Yeoman generators using VSCode extension or the browser.
Apache License 2.0
101 stars 46 forks source link

Template Wizard fails running ESM-based Easy UI5 generator #850

Open petermuessig opened 2 months ago

petermuessig commented 2 months ago

When trying to use the Template Wizard in VSCode or BAS for the Easy UI5 generator it immediately crashes with the following error message:

{
  "label": "Application Wizard.AbstractWebviewPanel",
  "level": "error",
  "message": "easy-ui5:app generator failed - runGenerator() require() of ES Module /Users/XXX/SAPDevelop/ghdesktop/generator-easy-ui5/generators/app/index.js from /Users/XXX/.vscode/extensions/sapos.yeoman-ui-1.16.3/dist/extension.js not supported.\nInstead change the require of index.js in /Users/XXX/.vscode/extensions/sapos.yeoman-ui-1.16.3/dist/extension.js to a dynamic import() which is available in all CommonJS modules.",
  "stack": "Error [ERR_REQUIRE_ESM]: require() of ES Module /Users/XXX/SAPDevelop/ghdesktop/generator-easy-ui5/generators/app/index.js from /Users/XXX/.vscode/extensions/sapos.yeoman-ui-1.16.3/dist/extension.js not supported.\nInstead change the require of index.js in /Users/XXX/.vscode/extensions/sapos.yeoman-ui-1.16.3/dist/extension.js to a dynamic import() which is available in all CommonJS modules.\n    at c._load (node:electron/js2c/node_init:2:13801)\n    at E._load (/Applications/Visual Studio Code.app/Contents/Resources/app/out/vs/workbench/api/node/extensionHostProcess.js:177:6051)\n    at i._load (/Applications/Visual Studio Code.app/Contents/Resources/app/out/vs/workbench/api/node/extensionHostProcess.js:174:31787)\n    at o._load (/Applications/Visual Studio Code.app/Contents/Resources/app/out/vs/workbench/api/node/extensionHostProcess.js:139:34334)\n    at Module.patchedRequire (/Users/XXX/.vscode/extensions/sapse.sap-ux-application-modeler-extension-1.14.4/dist/extension-min.js:943:9530)\n    at r.require (/Users/XXX/.vscode/extensions/sapos.yeoman-ui-1.16.3/dist/extension.js:152501:22)\n    at g (/Applications/Visual Studio Code.app/Contents/Resources/app/out/bootstrap-fork.js:2:647)\n    at Object.get [as easy-ui5:app] (/Users/XXX/.vscode/extensions/sapos.yeoman-ui-1.16.3/dist/extension.js:144696:28)\n    at e.exports.get (/Users/XXX/.vscode/extensions/sapos.yeoman-ui-1.16.3/dist/extension.js:144706:39)\n    at B.get (/Users/XXX/.vscode/extensions/sapos.yeoman-ui-1.16.3/dist/extension.js:144317:28)\n    at B.create (/Users/XXX/.vscode/extensions/sapos.yeoman-ui-1.16.3/dist/extension.js:144360:30)\n    at m.<anonymous> (/Users/XXX/.vscode/extensions/sapos.yeoman-ui-1.16.3/dist/extension.js:150381:27)\n    at Generator.next (<anonymous>)\n    at o (/Users/XXX/.vscode/extensions/sapos.yeoman-ui-1.16.3/dist/extension.js:150214:23)",
  "time": "2024-09-04T04:01:52.666Z"
}

This states that ESM-based generators are not supported by Yeoman UI. Are there any plans to change that? As more and more NPM packages are ESM-based a change to ES modules helped to simplify the code a lot.

I tried to create a proxy generator which dynamically requires the ESM-based Easy UI5 generator. Unfortunately, without success as the dynamic import statement leads to the following error:

2024-09-04 07:23:33.131 [error] TypeError: A dynamic import callback was not specified.
    at importModuleDynamicallyCallback (node:internal/modules/esm/utils:228:9)
    at /Users/XXX/SAPDevelop/ghdesktop/generator-ui5-app/generators/app/index.js:9:4
    at new Promise (<anonymous>)
    at module.exports.prompting (/Users/XXX/SAPDevelop/ghdesktop/generator-ui5-app/generators/app/index.js:7:10)
    at Object.<anonymous> (/Users/XXX/SAPDevelop/ghdesktop/generator-ui5-app/node_modules/yeoman-generator/lib/index.js:1096:23)
    at /Users/XXX/SAPDevelop/ghdesktop/generator-ui5-app/node_modules/run-async/index.js:49:25
    at new Promise (<anonymous>)
    at /Users/XXX/SAPDevelop/ghdesktop/generator-ui5-app/node_modules/run-async/index.js:26:19
    at /Users/XXX/SAPDevelop/ghdesktop/generator-ui5-app/node_modules/yeoman-generator/lib/index.js:1097:9
    at new Promise (<anonymous>)
    at module.exports.executeTask (/Users/XXX/SAPDevelop/ghdesktop/generator-ui5-app/node_modules/yeoman-generator/lib/index.js:1068:12)
    at runLoop.add.once (/Users/XXX/SAPDevelop/ghdesktop/generator-ui5-app/node_modules/yeoman-generator/lib/index.js:1048:14)
    at Immediate.<anonymous> (/Users/XXX/.vscode/extensions/sapos.yeoman-ui-1.16.3/dist/extension.js:164006:39)
    at processImmediate (node:internal/timers:478:21)

To verify the issue a bit more in depth, I made a very basic ESM-based generator:

import Generator from "yeoman-generator";

export default class extends Generator {
    async prompting() {
        return this.prompt([
            {
                type: "input",
                name: "namespace",
                message: "Enter your application id (namespace)?",
                validate: (s) => {
                    if (/^[a-zA-Z0-9][a-zA-Z0-9_.]*$/g.test(s)) {
                        return true;
                    }

                    return "Please use alpha numeric characters and dots only for the namespace.";
                },
                default: "com.myorg.myapp"
            }
        ])
    }
};

in this case it now fails with the following error message:

{
  "label": "Application Wizard.AbstractWebviewPanel",
  "level": "error",
  "message": "ui5-app:app generator failed - runGenerator() Cannot use import statement outside a module",
  "stack": "/Users/XXX/SAPDevelop/ghdesktop/generator-ui5-app/generators/app/index.js:1\n(function (exports, require, module, __filename, __dirname) { import Generator from \"yeoman-generator\";\n                                                              ^^^^^^\n\nSyntaxError: Cannot use import statement outside a module\n    at new Script (node:vm:116:7)\n    at Module.u._compile (/Applications/Visual Studio Code.app/Contents/Resources/app/out/bootstrap-fork.js:2:1131)\n    at Object.Module._extensions..js (node:internal/modules/cjs/loader:1432:10)\n    at Module.load (node:internal/modules/cjs/loader:1215:32)\n    at Module._load (node:internal/modules/cjs/loader:1031:12)\n    at Function.c._load (node:electron/js2c/node_init:2:13801)\n    at Function.E._load (/Applications/Visual Studio Code.app/Contents/Resources/app/out/vs/workbench/api/node/extensionHostProcess.js:177:6051)\n    at Function.i._load (/Applications/Visual Studio Code.app/Contents/Resources/app/out/vs/workbench/api/node/extensionHostProcess.js:174:31787)\n    at Function.o._load (/Applications/Visual Studio Code.app/Contents/Resources/app/out/vs/workbench/api/node/extensionHostProcess.js:139:34334)\n    at Module.require (node:internal/modules/cjs/loader:1240:19)\n    at Module.patchedRequire (/Users/XXX/.vscode/extensions/sapse.sap-ux-application-modeler-extension-1.14.5/dist/extension-min.js:927:9530)\n    at Module.r.require (/Users/XXX/.vscode/extensions/sapos.yeoman-ui-1.16.3/dist/extension.js:152501:22)\n    at g (/Applications/Visual Studio Code.app/Contents/Resources/app/out/bootstrap-fork.js:2:647)\n    at Object.get [as ui5-app:app] (/Users/XXX/.vscode/extensions/sapos.yeoman-ui-1.16.3/dist/extension.js:144696:28)\n    at e.exports.get (/Users/XXX/.vscode/extensions/sapos.yeoman-ui-1.16.3/dist/extension.js:144706:39)\n    at B.get (/Users/XXX/.vscode/extensions/sapos.yeoman-ui-1.16.3/dist/extension.js:144317:28)\n    at B.create (/Users/XXX/.vscode/extensions/sapos.yeoman-ui-1.16.3/dist/extension.js:144360:30)\n    at m.<anonymous> (/Users/XXX/.vscode/extensions/sapos.yeoman-ui-1.16.3/dist/extension.js:150381:27)\n    at Generator.next (<anonymous>)\n    at o (/Users/XXX/.vscode/extensions/sapos.yeoman-ui-1.16.3/dist/extension.js:150214:23)",
  "time": "2024-09-04T04:19:17.169Z"
}

So, basically the environment in which the generators are executed seem to assume CJS modules and not ESM and ESMs are not supported there as import or dynamic import import(...) statements are not supported there. Are there any intentions to support ESM-based generators by the Template Wizard in the future? I would assume that more and more generators will adopt to ESM as it is now also in general supported by Node.js.

petermuessig commented 2 months ago

@idoprz @tomer-epstein @rimasirich @alex-gilin - maybe one of you can have a look into this issue and we can discuss this? I'm still unsure what to do? Transpiling the code back to CJS is also an option but this would also mean to downport dependencies as dynamic imports can't be used as well. I need to understand the way you run the template a bit more in detail to judge what the best option would be for Easy UI5 to run again with the Template Wizard. THX.

Cc: @nicoschoenteich

idoprz commented 2 months ago

@petermuessig It seems that adding support for ESM is high effort task. I suggest we have a meeting with @rimasirich , @alex-gilin & Avital the PO to discuss the options

petermuessig commented 2 months ago

@idoprz - I'm open to meet and discuss the options. 👍