2
votes

I am currently having a svelte program that gets compiled to the corresponding, js and css files, which I am using in a separate html template string. That is getting used as part of an application's webview - it basically gets put into a iframe at the end inside that application.

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta chatset='UTF-8">
        <meta http-equiv="Content-Security-Policy" content="default-src img-src https: data:; style-src 'unsafe-inline' ${webview.cspSource}; script-src 'nonce-${nonce}';">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <link href="${styleResetUri}" rel="stylesheet">
        <link href="${styleMainUri}" rel="stylesheet">
        <link href="${styleMainPanel}" rel="stylesheet">
        <script nonce="${nonce}">
            const vscode = acquireVsCodeApi();
        </script>
    </head>
    <body>
        <main><App/></main>
        <script src="${scriptMainPanel}" nonce="${nonce}" />
        <script src="${gramJS}" nonce="${nonce}" />
    </body>
</html>

I have my rollup config setup such that whatever is in my svelte folders gets compiled to js and css as said above which I import in the lines.

The line <script src="${scriptMainPanel}" nonce="${nonce}" /> and <link href="${styleMainPanel}" rel="stylesheet"> are the places where I am importing the compiled code. Similarly, my css gets imported.

Notice that I am using the tag as the place to mount my app like so,

import App from "../components/MainPanel.svelte";

const app = new App({
    target: document.getElementsByTagName("App")[0],
});

export default app;

The Issue

It all works perfectly fine - it renders fine and all. But, the issue I am facing is that, the <script src="${gramJS}" nonce="${nonce}" /> that I have in the body of the html code above, is not seen finally. Is it that svelte removes all other tags? I have seen this normally if I have other p, h1 or other html tags in the body, they get removed - but I have targeted App here, so it should not get removed yeah?

If not is there any other way to include my script in that html? Maybe include it inside the pre-compiled files so that it stays even after the compiling?

Note That extra script import is itself a minified script as it is node and some reason I am not able to use it within svelte.

--Update 1--

After inspecting the rendered HTML, I have found that the extra script tag <script src="${gramJS}" nonce="${nonce}" /> gets shifted inside the script tag <script src="${scriptMainPanel}" nonce="${nonce}" />. I do not understand why, more like any other tags in the html gets pushed into the script that references the compiled svelte code.

1
You are not showing how you actually "render" the HTML template, but I don't think svelte is doing anything with it. The problem is likely that you are self-closing the <script> elements. Those are not self-closing elements, you always need a proper end tag: <script ...></script>. Give that a try. - Felix Kling
Oh! great I will try that out. But I do not render it. I just return this html template string which gets passed onto the vscode extension webview. I don't control it much. But, you see if I just enter normal html elements inside that body tag without the compiled svelte scripts, it works perfectly fine. - Rohan Asokan
I found out something after inspecting the rendered html, which I have update. - Rohan Asokan
Hey @FelixKling. You literally solved my problem. I converted them to <script></script> tags and it works like charm. Feel free to add an answer and I would be able to mark it up. Thank you so much. You just cleared the issue I had for 3 days now. <3 - Rohan Asokan

1 Answers

2
votes

<script> elements cannot be self-closing. I don't know how the browser corrects that but I suspect that the two script tags somehow interfere with each other.

Use a proper closing tag for both elements:

<script src="${scriptMainPanel}" nonce="${nonce}"></script>
<script src="${gramJS}" nonce="${nonce}"></script>