cloudflareserverless-frameworkserverlesscloudflare-workersserverless-plugins

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


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/


Solution

  • 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.