How to locally run my cloudflare worker serverless function, during development?
Asked Answered
D

3

5

I managed to deploy my first cloudflare worker using serverless framework according to https://serverless.com/framework/docs/providers/cloudflare/guide/ and it is working when I hit the cloud.

During development, would like to be able to test on http://localhost:8080/*

What is the simplest way to bring up a local http server and handle my requests using function specified in serverless.yml?

I looked into https://github.com/serverless/examples/tree/master/google-node-simple-http-endpoint but there is no "start" script.

There seem to be no examples for cloudflare on https://github.com/serverless/

Ducal answered 23/12, 2018 at 7:10 Comment(0)
E
7

At present, there is no way to run the real Cloudflare Workers runtime locally. The Workers team knows that developers need this, but it will take some work to separate the core Workers runtime from the rest of Cloudflare's software stack, which is otherwise too complex to run locally.

In the meantime, there are a couple options you can try instead:

Third-party emulator

Cloudworker is an emulator for Cloudflare Workers that runs locally on top of node.js. It was built by engineers at Dollar Shave Club, a company that uses Workers, not by Cloudflare. Since it's an entire independent implementation of the Workers environment, there are likely to be small differences between how it behaves vs. the "real thing". However, it's good enough to get some work done.

Preview Service API

The preview seen on cloudflareworkers.com can be accessed via API. With some curl commands, you can upload your code to cloudflareworkers.com and run tests on it. This isn't really "local", but if you're always connected to the internet anyway, it's almost the same. You don't need any special credentials to use this API, so you can write some scripts that use it to run unit tests, etc.

Upload a script called worker.js by POSTing it to https://cloudflareworkers.com/script:

SCRIPT_ID=$(curl -sX POST https://cloudflareworkers.com/script \
  -H "Content-Type: text/javascript" --data-binary @worker.js | \
  jq -r .id)

Now $SCRIPT_ID will be a 32-digit hex number identifying your script. Note that the ID is based on a hash, so if you upload the exact same script twice, you get the same ID.

Next, generate a random session ID (32 hex digits):

SESSION_ID=$(head -c 16 /dev/urandom | xxd -p)

It's important that this session ID be cryptographically random, because anyone with the ID will be able to connect devtools to your preview and debug it.

Let's also define two pieces of configuration:

PREVIEW_HOST=example.com
HTTPS=1

These specify that when your worker runs, the preview should act like it is running on https://example.com. The URL and Host header of incoming requests will be rewritten to this protocol and hostname. Set HTTPS=1 if the URLs should be HTTPS, or HTTPS=0 if not.

Now you can send a request to your worker like:

curl https://00000000000000000000000000000000.cloudflareworkers.com \
  -H "Cookie: __ew_fiddle_preview=$SCRIPT_ID$SESSION_ID$HTTPS$PREVIEW_HOST"

(The 32 zeros can be any hex digits. When using the preview in the browser, these are randomly-generated to prevent cookies and cached content from interfering across sessions. When using curl, though, this doesn't matter, so all-zero is fine.)

You can change this curl line to include a path in the URL, use a different method (like -X POST), add headers, etc. As long as the hostname and cookie are as shown, it will go to your preview worker.

Finally, you can connect the devtools console for debugging in Chrome (currently only works in Chrome unfortunately):

google-chrome https://cloudflareworkers.com/devtools/inspector.html?wss=cloudflareworkers.com/inspect/$SESSION_ID&v8only=true

Note that the above API is not officially documented at present and could change in the future, but changes should be relatively easy to figure out by opening cloudflareworkers.com in a browser and looking at the requests it makes.

Elissaelita answered 23/12, 2018 at 22:25 Comment(5)
Thank you for your awesome answer.Ducal
The Preview Service API options opens some interesting doors, will try to play with it some time.Ducal
Is there any way to add a wasm module?Infinitude
@Infinitude Yes, the multipart/form-data format used to upload script+WASM modules to the regular Cloudflare API is also supported by the cloudflareworkers.com/script API.Elissaelita
Just to let you know that there's a small typo in the docs at (developers.cloudflare.com/workers/api/resource-bindings/…), with application/javsacript instead of application/javascript (API call section).Infinitude
C
2

You may also be able to test locally by loading the Cloudflare worker as a service worker.

Note:

  • Use a local web server with https:. Workers won't load using file: or http: protocols.
  • Your browser will need to support workers, so you can't use IE.
  • Mock any Cloudflare-specific features, such as KV.

<!doctype html>
<html>

<head>
  <meta charset="utf-8">
</head>

<body>
  <!-- Service worker registration -->
  <script>
    if ('serviceWorker' in navigator) {
      // Register the ServiceWorker
      navigator.serviceWorker.register('/service-worker.js')
        .then(
          function(reg) {
            // Registration succeeded
            console.log('[registerServiceWorker] Registration succeeded. Scope is ' + reg.scope)
            window.location.reload(true)
          })
        .catch(
          function(error) {
            // Registration failed
            console.log('[registerServiceWorker] Registration failed with ' + error)
          })
    } else {
      console.log('[registerServiceWorker] Service workers aren\'t supported')
    }
  </script>
</body>

</html>
Charbonneau answered 5/7, 2019 at 2:28 Comment(0)
E
0

Dollar Share Club created Cloudworker. It is not actively maintained, but it is a way to run Cloudflare Workers locally.

You can read about it on the Cloudflare blog in guest post by the original maintainer of Cloudworker.

Enamour answered 21/3, 2020 at 16:36 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.