Debugging scripts on HTML pages dynamically generated by another HTTP server
- Dominant language
- Dart
- Stars
- 224
- Forks
- 94
- Avg merge
- 7h 14m
- Merged PRs (30d)
- 2
Description
**Please provide a way to debug client-side Dart scripts that are referenced by HTML pages produced by a separate HTTP server.**
It seems _webdev serve_ currently only supports debugging client-side Dart scripts referenced by static HTML files (which must also be served by the _webdev serve_ process). That makes it suitable for single-page-applications (where the HTML comes from a static file), but not for dynamically generated HTML pages (where the HTML comes from a separately running HTTP server).
# Possible options
There are a number of possible approaches. I've described three below, but there could be others.
In the following:
* The term "DHTML server" refers to the HTTP server that dynamically generates HTML pages containing _script_ tags that reference the Dart client-side scripts. The DHTML Server may be implemented in Dart or not. In production, those client-side scripts would be the JavaScript files produced by _webdev build_. In debugging (the subject of this issue) they will need to come from _webdev serve_.
* The term "associated resources" refers to the other resources loaded by the JavaScript files (e.g. the *.map, *.dcc.map, *.digest, $sseHandler resources). The DHTML server does not know what these are.
* The term "static content" refers to other files in the directory loaded by _webdev serve_ (e.g. CSS stylesheets and images). The DHTML server would refer to them in its HTML pages.
## Option 1: webdev serve proxies requests for the DHTML server
Add a feature to allow _webdev serve_ to forward all HTTP requests it does not handle to the DHTML server, and returning the result from the DHTML server as its response. Any HTTP requests it can handle (i.e. corresponding to files it finds in the directory and generated by the DDC) it serves itself without involving the DHTML server.
In this approach, all requests from the browser are sent to _webdev serve_, and only some of them are forwarded to the DHTML server.
1. The request for the HTML goes to _webdev serve_, which forwards the request to the DHTML server, the HTML is generated and returned to _webdev serve_, and _webdev serve_ returns it to the browser.
2. The browser parses the script tag in the HTML and finds a relative URL.
3. The browser then sends a request for the script to _webdev serve_, which returns the DDC generated JavaScript.
4. The browser also retrieves the associated resources from the _webdev serve_.
5. The browser also retrieves static content from the _webdev serve_.
### Status
Ths currently does not work, because _webdev server_ does not have a proxy feature.
This had been proposed in [issue #61](https://github.com/dart-lang/webdev/issues/61), but it should be reconsidered.
### Pros and cons
The DHTML server does not need to change between debugging and production - reducing the risk of introducing bugs, as well as the need for it to detect the mode it is runnning in. The DHTML server is configured to always try to serve the files produced by _webdev build_, but when debugging (when those files don't exist) the browser requests for them simply never reach the DHTML server.
## Option 2: The DHTML server proxies requests for webdev serve
Need to ensure it is possible for the DHTML server to identify requests that are intended for _webdev serve_, so it can forward them on to it. Meanwhile, all requests itself handles are processed normally (including returning 404 Not Found for requests neither it nor _webdev serve_ handles).
In this approach, all requests from the browser are sent to the DHTML server, and only some of them are fowarded to _webdev serve_.
1. The request for the HTML goes to the DHTML server, which generates and returns it.
2. The browser parses the script tag in the HTML and finds a relative URL.
3. The browser then sends a request for the script to the DHTML server, which forwards the request to _webdev serve_, which returns the DCC generated JavaScript, and the DHTML server returns it to the brower.
4. The browser also retrieves the associated resources from the DHTML server, which proxies the request through to _webdev serve_.
5. Requests for the static content are also proxied through the DHTML server to _webdev serve_.
### Status
This currently does not work, because the URLs for the associated resources are not documented. Implementers of the DHTML server cannot correctly implement a proxy that works with _webdev serve_.
I used to have this working with my DHTML server, for Dart 2.0 through to Dart 2.2. But changes with Dart 2.3 and/or webdev 2.0.5 broke it. Through trial and error, I've managed to proxy as many associated resources as I can. But there are still some URLs that don't work (e.g. the browser asks for _/packages/build_web_compilers/src/dev_compiler/dart_sdk.js.map_ but _webdev serve_ returns 404 Not found); and there is some strange behavour with paths (e.g. the Dart script is in "/scripts/foo.dart" and the browser requests "/foo.digests": that returns a 404 on _webdev serve_, but "/scripts/foo.digests" works).
This is being proposed in [issue #223](https://github.com/dart-lang/webdev/issues/223).
### Pros and cons
Requires every DHTML server to implement proxying, as well as to change its behaviour between debugging and production. Extra work required for every DHTML server.
There might be issues integrating this with third-party tools (e.g. when _webdev serve_ is lauched by WebStorm).
## Option 3: Support running webdev serve separately from the DHTML server
Ensure that all the content served by _webdev serve_ works when it comes from a different source (i.e. different host and/or port) from where the HTML came from.
In this approach, there is no proxying at all.
1. The browser requests the HTML page from the DHTML server.
2. The browser parses the script tag and finds a absolute URL (i.e. one with an explicit host/port for the _webdev serve_).
3. The browser then fetches the script from _webdev serve.
4. The browser fetches the associated resources from _webdev serve_.
5. The browser fetches the static content from the _webdev serve_.
### Status
This currently does not work, because the DCC generated JavaScript does not reference the associated content relative to where it got the DCC generated JavaScript from. That is, the browser tries to load some of the associate content from the DHTML server rather than from _webdev serve_. It is probably trying to find them from the page's base URL rather than relative to where the JavaScript came from.
### Pros and cons
Requires the DHTML server to change its behaviour between debugging and production: the URLs for the scripts and static content must be changed.
Browser cross-site loading issues need to be addressed. This might mean the DHTML server needs to send a different set of HTTP header when running in debugging vs production.
I prefer option 1.
Contributor guide
Research direction
Start by reviewing the webdev serve behavior described here and the linked discussions in issues #61 and #223. Compare the three proposed approaches, including proxying, separate hosts, and associated-resource URLs. Done means a decided and implemented path allows debugging Dart scripts in HTML generated by a separate HTTP server.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- dart
- Domain
- cli, tooling
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Needs clarification
- Newbie friendliness
- 25/100