Quick Edit is a development experience for Cloudflare Workers, embedded right within the Cloudflare dashboard. Itâs the fastest way to get up and running with a new worker, and lets you quickly preview and deploy changes to your code.
Weâve spent a lot of recent time working on upgrading the local development experience to be as useful as possible, but the Quick Edit experience for editing Workers has stagnated since the release of workers.dev. Itâs time to give Quick Edit some love and bring it up to scratch with the expectations of todayâs developers.
Before diving into whatâs changedâa quick overview of the current Quick Edit experience:
We used the robust Monaco editor, which took us pretty farâitâs even what VSCode uses under the hood! However, Monaco is fairly limited in what it can do. Developers are used to the full power of their local development environment, with advanced IntelliSense support and all the power of a full-fledged IDE. Compared to that, a single file text editor is a step-down in expressiveness and functionality.
VSCode for Web
Today, weâre rolling out a new Quick Edit experience for Workers, powered by VSCode for Web. This is a huge upgrade, allowing developers to work in a familiar environment. This isnât just about familiarity thoughâusing VSCode for Web to power Quick Edit unlocks significant new functionality that was previously only possible with a local development setup using Wrangler.
Support for multiple modules!
Cloudflare Workers released support for the Modules syntax in 2021, which is the recommended way to write Workers. It leans into modern JavaScript by leveraging the ES Module syntax, and lets you define Workers by exporting a default object containing event handlers.
export default { async fetch(request, env) { return new Response("Hello, World!") } }
There are two sides of the coin when it comes to ES Modules though: exports and imports. Until now, if you wanted to organise your worker in multiple modules you had to use Wrangler and a local development setup. Now, youâll be able to write multiple modules in the dashboard editor, and import them, just as you can locally. We havenât enabled support for importing modules from npm yet, but thatâs something weâre actively exploringâstay tuned!
Edge Preview
When editing a worker in the dashboard, Cloudflare spins up a preview of your worker, deployed from the code youâre currently working on. This helps speed up the feedback loop when developing a worker, and makes it easy to test changes without impacting production traffic (see also, wrangler dev).
However, the in-dashboard preview hasnât historically been a high-fidelity match for the deployed Workers runtime. There were various differences in behaviour between the dashboard preview environment and a deployed worker, and it was difficult to have full confidence that a worker that worked in the preview would work in the deployed environment.
That changes today! Weâve changed the dashboard preview environment to use the same system that powers wrangler dev
. This means that your preview worker will be run on Cloudflareâs global network, the same environment as your deployed workers.
Helpful error messages
In the previous dashboard editor, the experience when your code throws an error wasnât great. Unless you wrap your worker code in a try-catch handler, the preview will show a blank page when your worker throws an error. This can make it really tricky to debug your worker, and is pretty frustrating. With the release of the new Quick Editor, we now wrap your worker with error handling code that shows helpful error pages, complete with error stack traces and detailed descriptions.
Typechecking
TypeScript is incredibly popular, and developers are more and more used to writing their workers in TypeScript. While the dashboard editor still only allows JavaScript files (and youâre unable to write TypeScript directly) we wanted to support modern typed JavaScript development as much as we could. To that end, the new dashboard editor has full support for JSDoc TypeScript syntax, with the TypeScript environment for workers preloaded. This means that writing code with type errors will show a familiar squiggly red line, and Cloudflare APIs like HTMLRewriter will be autocompleted.
How we built it
It wouldnât be a Cloudflare blog post without a deep dive into the nuts and bolts of what weâve built!
First, an overviewâhow does this work at a high level? We embed VSCode for Web in the Cloudflare dashboard as an iframe
, and communicate with it over a MessageChannel
. When the iframe
is loaded, the Cloudflare dashboard sends over the contents of your worker to a VSCode for Web extension. This extension seeds an in-memory filesystem from which VSCode for Web reads. When you edit files in VSCode for Web, the updated files are sent back over the same MessageChannel
to the Cloudflare dashboard, where theyâre uploaded as a previewed worker to Cloudflareâs global network.
As with any project of this size, the devil is in the details. Letâs focus on a specific area âhow we communicate with VSCode for Webâs iframe
from the Cloudflare dashboard.
The MessageChannel
browser API enables relatively easy cross-frame communicationâin this case, from an iframe embedder to the iframe itself. To use it, you construct an instance and access the port1
and port2
properties:
const channel=new MessageChannel() // The MessagePort you keep a hold of channel.port1 // The MessagePort you send to the iframe channel.port2
We store a reference to the MessageChannel
to use across component renders with useRef()
, since React would otherwise create a new MessageChannel
instance with every render.
With that out of the way, all that remains is to send channel.port2
to VSCode for Webâs iframe, via a call to postMessage()
.
// A reference to the iframe embedding VSCode for Web const editor=document.getElementById("vscode") // Wait for the iframe to load editor.addEventListener('load', ()=> { // Send over the MessagePort editor.contentWindow.postMessage('PORT', '*', [ channel.port2 ]); });
An interesting detail here is how the MessagePort
is sent over to the iframe. The third argument to postMessage()
indicates a sequence of Transferable objects. This transfers ownership of port2
to the iframe, which means that any attempts to access it in the original context will throw an exception.
At this stage the dashboard has loaded an iframe containing VSCode for Web, initialised a MessageChannel
, and sent over a MessagePort
to the iframe. Letâs switch contextâthe iframe now needs to catch the MessagePort
and start using it to communicate with the embedder (Cloudflareâs dashboard).
window.onmessage=(e)=> { if (e.data==="PORT") { // An instance of a MessagePort const port=e.ports[0] } };
Relatively straightforward! With not that much code, weâve set up communication and can start sending more complex messages across. Hereâs an example of how we send over the initial worker content from the dashboard to the VSCode for Web iframe:
// In the Cloudflare dashboard // The modules that make up your worker const files=[ { path: 'index.js', contents: ` import { hello } from "./world.js" export default { fetch(request) { return new Response(hello) } }` }, { path: 'world.js', contents: `export const hello="Hello World"` } ]; channel.port1.postMessage({ type: 'WorkerLoaded', // The worker name name: 'your-worker-name', // The worker's main module entrypoint: 'index.js', // The worker's modules files: files });
If youâd like to learn more about our approach, you can explore the code weâve open sourced as part of this project, including the VSCode extension weâve written to load data from the Cloudflare dashboard, our patches to VSCode, and our VSCode theme.
Weâre not done!
This is a huge overhaul of the dashboard editing experience for Workers, but weâre not resting on our laurels! We know thereâs a long way to go before developing a worker in the browser will offer the same experience as developing a worker locally with Wrangler, and weâre working on ways to close that gap. In particular, weâre working on adding Typescript support to the editor, and supporting syncing to external Git providers like GitHub and GitLab.
Weâd love to hear any feedback from you on the new editing experienceâcome say hi and ask us any questions you have on the Cloudflare Discord!
Source: cloudflare.com