adminjs
adminjs copied to clipboard
[Bug]: Issue with AdminJSOptions.env when pre-bundling for deployment
Contact Details
No response
What happened?
When I bundle for deployment I host all my static/public assets on a CDN. Not just the js files adminJS uses, but also images, css, config etc.
To that end, in my code I dynamically build the urls based on an environment variable CDN_PATH, which is really only available on the server, as its part of the build automation to create that.
On the UI side, I tried passing this down to the components using AdminJSOptions.env:
but it doesnt seem this this is passed on when rendering the app using bundled files:
Almost everything works, except when I'm using a component that requires a url source, like an <img>
tag, for example.
Since the node app is the one initiating the app rendering, even if it ultimately uses components fromt he CDN, couldnt it still pass the adminjs env info tot he frontend for use by the react app?
Bug prevalence
Always
AdminJS dependencies version
"dependencies": { "@adminjs/bundler": "^3.0.0", "@adminjs/express": "^6.1.0", "@adminjs/prisma": "^5.0.1", "@adminjs/themes": "^1.0.1", "@adminjs/upload": "^4.0.1", "@aws-sdk/client-api-gateway": "^3.465.0", "@aws-sdk/client-cognito-identity-provider": "^3.468.0", "@fortawesome/fontawesome-free": "^6.5.1", "@types/express": "^4.17.21", "adminjs": "^7.4.2", "amazon-cognito-identity-js": "^6.3.7", "cors": "^2.8.5", "express": "^4.18.2", "express-formidable": "^1.2.0", "express-session": "^1.17.3", "memorystore": "^1.6.7", "prisma": "^5.6.0", "tslib": "^2.6.2" }, "devDependencies": { "@types/cors": "^2.8.17", "@types/express-session": "^1.17.10", "tsx": "^4.6.2", "nodemon": "^3.0.2" },
What browsers do you see the problem on?
No response
Relevant log output
n/a
Relevant code that's giving you issues
No response
It seems to be an issue with @adminjs/bundler
. I will probably have to update it so that it requires AdminJSOptions
.
You should be able to add missing envs by creating a custom script.
import fs from 'fs/promises'
const setEnvs = async (admin: AdminJS) => {
const { env = {} } = admin.options
const script = Object.keys(env).map((envKey) => (
`AdminJS.env.${envKey} = ${JSON.stringify(env[envKey])}\n`
)).join('')
await fs.writeFile('<destination path>', script, 'utf8')
}
You can run it in the same file where you use @adminjs/bundler
. If you don't want to create an AdminJS
instance for the script, it's enough if you pass only AdminJSOptions
object or envs object.
Afterwards, add the generated script to AdminJS assets:
const admin = new AdminJS({
// ...
assets: {
scripts: process.env.NODE_ENV === 'production' ? ['/envs.js'] : [],
}
})
Thats a clever solution, for my use, those values weren't known at build time, so I did the same thing with terraform:
locals {
adminjs_ui_env = templatefile("${path.module}/ui-env.tftpl", {
env = {
DEFAULT_BASE_PATH = "/app"
CDN_PATH = "https://${aws_s3_bucket.my_bucket.bucket}.s3.amazonaws.com/dashboard/"
}
})
}
resource "aws_s3_object" "ui-env-js" {
bucket = aws_s3_bucket.my_bucket.id
key = "dashboard/ui-env.js"
content_base64 = base64encode(local.adminjs_ui_env)
etag = md5(local.adminjs_ui_env)
content_type = "application/javascript"
acl = "public-read"
}
ui-env.tftpl
%{ for config_key, config_value in env }
AdminJS.env.${config_key} = ${config_value}
%{ endfor ~}
Confirmed works
Just copy env string is working too:
env: {
IMAGES_PATH: `${process.env.IMAGES_PATH}`,
}
So it's seems to be an unclear behaviour, not a real bug 🙂