Debugging with svelte
Asked Answered
P

4

15

I'm trying to dig into Svelte 3 (v3.7.1) and it works quite well ... with a few stumbling blocks when it comes to including external CSS (bootstrap).

But nevertheless, one thing I cannot seem to wrap my head around is debugging the svelte app in my browser

I found a post on svelte github issues that stated that I just need to include {@debug} somewhere in my code in order to make the browser break at "that point" so I can debug and inspect current state.

But: This does not work at all. Even though the {@debug} is present, there is no breaking even though I have the developer tools open.

What do I have to do in order to debug my code?

EDIT: I figured you needed to know about my setup

I use a node/express web server that serves the compiled svelte client as app.use(express.static('svelteclient/public')) from the svelte project's subfolder.

Code excerpt:

<script>

   import { onMount } from 'svelte';

   let searches = ["angular", "deno", "svelte", "stencil"];
   let tweets = {};

   let currentImage = null;
   let currentYTUrl = "";

   for(let search of searches) {
      tweets[search] = [];
   }

   let socket = io();

   let modal = null;
   let ytmodal = null;

   onMount(() => {
      modal = UIkit.modal('#mymodal');
      ytmodal = UIkit.modal('#myytmodal');
   });

...
</script>

<style>
   .uk-panel-badge .uk-badge {
      cursor: pointer;
   }
</style>

{@debug}


<div class="uk-grid" data-uk-grid-margin>
   {#each searches as search}
   <div class={'uk-width-medium-1-' + searches.length}>
      ...
   </div>
   {/each}
</div>

Chrome version is 75.0.3770.142

Pembroke answered 7/8, 2019 at 9:2 Comment(4)
Make sure you're compiling with dev: true, otherwise {@debug ...} tags will be stripped outBorchert
If you mean dev: true in rollup.config.js -> plugins -> svelte() ... it doesn't work. But I found a way ... just npm run dev and then immediately stop the live reload serverPembroke
dev: true works if you also prevent the terser() plugin from runningPembroke
use svelte-watch, it allows monitoring components state using redux devtoolsBonis
P
6

Thank you for all your good hints

The problem was: When compiling for production, every debugger statement would be stripped from the resulting bundle.js

Solution: npm run dev instead and then immediately stop the live reload server in order to avoid weird URL compositions regarding socket.io

EDIT: Another solution:

Change rollup.config.js before running npm run build:

    plugins: [
        svelte({
            // Always enable run-time checks
            dev: true,
            ...
        }),
        ...
        // NOT use terser, otherwise debugger will be stripped!
        //production && terser()
Pembroke answered 7/8, 2019 at 11:55 Comment(0)
S
19

The {@debug} template syntax can be used as an alternative to console.log.

You can place it in your html code, and then open the devtools of your browser.

If your component goes through the @debug statement while the devtools are open, it will automatically pause the execution.

edit

if you have this svelte code

<script>
    let name = 'world';
</script>

{@debug name}

<h1>Hello {name}!</h1>

it will compile to

// more code
c: function create() {
    {
        const {  } = ctx;
        console.log({ name }); // <-- Note those 2 lines
        debugger; // <-- corresponding to the @debug statement
    }

    t0 = space();
    h1 = element("h1");
    t1 = text("Hello ");
    t2 = text(name);
    t3 = text("!");
    add_location(h1, file, 6, 0, 56);
}
// more code

It will run every time the component is rendered. Including the first time. It isn't bound to the value change if said value change doesn't trigger a new render.

If you want to bind a console log to a value change you need to use a reactive statement in your script

$: console.log(name);

or

$: value, console.log('value has been updated');

the debugger statement stop the script execution in both Chrome 76 and Firefox Quantum 68

Stolon answered 7/8, 2019 at 9:14 Comment(10)
No, it won't ... that's what I did and what I thought, but it just won't stop therePembroke
What's your browser? Because it's working fine in Chrome and FirefoxStolon
I have Google Chrome 75.0.3770.142 ... see my code in my latest editPembroke
I'm using Chrome, go to a new tab, open your devtools, go to this link using your own code. Because the debugger is pausing execution for me.Stolon
Confirmed ... so why is it not doing it in my setup? The code compiles just fine (no errors, no warnings) and runs perfectly. But @debug doesn't triggerPembroke
Any chance you would be using some kind of SSR ? Maybe try to check in your compiled file if you can find debugger or not.Stolon
No SSR involved here ... but the minified bundle.js does NOT contain a debugger statement. That might of course be the cause of my problem. Maybe it is because I used npm run build to build it?Pembroke
Yeah the debug statements are probably not included in the build version. Leaving console.logs in a production apps is often frowned upon, so it makes sense that the svelte compiler is scrapping them.Stolon
So then I'm lost ... the dev build won't run smoothly with my Node/Express setup (especially the socket.io part is doing all kinds of weird things). Can I maybe do a npm run dev without running a live server? I would just need the dev build ....Pembroke
If you want a Node/Express setup running svelte, you should take a look at sapper. Otherwise yeah, you should be able to run a dev build w/o a live serverStolon
P
6

Thank you for all your good hints

The problem was: When compiling for production, every debugger statement would be stripped from the resulting bundle.js

Solution: npm run dev instead and then immediately stop the live reload server in order to avoid weird URL compositions regarding socket.io

EDIT: Another solution:

Change rollup.config.js before running npm run build:

    plugins: [
        svelte({
            // Always enable run-time checks
            dev: true,
            ...
        }),
        ...
        // NOT use terser, otherwise debugger will be stripped!
        //production && terser()
Pembroke answered 7/8, 2019 at 11:55 Comment(0)
M
2

The {@debug} statement only triggers a breakpoint when the variable you debug changes. The documentation hints at that with the last paragraph, "The {@debug} tag without any arguments will insert a debugger statement that gets triggered when any state changes, as opposed to the specified variables." (see https://svelte.dev/docs#debug)

The following code stops at the breakpoint after 3 seconds.

<script>
  let name = 'world';

  setTimeout(() => {
    name = 'moon';
  }, 3000)
</script>

{@debug name}
<h1>Hello {name}!</h1>

A working example can be seen at https://svelte.dev/repl/761771bd8eb9462796bba3373dfa46c7?version=3.7.1

Miles answered 7/8, 2019 at 10:49 Comment(1)
Oh never mind, it also triggers the first time the page renders. If that doesn't work for you, please provide more details on your browser, version and ideally an example of your code.Miles
E
1

I'll also recommend the official dev tools browser extension from SvelteJS that allows you to:

  • browse components & templating logic
  • inspect props, state, and stores
  • modify state directly

Available for both

Eduino answered 14/6, 2023 at 23:13 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.