Phatso
Phatso•2y ago

Import from variable path?

Howdy - I'm trying to make my Cloudflare Workers app self-hostable in a Docker Container. To do this, I'm going to run it with Deno when self-hosting. Ideally I would like to change none of my actual application code and defer any environment-specific setup to different files. i.e.:
src/
- index.js
- selfhost.js
- cloudflare.js
src/
- index.js
- selfhost.js
- cloudflare.js
And then:
// index.js
import { app, serve } from (isSelfHost ? "./selfhost.js" : "./cloudflare.js")
// index.js
import { app, serve } from (isSelfHost ? "./selfhost.js" : "./cloudflare.js")
I know this doesn't work, so my question is how do I achieve something like this? Ultimately the problem is I can't be requiring Deno packages in cloudflare workers or vice versa.
2 Replies
Moomoo
Moomoo•2y ago
You can use dynamic imports: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/import const {app, serve} = await import(isSelfHost ? "./selfhost.js" : "./cloudflare.js");
import() - JavaScript | MDN
The import() syntax, commonly called dynamic import, is a function-like expression that allows loading an ECMAScript module asynchronously and dynamically into a potentially non-module environment.
Phatso
PhatsoOP•2y ago
Amazing, thank you! Unfortunately Cloudflare doesn't like it (top-level imports) But I was able to rework my setup. My new structure is like:
myProject/
- index.js
- setup_app.js
- docker/
- selfhost.js
myProject/
- index.js
- setup_app.js
- docker/
- selfhost.js
// index.js
import { app, serve } from "./setup_app.js"
// index.js
import { app, serve } from "./setup_app.js"
And then in my Dockerfile
...
COPY ./index.js /app/index.js
COPY ./docker/selfhost.js /app/setup_app.js
...
COPY ./index.js /app/index.js
COPY ./docker/selfhost.js /app/setup_app.js
So basically I just make the files behave the same way, but stub the setup_app.js with my selfhost.js in the container itself. I imagine there's a more elegant way to do this with esbuild or something but I'm just relieved to be done with it 😅