Cloudflare Workers - Build time constants with Wrangler

Replacing global identifiers with build-time constants has a few uses - inserting a Git hash or release number for using with Sentry SDKs or eliding away code that is only meant for development & staging environments.

Wrangler, the Cloudflare Workers command-line tool, exposes a few esbuild APIs that we can interact with. The two we're interested in for the sake of this scenario are define and minify - let's take a look.

define

The define feature allows us to replace a global identifier with a constant expression - let's say replacing DEV with true or ENVIRONMENT with "staging".

Let's try replacing ENV with a string value of "dev":

name = "test-worker"
main = "src/index.ts"
compatibility_date = "2023-01-11"

[define]
ENV = '"prod"'

[env.dev.define]
ENV = '"dev"'
wrangler.toml

The value of a key under the define table is the literal substitution - meaning, if you wish to substitute ENV with a string value of "dev" then you would write ENV = '"dev"' - as otherwise it would be replaced with a variable called dev which would of course be undefined.

Here's our script:

declare const ENV: string

export default <ExportedHandler> {
  async fetch() {
    if (ENV === "dev") {
      console.log("i'm dev")
    }

    if (ENV === "staging") {
      console.log("i'm staging")
    }

    return new Response();
  },
};

If we do a dry-run publish with Wrangler to see the built script, we can see that the conditionals have been replaced with true and false respectively:

// src/index.ts
var src_default = {
  async fetch() {
    if (true) {
      console.log("i'm dev");
    }
    if (false) {
      console.log("i'm staging");
    }
    return new Response();
  }
};
export {
  src_default as default
};
//# sourceMappingURL=index.js.map
npx wrangler publish --env dev --dry-run --outdir ./ && cat index.js

This is great - but the if (false) branch is dead code since that condition will never be true. Can we get rid of it?

minify

Of course we can! If we add --minify to our Wrangler dry-run publish, we'll see that the if (false) branch has been elided away.

var e={async fetch(){return console.log("i'm dev"),new Response}};export{e as default};
//# sourceMappingURL=index.js.map
npx wrangler publish --env dev --dry-run --outdir ./ --minify && cat index.js

This can also be added to your Wrangler.toml on a per-environment basis, such as minifying production code but not development, with the minify = true|false key.