denoflare icon indicating copy to clipboard operation
denoflare copied to clipboard

Enable debugging through the --inspect protocol

Open marshallswain opened this issue 3 years ago • 11 comments

I've browsed through the denoflare CLI code for serve and I'm not sure where exactly this would be enabled. It would be so amazing to be able to hit breakpoints inside the worker, similar to what is mentioned here for deno --inspect: https://deno.land/manual/getting_started/debugging_your_code

marshallswain avatar Nov 21 '21 06:11 marshallswain

Adding --inspect to the deno command works. Using the example from: https://denoflare.dev/guides/serve run:

deno run --inspect --unstable --allow-read --allow-net --allow-env https://raw.githubusercontent.com/skymethod/denoflare/v0.4.4/cli/cli.ts serve hello-local

Then go to chrome://inspect and you should see:

image

Inspect the worker target.

As there don't appear to be any source maps finding the code can be a little awkward so add a debugger; statement at the start of the fetch function, open the url in another browser tab, and the inspector will pause at the debugger statement.

(The example configuration also seems to serve favicon.ico request from the same endpoint so I see it stopping twice each time I refresh the browser tab.)

// index.ts
export default {
    async fetch(request: Request, env: any) {
       debugger;
        try {
            return new Response('hi')
        } catch (e) {
            return new Response(e.message)
        }
    },
}
// .denoflare
{
    "$schema": "https://raw.githubusercontent.com/skymethod/denoflare/v0.4.4/common/config.schema.json",
    "scripts": {
        "hello-local": {
            "path": "index.ts",
            "localPort": 3030
        }
    }
}

lrowe avatar Mar 20 '22 02:03 lrowe

Thanks for this @lrowe - if you run denoflare serve with a config specifying "localIsolation": "none", this might give you a better debugging experience (with source maps), since the script code will be imported directly into the main Deno isolate.

You'll lose module reloading, however - so will have to restart the process on any changes. Probably ok for debugging loops.

By default, scripts run in "localIsolation": "isolate" mode (an option at the Script level), which takes a snapshot of your code and runs it in a permissionsless Deno worker - which is safer, and more closely resembles the cloudflare production environment (no Deno global etc), and crucially allows us to provide automatic module reloading on change (denoflare just tears down the old permissionless worker and recreates it).

As far as I can tell, there is no way to specify sourcemaps when instantiating a Deno Worker from a blob url, but anyone can figure it out, I'd love to be able to pass these through. I have them (Deno.emit gives them to me), but I can't tell the Worker about them.

Hope that helps!

johnspurlock-skymethod avatar Mar 23 '22 14:03 johnspurlock-skymethod

@johnspurlock-skymethod looking at the sources while debugging a regular Deno worker it looks like the javascript code gets generated with inline source maps. I assume it would be possible to do the same here by supplying compilerOptions: { inlineSourceMap: true } to Deno.emit in https://github.com/skymethod/denoflare/blob/master/cli/emit.ts#L3.

  • https://github.com/denoland/deno/issues/4765#issuecomment-614282334
  • https://deno.land/[email protected]/typescript/runtime
  • https://www.typescriptlang.org/docs/handbook/compiler-options.html

(I found this project while looking for examples of using Deno workers but am not actually using it or the Cloudflare platform.)

lrowe avatar Mar 23 '22 22:03 lrowe

Looking into getting this working inside vscode.

You should run serve in no isolation mode (no hot reloading) - which means setting "localIsolation": "none" inside your .denoflare file for that script config. You'll also need to use the file:// scheme in the "path" to your worker, otherwise any absolute slashed path will be resolved against the program url, which in this case is the https denoflare release version.

Then just set a breakpoint inside your fetch function, and it seems to work as expected. Can edit the breakpoint with the expression !request.url.endsWith('.ico'); to filter out favicon requests.

.denoflare

...
    "myworker": {
        "path": "file:///path/to/myworker/worker.ts",
        "localIsolation": "none"
    },
...

.vscode/launch.json

{
    "version": "0.2.0",
    "configurations": [
        {
            "request": "launch",
            "name": "denoflare serve myworker",
            "type": "node",
            "program": "https://raw.githubusercontent.com/skymethod/denoflare/v0.5.7/cli/cli.ts",
            "args": [ "serve", "myworker" ],
            "cwd": "${workspaceFolder}",
            "runtimeExecutable": "deno",
            "runtimeArgs": [
                "run",
                "--unstable",
                "--inspect",
                "--allow-all",
            ],
            "attachSimplePort": 9229,
            "outputCapture": "std"
        }
    ]
}

If localIsolation was settable via the command line, the .denoflare config would be unnecessary for simple scripts. I'll include a command line flag for local isolation mode in the next release.

johnspurlock-skymethod avatar Aug 17 '22 23:08 johnspurlock-skymethod

Was looking if localIsolation was present yet, not seeing it? Is this still the recommended way to start vscode debugging?

JustinGrote avatar Dec 08 '22 21:12 JustinGrote

Yea it's there image

Still the recommended approach, so your code doesn't change from underneath you with hot reload.

johnspurlock-skymethod avatar Dec 08 '22 21:12 johnspurlock-skymethod

I meant the command line switch, as opposed to the .denoflare config item (which I'm currently using)

If localIsolation was settable via the command line, the .denoflare config would be unnecessary for simple scripts. I'll include a command line flag for local isolation mode in the next release.

JustinGrote avatar Dec 08 '22 23:12 JustinGrote

Ah ok yes, no command line option for that yet. I have some time to implement that now...

johnspurlock-skymethod avatar Dec 08 '22 23:12 johnspurlock-skymethod

Ok, just pushed change 43c4a7ad56ac8a3b34c284920ce57ce1103a7c95 that should do the trick. Can you try it out on your side?

Install denoflare as of 43c4a7ad56ac8a3b34c284920ce57ce1103a7c95 to try it out (replace the release tag with the commit hash however you installed Denoflare)

johnspurlock-skymethod avatar Dec 08 '22 23:12 johnspurlock-skymethod

I have a denoflare alias that just runs off the master branch so I should be able to test.

JustinGrote avatar Dec 09 '22 00:12 JustinGrote

Works great, also I was able to use an import map to get around the need to specify file:// in the .denoflare config:

import-map.json

{
	"imports": {
		"src/": "./src/"
	}
}

.denoflare

{
	"$schema": "https://raw.githubusercontent.com/skymethod/denoflare/master/common/config.schema.json",
	"scripts": {
		"pwsh-gallery-preview": {
			"path": "src/worker.ts",
			"customDomains": [
				"preview.pwsh.gallery"
			],
			"compatibilityDate": "2022-12-08",
		}
	}
}

launch.json

{
	"version": "0.2.0",
	"configurations": [
		{
			"request": "launch",
			"name": "denoflare",
			"type": "node",
			"cwd": "${workspaceFolder}",
			"runtimeExecutable": "deno",
			"runtimeArgs": [
				"run",
				"--unstable",
				"--inspect",
				"--allow-all",
				"--import-map=import-map.json"
			],
			"resolveSourceMapLocations": [
				"${workspaceFolder}/src/**",
			],
			"program": "https://raw.githubusercontent.com/skymethod/denoflare/43c4a7ad56ac8a3b34c284920ce57ce1103a7c95/cli/cli.ts",
			"args": [
				"serve",
				"pwsh-gallery-preview",
				"--local-isolation",
				"none"
			],
			"attachSimplePort": 9229,
			"outputCapture": "std",
		}
	]
}

EDIT: There are some source map errors too still but thats a minor cleanup, breakpoints for the main code works. Maybe somehow have a "Just My Code" option like Node does.

EDIT 2: New source map setup seems to work fine, you'll probably need something for the new native npm functionality just added in deno 1.18 if you use it.

JustinGrote avatar Dec 09 '22 01:12 JustinGrote