Wrangler.toml passing variables to JS with webpack

All, I’ve begun using Workers Sites to host my website. I’m now looking at adding some Worker-side logic for statistics and events and so forth. Unfortunately, I can’t seem to find any way to set a couple of variables in wrangler.toml, say under [env.production], and have those variables available from within the Javascript.

How is this usually done? I’m trying to set a descriptive version string, script name, and some other info (third party URLs, API keys, etc) which are different depending on if I’m pushing to dev or production.

Am I going about this wrong?

Ok, I slept on it a bit. Here’s my idea: For each of my KVs, I have a key stage which contains either development or production. My Workers check that at start because I got burned, once. :-/

Do most people store stage-specific configuration in their KVs? I’m thinking it’s not too insane, since it’ll get read frequently, it should be hot. If it becomes a problem reading and parsing it for each event, I could store it in a global, and just do a check on each event. To protect me from me, I’d include the stage for the config within the config, and compare it against the stage value of the KV store…

Is this similar to what other people do?

That’s currently what I do.

I have two domains. staging.domain.com and prod.domain.com

Then I have a KV for configs, one for staging and one for prod, on each Worker run I retrieve the KV and retrieve the current domain and apply the respective config. I don’t use globals though, I found it unreliable and easy to shoot yourself in the foot, depends on the use-case of course.

There’s some changes coming up in Wrangler that support secrets properly now though.

See here for details:

1 Like

Ah, ok. Good to hear, thanks @thomas4!

FTR: I’ve had good luck with globals, e.g.

var logs = []

function initlogs(rayid, a, b) {
    const ts = new Date()

    logs[rayid] = {
        "timestamp": ts.toISOString(),
        "rayid": rayid,
        "a": a,
        "b": b,
        "messages": []
    }
}

function _logit(rayid, level, msg) {
    const ts = new Date

    const m = {
        "timestamp": ts.toISOString(),
        "level": level,
        "message": msg,
    }

    logs[rayid].messages.push(m)
}

async function savelogs(rayid) {
    const key = `${logs[rayid].timestamp}/${rayid}`
    const logs_s = await JSON.stringify(logs[rayid], null, null)

    /* cleanup globals */
    logs[rayid] = {}
    delete logs[rayid]

    /* store in the KV for later retrieval */
    await LOGS.put(key, logs_s))
}

As long as you never set rayid global, it works great. This way, I get great logs, and only a single serious async (LOGS.put()), and then my server pulls log messages from the KV as a cron job.

I tried using globals for logs, which works fine as long as it’s a single request - but when it’s paralleled and within the same zone, they keep overlapping - thus adding multiple values/logs to the global array even though it should be a single log entry.

I remember you asked a question about rayid a while back, you mean that by using that, the request logs can be entirely unique?

yes, because the rayid is unique to each event. So by making the global object a hash table keyed on the rayid, the logging remains distinct per request. As long as you always append to logs[rayid].messages

[edit to add] And the cleanup with my savelogs(), above is critical to prevent the process from being killed due to memory pressure. Which, would take a while, but still, better to cleanup after yourself.

That’s really neat, wish id known about rayids as unique, it would have saved a lot of time.

I’ll get on testing it tomorrow morning, thanks for sharing!

Well, if you’ll recall, I don’t think I ever got a clear answer of the strength of the uniqueness property of the rayid. However, I view it as akin to a process id in that it’s unique enough for the lifetime of the process on the machine that it’s on.

On the other side of the coin, you see I use both the rayid and a timestamp as the key for the log storage. Just in case… :slight_smile:

@thomas4 if I could figure out how to send a DM in the Discourse thing, I’d send you a link to the WIP code. I guess I’m making a node.js module? I dunno. It seems after six months+ I’m finally figuring out the JS-way. :slight_smile: