Migrating a Worker off a vendored src/core/

For a Worker that keeps its framework layer in the repository as src/core/. After this migration, that directory is gone and the same code arrives as two libraries.

What moved where

Was Is now
src/core/system/** @bayudwiyansatria/core
src/core/cloudflare/** @bayudwiyansatria/cloudflare
src/core/http/** @bayudwiyansatria/cloudflare/middlewares
src/core/index.ts the two package barrels

Everything else — app.ts, controllers/, services/, models/, config/*Config.ts, utils/ — stays exactly where it is.

1. Install

npm install @bayudwiyansatria/core @bayudwiyansatria/cloudflare
rm -rf src/core

2. Rewrite the imports

Every core/… specifier becomes one of three package imports. The rule is which layer the symbol came from:

// before
import { Logger } from 'core/system/observability/Logger'
import { KVService } from 'core/cloudflare/services/KVService'
import { SecurityMiddleware } from 'core/http/SecurityMiddleware'

// after
import { Logger } from '@bayudwiyansatria/core'
import { KVService } from '@bayudwiyansatria/cloudflare'
import { SecurityMiddleware } from '@bayudwiyansatria/cloudflare/middlewares'

Both packages export from a single barrel, so the deep paths collapse.

3. Register the configuration surface

This is the substantive change. resolve() used to import src/config/ directly; a package cannot reach into its consumer, so the application now hands the surface to the kernel instead.

Add one call at the end of src/config/index.ts, after defaults and overrides are declared:

import { configure } from '@bayudwiyansatria/core'

// …existing defaults and overrides…

configure(defaults, overrides)

Then make src/app.ts depend on it, so the module graph guarantees the ordering:

import 'config' // must stay above the rest — see below

import { Hono } from 'hono'

Why the side-effect import rather than a call in src/index.ts. ES imports are hoisted and evaluated before any statement runs, so a configure() call written in the composition root executes after app.ts has already initialised — and app.ts reads configuration while initialising, because SecurityMiddleware.apply needs the protected pattern and the allowed origins at the moment it registers routes. Putting the call in config/ and naming that dependency in app.ts makes the module graph enforce the order, since a module is always fully evaluated before its importers.

If you skip this, the Worker throws ConfigurationError on startup with a message naming both likely causes.

4. Extend CloudflareEnv

Env used to be an ambient global that src/core/ and src/types/ both declared into. A package cannot merge into a consumer's global scope, so it is now an exported interface you extend.

Rename src/types/env.d.ts to src/types/Env.ts and change the declaration:

import type { CloudflareEnv } from '@bayudwiyansatria/cloudflare'

export interface Env extends CloudflareEnv {
  LOG_LEVEL?: string
  API_AUTH_TOKEN_HEADER: string
  API_AUTH_TOKEN_VALUE: string
}

Env is no longer global, so every file that references it needs an import:

import type { Env } from 'types/Env'

ctx.env still offers every member, Cloudflare's and yours.

5. Switch module resolution

Both packages publish an exports map, and the ./middlewares subpath does not resolve under classic Node resolution:

// tsconfig.json
"moduleResolution": "Bundler"

Bundler is the accurate description of what happens — Rollup and Wrangler resolve these imports, not Node, and both honour exports.

6. Drop the obsolete lint boundary

eslint.config.ts had a no-restricted-imports block guarding src/core/system/ and an exemption for src/core/system/config/resolve.ts. Both refer to files that no longer exist; the boundary they protected is now enforced inside the packages. Delete them, and consider a leaf-layer rule over models/, types/, utils/, and config/ in their place.

Verify

npx tsc --noEmit
npm run lint
npm run build

Then run the Worker locally with npx wrangler dev and exercise a protected route. A 401 without the configured key and a successful response with it confirms that the middleware still composes across the package boundary. A startup ConfigurationError means step 3 is incomplete.

If you vendored changes into src/core/

Diff your copy against the libraries before deleting it. Contribute framework-layer changes to the corresponding library rather than re-vendoring them, or the next upgrade will silently revert them.

results matching ""

    No results matching ""