inception-project / inception

INCEpTION provides a semantic annotation platform offering intelligent annotation assistance and knowledge management.
https://inception-project.github.io
Apache License 2.0
585 stars 149 forks source link

Multiple Vue components on one page #2101

Closed UWinch closed 3 years ago

UWinch commented 3 years ago

Is your feature request related to a problem? Please describe. Currently we cannot add more than one Vue component to a page with the VueBehavior (or VueComponent). It results in a Uncaught SyntaxError: Identifier 'loadModule' has already been declared error and the second component does not show.

Describe the solution you'd like We are using vue3-sfc-loader with related init script to create the Vue app and load the module. We could check if this is already done and then only add the new Vue component to the already existing Vue app.

reckart commented 3 years ago

Actually, it should not be a problem to run multiple Vue apps on a single page: https://stackoverflow.com/a/49740866/2511197

It looks more to me as if the loading of the vue3-sfc-loader itself somehow happens multiple times. Normally, that should also no happen if the JS is loaded via a Wicket JSResource. But we'd need to check what happens exactly.

reckart commented 3 years ago

I'd say the problem may be this code here in VueBehavior.java:

StringBuilder script = new StringBuilder();
        script.append("const { loadModule } = window['vue3-sfc-loader'];\n");
        script.append("const options = {\n");
        script.append("  moduleCache: {\n");
        script.append("    vue: Vue\n");
        script.append("  },\n");
        script.append("  async getFile(url) {\n");
        script.append("    const res = await fetch(url);\n");
        script.append("    if ( !res.ok )\n");
        script.append("      throw Object.assign(new Error(url+' '+res.statusText), { res });\n");
        script.append("    return await res.text();\n");
        script.append("  },\n");
        script.append("  addStyle() {},\n");
        script.append("};\n");

If this is executed in the global page context, then the second time it would be called (i.e. when the behavior is used on a second component), then it could clash. If we can use a local scope for the variables used in the call, I would expect it to fix the issue.