I have a Koa nodejs server which I added AdminJS to and it's working beautifully locally. My goal is to override the Dashboard component. I did so successfully when not running in production. However when I run in production mode (NODE_ENV=production node ./dist/server.js
) it fails silently.
const componentLoader = new ComponentLoader();
const Components = {
Dashboard: componentLoader.add("Dashboard", "./admin/dashboard"),
};
const admin = new AdminJS({
componentLoader,
dashboard: {
component: Components.Dashboard,
}
});
My dashboard.tsx file is in src/admin/
and admin is a folder on the same level as src/server.ts
. Also, my componentLoader when I inspect it is showing the correct filePath that ends with dist/admin/dashboard
Also, when I check dist/admin/dashboard.js
I see my React code. So my tsconfig seems to be correct and the dashboard.tsx has a default export.
What confuses me is when I run nodemon --watch src --exec node -r esbuild-register src/server.ts
is works correctly so it seems in general I have things hooked up correctly.
Lastly, here's my tsconfig.json
.
{
"$schema": "https://json.schemastore.org/tsconfig",
"compilerOptions": {
"jsx": "react",
"lib": [
"es6"
],
"target": "es2017",
"module": "commonjs",
"esModuleInterop": true,
"resolveJsonModule": true,
"strict": true,
"allowSyntheticDefaultImports": true,
"noImplicitAny": true,
"allowJs": false,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true,
"noImplicitReturns": true,
"strictNullChecks": true,
"moduleResolution": "node",
"inlineSources": true,
"sourceRoot": "/",
"sourceMap": true,
"isolatedModules": true,
"outDir": "./dist",
"rootDir": "./src",
"composite": true,
"baseUrl": ".",
"paths": {
"src/*": [
"src/*"
]
}
},
"exclude": [
"node_modules",
"./node_modules/*"
],
"files": [
"./src/server.ts"
],
"include": [
"./src/**/*",
"./src/*"
]
}
UPDATE: I did notice that the components.bundle.js file was missing when navigating to my adminjs dashboard. Since I am using GCP App Engine, I know that that file will not able to be built and saved on the fly in the file system so I have integrated @adminjs/bundler which creates the missing files. However the piece I still haven't put together is how to integrate it into the build pipeline (in particular I'm not sure what the destination of the components.bundle.js should be).
Before I explain my solution here are a few pieces of context:
./.adminjs/bundle.js
First, I created a file which bundles the frontend components. I have not tried doing that with the ComponentLoader so I wouldn't need duplicate code yet, but here's what I know for certain works:
I believe if I were to create a file which creates the ComponentLoader and adds the components that it would be equivalent (it would export the Components and the componentLoader for use by the AdminJS configuration).
Note
../src/dashboard
is simply the location of the dashboard.tsx file I chose. And Dashboard is the name of the component.Then, I created a script which uses
@adminjs/bundler
to actually create the bundles. (I named it bundler.ts).I added a script to my package.json which does the following:
Now, when I run this script (which I do when I run before doing
node ./dist/server.js
), the adminjs router is going to be able to find the previously missing file.Note that when running your server you'll also want to make sure you set
ADMIN_JS_SKIP_BUNDLE='true'
.I hope this helps the next person. I also do hope some documentation and better tooling is on its way. This is kind of messy but solved my issue for now.