Skip to content

Instantly share code, notes, and snippets.

@EverlastingBugstopper
Last active February 12, 2020 23:56
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save EverlastingBugstopper/81576f134477cdd9fb02cdc6959892a9 to your computer and use it in GitHub Desktop.
Save EverlastingBugstopper/81576f134477cdd9fb02cdc6959892a9 to your computer and use it in GitHub Desktop.
wrangler 1.8.0-rc.0 testing instructions

Getting Started

Installation

npm i @cloudflare/wrangler@1.8.0-rc.0 -g

Creating a project

The documentation below assumes you have some familiarity with Wrangler and are already developing Workers. If this is not the case that is OK, come back after you've read through our Quickstart and have gotten up and running with Wrangler.

DISCLAIMER

These features are all unstable and are not beholden to the same backwards compatibility guarantees as normal Wrangler releases.

Proceed with Caution!

Thanks!

Thanks for trying these features out! We're really excited, there's some really cool stuff in here :)

Features

There are three main features in this release candidate which each have their own individual testing instructions:

Testing wrangler dev

Usage

$ wrangler dev --help
👂  Start a local server for developing your worker

USAGE:
    wrangler dev [OPTIONS]

FLAGS:
        --help    Prints help information

OPTIONS:
    -e, --env <env>      environment to build
    -h, --host <host>    domain to test behind your worker. defaults to example.com
    -i, --ip <ip>        ip to listsen on. defaults to localhost
    -p, --port <port>    port to listen on. defaults to 8787

Workers

wrangler dev works very similarly to wrangler preview except that instead of opening your browser to preview your worker, it will start a server on localhost that will execute your worker on incoming HTTP requests. From there you can use cURL, Postman, your browser, or any other HTTP client to test the behavior of your worker before publishing it.

You should run wrangler dev from your worker directory, and if your worker makes any requests to a backend, you should specify the host with --host example.com.

From here you should be able to send HTTP requests to localhost:8787 along with any headers and paths, and your worker should execute as expected. Additionally, you should see console.log messages and exceptions appearing in your terminal. If either of these things don't happen, or you think the output is incorrect, please file an issue!

You should be able to use cURL, Postman, and any other HTTP client you'd like with this.

Workers Sites

wrangler dev should work with Workers Sites as well! If your site has some sort of configuration for the base url, you'll want to change them to point to localhost:8787 instead of the usual. Then you can just run wrangler dev with the same configuration options outlined above.

Feedback

If you'd like to provide feedback on wrangler dev, you can comment on this issue or file a new one! Just make sure to prefix your issue title with [dev].

Advanced

If you'd like for wrangler dev to listen on something other than localhost, you can pass something like --ip 127.0.0.1. This may be useful if you want to test with Docker.

You can also pass --port 8000 if you are already using port 8787 for something else.

Very Advanced

If you would like to try something that hasn't been tested yet, you could try to put a worker in front of something you're running on localhost.

Let's say you have a react app that you're developing locally and it's running on localhost:4000 and you want to also develop a worker at the same time (maybe play around with the new HTMLRewriter API a bit). Unfortunately, you cannot call $ wrangler dev --host localhost:4000 because Cloudflare's preview service needs the back end to be a public URL.

What you can do instead is spin up a TryCloudflare endpoint and pass that url to the --host argument of wrangler dev and then develop them in tandem.

This is a completely unpaved path that has not been tested at all so your mileage may vary. If you get it to work, we'd love to hear about it!

Testing Text / Secret Environment Variable Support

Adding secrets to a new project

To add a secret to your project, from project root run wrangler secret put <SECRET_NAME>, then type in your secret when prompted.

Now, modify your script to access the secret and return it in the response:

addEventListener('fetch', event => {
  event.respondWith(handleRequest(event.request))
})
/**
 * Respond with secret text
 * @param {Request} request
 */
async function handleRequest(request) {
  return new Response(`this was super secret! ${SECRET_NAME}`, {
    headers: { 'content-type': 'text/plain' },
  })
}

Run wrangler preview and you should see the browser pop up with the Cloudflare Workers preview and your response.

Note: secrets require authentication for use; if you see an error saying that wrangler fell back to unauthenticated preview, try adding your account_id to your wrangler.toml, or re-run wrangler config

Migrating secrets from KV

If you already have a project using KV to store secrets, it's easy to migrate to using secrets.

Let's use an example of a Worker that calls a third party API using an API token. It might look something like this if you are using KV to store the token:

example script:

async function handleRequest(request) {
  // With secrets, we can remove this line...
  let API_TOKEN = await KV_SECRETS.get("API_TOKEN")
  let init = {
    headers: {
      'content-type': 'application/json;charset=UTF-8',
      // ...and use our API_TOKEN variable directly here
      'authorization': `Bearer ${API_TOKEN}`,
    },
  }
  const response = await fetch('https://example.com/api/resource', init)
  const result = await response.json()
  return new Response(result, { headers: { 'content-type': 'application/json;charset=UTF-8' } })
}

addEventListener('fetch', event => {
  return event.respondWith(handleRequest(event.request))
})

example wrangler.toml:

name = "worker"
type = "javascript"
account_id = "youraccountid"
# remove this line
kv-namespaces = [{ id = "kvnamespaceid", binding = "KV_SECRETS" }]

From the command line, run wrangler secret put API_TOKEN. You will be prompted to provide your secret here. You can also pipe a secret to the command in the case of CI:

$ echo "secretapitokenshhdontpeek" | wrangler secret put API_TOKEN

Environments

Secrets are scoped to each script, so if you are developing across multiple environments in Wrangler, you'll want to set secrets individually on each environment. Like other Wrangler commands, secret commands accept an --env flag specifying the named environment in your wrangler.toml.

for example, given this wrangler.toml:

name = "worker"
type = "javascript"
account_id = "youraccountid"
[env.prod]

if you want to make the API_TOKEN secret for your prod env, you would run

$ wrangler secret put API_TOKEN --env prod

Adding plain text globals to your project

In addition to Secrets, you can also add simple text globals to your Worker. These can be handy when you want to use the same script file, but flip based on "environment". Let's try a simple one where we use a global "ENV" to tell our Worker whether it is in "production" or "staging".

addEventListener('fetch', event => {
  event.respondWith(handleRequest(event.request))
})
/**
 * Respond with hello worker text
 * @param {Request} request
 */
async function handleRequest(request) {
  return new Response(`this worker is running in ${ENV}`, {
    headers: { 'content-type': 'text/plain' },
  })
}

In your wrangler.toml, add the following:

name = "worker"
type = "javascript"
account_id = "your-account-id"
workers_dev = true
config = { ENV = "staging" }
[env.prod]
config = { ENV = "production" }

Now, if you run wrangler preview, you should get back the response this worker is running in staging. If you then run wrangler preview --env prod, you should get back the response this worker is running in production. ✨

Inheritance and config vars

Inheritance works for config vars very nicely; if i wanted to include a hostname in the above but wanted it to be the same between workers, you can add it to the top level and it will be inherited by all of the environments:

name = "worker"
type = "javascript"
account_id = "your-account-id"
workers_dev = true
config = { ENV = "staging", hostname = "https://example.com" }
[env.prod]
config = { ENV = "production" }

Both worker and worker-prod will have access to the variable hostname with value https://example.com.

Feedback

We love bug reports!!! But we also love any feedback on terminal messaging, including success messages, error messages, etc. Please feel free to file an issue with any feedback or bug reports.

Testing Multi Route Support

Update your wrangler.toml to use routes

If you are deploying Workers to a zone on Cloudflare (as opposed to deploying to a subdomain on workers.dev), you can now specify multiple routes in your wrangler.toml file! Just change your route key to routes and turn the value into an array:

name = "worker"
type = "javascript"
account_id = "youraccountid"
# change this line
# route = "example.com/foo/*"
# to this line
routes = ["example.com/foo/*", "example.com/bar/*"]
zone_id = "yourzoneid"

*Note: the route key is still supported for backward compatibility and simplicity; many Workers projects only need a single root level route. For everyone else, we created a new key.

Results

There are a few potential results of deploying to a route, and each route is deployed individually (we don't currently have a bulk upload endpoint for routes). Wrangler will tell you if:

  • your route was created successfully
  • your route already existed
  • the route you specified is already pointing to a different Worker
  • there was an error deploying to a route (includes the returned API error)

Did it work?

Once you have published, at minimum visit the zoned dashboard on Cloudflare to confirm that your routes table has been updated.

list routes / delete route commands

To list the routes associated with a zone, run wrangler route list

To delete a route from a zone, run wrangler route delete <route-id> (route ids are included in the output of wrangler route list).

These should respond appropriately to an --env flag, so if you have a wrangler.toml with

name = "my-worker"
[env.prod]
routes = ["example.com/other-path"]

Running wrangler route list --env prod will return the routes for the worker named my-worker-prod

Feedback

We are of course interested in bug reports!!! We also love any feedback on terminal messaging, including success messages, error messages, etc. Please feel free to file an issue with any feedback or bug reports.

Some details

Specify only a single deploy target (per environment)

Just like the route key, routes is incompatible with workers_dev. It also requires a zone_id value to deploy. Finally, you can only specify route or routes, not both.

Here are a couple of "evil" tomls:

name = "worker"
type = "javascript"
account_id = "youraccountid"
routes = ["example.com/foo/*", "example.com/bar/*"]
zone_id = "" # zone_id is required to deploy to routes
name = "worker"
type = "javascript"
account_id = "youraccountid"
workers_dev = true # you must specify either routes or a workers_dev deploy, not both
routes = ["example.com/foo/*", "example.com/bar/*"]
zone_id = "yourzoneid"
name = "worker"
type = "javascript"
account_id = "youraccountid"
route = "example.com/*" # you must specify either route or routes, not both
routes = ["example.com/foo/*", "example.com/bar/*"]
zone_id = "yourzoneid"

Environments

While your zone_id can be specified once at the top level and used across all environments, neither the route key nor the routes key should inherit; if you specify a zoned deploy in an environment, you must specify either route or routes.

bad:

name = "worker"
type = "javascript"
account_id = "youraccountid"
routes = ["example.com/foo/*", "example.com/bar/*"]
zone_id = "yourzoneid"

[env.foo]
# you need to include a `route | routes` entry here

good:

name = "worker"
type = "javascript"
account_id = "youraccountid"
routes = ["example.com/foo/*", "example.com/bar/*"]
zone_id = "yourzoneid"

[env.foo]
routes = ["foo.example.com/foo/*", "foo.example.com/bar/*"]

No null workers

This version does not support the concept of "null" workers.

@ashleymichal
Copy link

if your worker makes any requests to a backend, you should specify the host with --host example.com.

i don't quite understand this; i assume you mean if your worker has an origin?

@EverlastingBugstopper
Copy link
Author

@ashleymichal yes that's correct.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment