SoftwareBrothers / adminjs

AdminJS is an admin panel for apps written in node.js
https://adminjs.co
MIT License
8.17k stars 660 forks source link

Pre-bundling frontend assets with new Component Loader #1314

Open emiller12 opened 1 year ago

emiller12 commented 1 year ago

Hi, I've been loving adminjs so far. I managed to get something basic up and running and hitting my exisiting db very quickly. I have created some custom pages and managed to surface those in the navigation by following the documentation for the Component Loader here (https://docs.adminjs.co/ui-customization/writing-your-own-components). All of that works fine.

However I have run into a bit of a hurdle and would appreciate being pushed in the right direction.

I am wanting to deploy adminjs to AWS lambda and push the pre-built frontend bundles to an s3 bucket to be served statically.

I have read many threads saying that this is possible using the @adminjs/bundler package, and setting the assetsCDN option in the AdminJS options.... however all of the examples I have seen of this approach use the now deprecated AdminJS.bundle(...) approach, rather that the newer "Component Loader" approach. Also the offical example app appears to still be using a an older version of adminjs (before the Component Loader was added).

So I guess I'm hoping that you would be able to point me towards an example of how I can achieve pre-bundling of the frontend assets on the latest version of AdminJS

Thanks :)

Describe the problem feature solves Documentation and Examples around pre-bundling frontend assets for deploying AdminJS in serverless environments is a bit outdated and limited.

Describe the solution you'd like I would really like to be provided with a clear example to or advice on how to achieve the pre-bundling setup on the latest version of adminjs

Acceptance criteria

dziraf commented 1 year ago

The example app will be updated soon, we also want to update & document @adminjs/bundler's usage with ComponentLoader. That said, deploying to a serverless environment might not be the best idea in the end as we had done it before and there had always been issues related to performance and resources usage.

emiller12 commented 1 year ago

Thanks for the reply @dziraf .

So are you saying that it is not currently possible to to use @adminjs/bundler with newer versions of adminjs that use the ComponentLoader?

Inoir commented 1 year ago

ive made the precompiled lib working, but cant use the components in the application. not one sentence about this topic.

so i.e ive a package named "admin-components" that exports componentLoader and Components like in the description. using the assetCDN stuff and set it to hosted files url out of the bundler. so question is how can you use them in the admin backend. if you import just the Components and use it like in other examples, it will still try to resolve the physical path. settings like ADMIN_JS_SKIP_BUNDLE="true" doesnt matter, cause the resolvment of the physical file is done in the ComponentLoader.add or AdminJS.bundle function. so it doesnt wait for some initialization of the adminjs until it tries to resolve physical paths. no way to get this working with newer versions at this moment. for me its clearly impossible and there needs to be some work done to get a external library with assets working.

my component file looks like this and is also the index of the component lib

import { bundleComponents as importExportComponents } from "@adminjs/import-export"
import { ComponentLoader } from "adminjs"

export * from "./lib/dashboard"

export const componentLoader = new ComponentLoader()

export const Components = {
  ...importExportComponents(),
  Dashboard: componentLoader.add("Dashboard", "./lib/dashboard"),
}

Problem is the usage:

dashboard: {
  component: AdminJS.bundle("Dashboard"),
},
import { Components } from "admin-components"

dashboard: {
  component: Components.Dashboard,
},

both will try to resolve a physical path, without adding i.e the componentLoader, adding the componentLoader will have same result. setting env variable => same result, (since i use nestjs) setting shouldBeInitialized as option on the module also same result. will always try to bundle on the backend.

Inoir commented 1 year ago

Right after this i had the simple idea and its working:

dashboard: {
  component: "Dashboard",
},

is working. so just simple define it with same name as defined in the loader as key.

ryanmargono commented 1 year ago

@Inoir were you able to successfully get adminjs served thru a lambda? We are looking to do the same (only concerned with the db CRUD panel).

Inoir commented 1 year ago

No sorry, we made it working with custom components, but had other issue, so we dont use adminjs anymore. Lambda was never in scope.

cjativa commented 1 year ago

It seems deploying to AWS Lambda will be impossible either way due to asset size. Starting the server code that imports AdminJS also causes some files that import React to be run, and well, that means you'll need to have React in your Lambda deploy node_modules folder...which will likely make your Lambda cold start pretty slow due to node_modules size...

Looks like AWS Lambda deployment for AdminJS is very much an afterthought.

cjativa commented 1 year ago

Why is there no steps for transpiling/bundling the frontend dependencies into assets to be deployed for use with the server? The lack of this leads to oddities like requiring styled-components to be available in the server node_modules.