SoftwareBrothers / adminjs

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

@adminjs/relations rendering error: Error: Component "RelationsShowPropertyComponent" has not been bundled #1649

Open Dr4CuK30 opened 6 months ago

Dr4CuK30 commented 6 months ago

Discussed in https://github.com/SoftwareBrothers/adminjs/discussions/1648

Originally posted by **Dr4CuK30** April 2, 2024 Hello guys, I wrote a implementation of relations (one to many and many to many) using the @adminjs/relations but is generating the following error in the visual generated resources that have this relations: Captura de pantalla 2024-04-02 a la(s) 2 56 55 p  m This is the browser console output: Captura de pantalla 2024-04-02 a la(s) 2 58 20 p  m And this is my resources: ` const createStreamingResource = () => ({ resource: Streaming, options: { navigation: { icon: 'Users' }, }, features: [ owningRelationSettingsFeature({ componentLoader, licenseKey: process.env.LICENSE_KEY, relations: { members: { type: RelationType.ManyToMany, junction: { joinKey: 'streamingId', inverseJoinKey: 'collaboratorId', throughResourceId: 'StreamingCollaborator', }, target: { resourceId: 'Collaborator', }, }, }, }), ], }); ` And my packege.json: Captura de pantalla 2024-04-02 a la(s) 3 02 34 p  m
tillkolter commented 5 months ago

I was facing the same issue and suspected the regression was introduced here

I downgraded to the version before the update and it worked again.

But then I realized that the bundling approach was not really "production-like", so I chose to add @adminjs/bundler and add an assets bundling step to my CI. Now everything works on the most recent version.

Androz2091 commented 1 month ago

I am getting the same issue and I am not able to reproduce @tillkolter's fix. Do I need to code a custom component? Or should it be available when calling new ComponentLoader()?

features: [
    owningRelationSettingsFeature({
        componentLoader: new ComponentLoader(),
        licenseKey: process.env.ADMINJS_LICENCE_KEY,
        relations: {
            server: {
                type: RelationType.OneToMany,
                target: {
                    joinKey: 'serverId',
                    resourceId: 'WhitelistedEmoji',
                },
            }
        }
    })
]
dziraf commented 1 month ago
        componentLoader: new ComponentLoader(),

This is wrong. ComponentLoader should be a singleton created in a separate file and imported wherever it's needed.

In your case, it should be imported into owningRelationSettingsFeature to make sure the feature adds it's components to the bundle AND you must also import it to your AdminJS constructor to make sure the admin panel actually loads it.

Androz2091 commented 1 month ago

Ohh you're right, I get it now. This does not work but I get the idea, how can I correct?

import { componentLoader } from './component-loader.js';

const admin = new AdminJS({
    branding: {
        companyName: 'Discord Bot'
    },
    componentLoader: componentLoader,
    resources: entities.map((entity) => ({
        resource: entity,
        options: getOptions(entity),
        features: [
            owningRelationSettingsFeature({
                componentLoader: componentLoader,
                licenseKey: process.env.ADMINJS_LICENCE_KEY,
                relations: {
                    server: {
                        type: RelationType.OneToMany,
                        target: {
                            joinKey: 'serverId',
                            resourceId: 'WhitelistedEmoji',
                        },
                    }
                }
            })
        ]
    }))
});
import { ComponentLoader } from 'adminjs'

const componentLoader = new ComponentLoader()

export { componentLoader }
Androz2091 commented 1 month ago

image

dziraf commented 1 month ago

This seems to be correct. If your server doesn't bundle custom components for some reason, you can try adding this after you create AdminJS instance:

if (process.env.NODE_ENV === 'production') {
  await admin.initialize(); // bundle components.bundle.js only once on start-up
} else {
  admin.watch(); // tell rollup to watch for file changes in dev environment
}

When you start the application, there should be a log saying that files are being bundled

Androz2091 commented 1 month ago

Thank you for your answer I get

/home/poca/Documents/GitHub/restriction-discord-bot/node_modules/.pnpm/@babel+core@7.25.2/node_modules/@babel/core/lib/vendor/import-meta-resolve.js:225
  Error.captureStackTrace(error);
        ^

Error: Cannot find package '@babel/plugin-syntax-import-assertions' imported from /home/poca/Documents/GitHub/restriction-discord-bot/babel-virtual-resolve-base.js
    at __node_internal_ (/home/poca/Documents/GitHub/restriction-discord-bot/node_modules/.pnpm/@babel+core@7.25.2/node_modules/@babel/core/lib/vendor/import-meta-resolve.js:225:9)
    at new NodeError (/home/poca/Documents/GitHub/restriction-discord-bot/node_modules/.pnpm/@babel+core@7.25.2/node_modules/@babel/core/lib/vendor/import-meta-resolve.js:195:5)
    at packageResolve (/home/poca/Documents/GitHub/restriction-discord-bot/node_modules/.pnpm/@babel+core@7.25.2/node_modules/@babel/core/lib/vendor/import-meta-resolve.js:899:9)
    at moduleResolve (/home/poca/Documents/GitHub/restriction-discord-bot/node_modules/.pnpm/@babel+core@7.25.2/node_modules/@babel/core/lib/vendor/import-meta-resolve.js:939:18)
    at defaultResolve (/home/poca/Documents/GitHub/restriction-discord-bot/node_modules/.pnpm/@babel+core@7.25.2/node_modules/@babel/core/lib/vendor/import-meta-resolve.js:1017:15)
    at resolve (/home/poca/Documents/GitHub/restriction-discord-bot/node_modules/.pnpm/@babel+core@7.25.2/node_modules/@babel/core/lib/vendor/import-meta-resolve.js:1030:12)
    at tryImportMetaResolve (/home/poca/Documents/GitHub/restriction-discord-bot/node_modules/.pnpm/@babel+core@7.25.2/node_modules/@babel/core/lib/config/files/plugins.js:142:45)
    at resolveStandardizedNameForImport (/home/poca/Documents/GitHub/restriction-discord-bot/node_modules/.pnpm/@babel+core@7.25.2/node_modules/@babel/core/lib/config/files/plugins.js:164:19)
    at resolveStandardizedName (/home/poca/Documents/GitHub/restriction-discord-bot/node_modules/.pnpm/@babel+core@7.25.2/node_modules/@babel/core/lib/config/files/plugins.js:173:22)
    at loadPlugin (/home/poca/Documents/GitHub/restriction-discord-bot/node_modules/.pnpm/@babel+core@7.25.2/node_modules/@babel/core/lib/config/files/plugins.js:52:20)
    at loadPlugin.next (<anonymous>)
    at createDescriptor (/home/poca/Documents/GitHub/restriction-discord-bot/node_modules/.pnpm/@babel+core@7.25.2/node_modules/@babel/core/lib/config/config-descriptors.js:140:16)
    at createDescriptor.next (<anonymous>)
    at step (/home/poca/Documents/GitHub/restriction-discord-bot/node_modules/.pnpm/gensync@1.0.0-beta.2/node_modules/gensync/index.js:261:32)
    at evaluateAsync (/home/poca/Documents/GitHub/restriction-discord-bot/node_modules/.pnpm/gensync@1.0.0-beta.2/node_modules/gensync/index.js:291:5)
    at /home/poca/Documents/GitHub/restriction-discord-bot/node_modules/.pnpm/gensync@1.0.0-beta.2/node_modules/gensync/index.js:44:11
    at Array.forEach (<anonymous>)
    at Function.async (/home/poca/Documents/GitHub/restriction-discord-bot/node_modules/.pnpm/gensync@1.0.0-beta.2/node_modules/gensync/index.js:43:15)
    at Function.all (/home/poca/Documents/GitHub/restriction-discord-bot/node_modules/.pnpm/gensync@1.0.0-beta.2/node_modules/gensync/index.js:216:13)
    at Generator.next (<anonymous>)
    at createDescriptors (/home/poca/Documents/GitHub/restriction-discord-bot/node_modules/.pnpm/@babel+core@7.25.2/node_modules/@babel/core/lib/config/config-descriptors.js:102:41)
    at createDescriptors.next (<anonymous>)
    at createPluginDescriptors (/home/poca/Documents/GitHub/restriction-discord-bot/node_modules/.pnpm/@babel+core@7.25.2/node_modules/@babel/core/lib/config/config-descriptors.js:99:17)
    at createPluginDescriptors.next (<anonymous>)
    at /home/poca/Documents/GitHub/restriction-discord-bot/node_modules/.pnpm/@babel+core@7.25.2/node_modules/@babel/core/lib/config/config-descriptors.js:65:32
    at Generator.next (<anonymous>)
    at Function.<anonymous> (/home/poca/Documents/GitHub/restriction-discord-bot/node_modules/.pnpm/@babel+core@7.25.2/node_modules/@babel/core/lib/gensync-utils/async.js:21:3)
    at Generator.next (<anonymous>)
    at step (/home/poca/Documents/GitHub/restriction-discord-bot/node_modules/.pnpm/gensync@1.0.0-beta.2/node_modules/gensync/index.js:269:25)
    at evaluateAsync (/home/poca/Documents/GitHub/restriction-discord-bot/node_modules/.pnpm/gensync@1.0.0-beta.2/node_modules/gensync/index.js:291:5)
    at Function.errback (/home/poca/Documents/GitHub/restriction-discord-bot/node_modules/.pnpm/gensync@1.0.0-beta.2/node_modules/gensync/index.js:113:7)
    at errback (/home/poca/Documents/GitHub/restriction-discord-bot/node_modules/.pnpm/@babel+core@7.25.2/node_modules/@babel/core/lib/gensync-utils/async.js:65:18)
    at async (/home/poca/Documents/GitHub/restriction-discord-bot/node_modules/.pnpm/gensync@1.0.0-beta.2/node_modules/gensync/index.js:188:17)
    at onFirstPause (/home/poca/Documents/GitHub/restriction-discord-bot/node_modules/.pnpm/gensync@1.0.0-beta.2/node_modules/gensync/index.js:216:13)
    at Generator.next (<anonymous>)
    at cachedFunction (/home/poca/Documents/GitHub/restriction-discord-bot/node_modules/.pnpm/@babel+core@7.25.2/node_modules/@babel/core/lib/config/caching.js:52:46)
    at cachedFunction.next (<anonymous>)
    at mergeChainOpts (/home/poca/Documents/GitHub/restriction-discord-bot/node_modules/.pnpm/@babel+core@7.25.2/node_modules/@babel/core/lib/config/config-chain.js:349:34)
    at mergeChainOpts.next (<anonymous>)
    at chainWalker (/home/poca/Documents/GitHub/restriction-discord-bot/node_modules/.pnpm/@babel+core@7.25.2/node_modules/@babel/core/lib/config/config-chain.js:316:14)
    at chainWalker.next (<anonymous>)
    at buildRootChain (/home/poca/Documents/GitHub/restriction-discord-bot/node_modules/.pnpm/@babel+core@7.25.2/node_modules/@babel/core/lib/config/config-chain.js:56:36)
    at buildRootChain.next (<anonymous>)
    at loadPrivatePartialConfig (/home/poca/Documents/GitHub/restriction-discord-bot/node_modules/.pnpm/@babel+core@7.25.2/node_modules/@babel/core/lib/config/partial.js:72:62)
    at loadPrivatePartialConfig.next (<anonymous>)
    at loadPartialConfig (/home/poca/Documents/GitHub/restriction-discord-bot/node_modules/.pnpm/@babel+core@7.25.2/node_modules/@babel/core/lib/config/partial.js:115:25)
    at loadPartialConfig.next (<anonymous>)
    at step (/home/poca/Documents/GitHub/restriction-discord-bot/node_modules/.pnpm/gensync@1.0.0-beta.2/node_modules/gensync/index.js:269:25)
    at evaluateAsync (/home/poca/Documents/GitHub/restriction-discord-bot/node_modules/.pnpm/gensync@1.0.0-beta.2/node_modules/gensync/index.js:291:5)
    at /home/poca/Documents/GitHub/restriction-discord-bot/node_modules/.pnpm/gensync@1.0.0-beta.2/node_modules/gensync/index.js:93:9
    at new Promise (<anonymous>)
    at async (/home/poca/Documents/GitHub/restriction-discord-bot/node_modules/.pnpm/gensync@1.0.0-beta.2/node_modules/gensync/index.js:92:14)
    at stopHiding - secret - don't use this - v1 (/home/poca/Documents/GitHub/restriction-discord-bot/node_modules/.pnpm/@babel+core@7.25.2/node_modules/@babel/core/lib/errors/rewrite-stack-trace.js:47:12)
    at loadPartialConfigAsync (/home/poca/Documents/GitHub/restriction-discord-bot/node_modules/.pnpm/@babel+core@7.25.2/node_modules/@babel/core/lib/config/index.js:34:85)
    at transformCode (file:///home/poca/Documents/GitHub/restriction-discord-bot/node_modules/.pnpm/@rollup+plugin-babel@6.0.4_@babel+core@7.25.2_rollup@4.20.0/node_modules/@rollup/plugin-babel/dist/es/index.js:113:81)
    at Object.transform (file:///home/poca/Documents/GitHub/restriction-discord-bot/node_modules/.pnpm/@rollup+plugin-babel@6.0.4_@babel+core@7.25.2_rollup@4.20.0/node_modules/@rollup/plugin-babel/dist/es/index.js:291:16)
    at file:///home/poca/Documents/GitHub/restriction-discord-bot/node_modules/.pnpm/rollup@4.20.0/node_modules/rollup/dist/es/shared/node-entry.js:19892:40 {
  code: 'PLUGIN_ERROR',
  pluginCode: 'ERR_MODULE_NOT_FOUND',
  plugin: 'commonjs--resolver',
  hook: 'resolveId',
  id: '/home/poca/Documents/GitHub/restriction-discord-bot/.adminjs/entry.js',
  watchFiles: [
    '/home/poca/Documents/GitHub/restriction-discord-bot/.adminjs/entry.js'
  ]
}

Node.js v20.12.1
Androz2091 commented 1 month ago

I can try anything now just tell me :pray:

dziraf commented 1 month ago

you could try installing @babel/plugin-syntax-import-assertions manually, I don't use pnpm myself and it looks like it cannot find the package

Androz2091 commented 1 month ago

Wow!! it works with admin.watch after installing the babel plugin. It does not with admin.initialize though. Thank you so much! I could not expect someone to answer that fast.

AntonOrnatskyi commented 4 days ago

I have the same problem, admin.initialize() doesn't help, I even see no message about bundled files. Environment: Node, Express, Typeorm

base-property-component.js:77 Uncaught Error: Component "RelationsShowPropertyComponent" has not been bundled, ensure it was added to your ComponentLoader instance (the one included in AdminJS options). at base-property-component.js:77:13

How to add component to ComponentLoader instance?

    await AppDataSource.initialize();
    this.server = new AdminJS({
      resources: [
        { resource: Unit,
          options: { 
            parent: { 
              name: 'Units' 
            },
            actions: {
              findRelation: {
                isAccessible: true,
              },
            },
          },
          features: [
            owningRelationSettingsFeature({
              componentLoader,
              licenseKey: 'hidden',
              relations: {
                persons: {
                  type: RelationType.OneToMany,
                  target: {
                    joinKey: 'unitId',
                    resourceId: 'Person',
                  },
                }
              },
            }),
          ],
        },
      { resource: Person,
        options: { 
          parent: { 
            name: 'Persons' 
          }    
        },
        features: [targetRelationSettingsFeature()]
      }
    ],
       rootPath: '/admin',
    })
    await this.server.initialize()
Androz2091 commented 4 days ago

@AntonOrnatskyi here is an example of a working project with this plugin. you might be happy to take some inspiration: https://github.com/androz2091-business/restriction-discord-bot/blob/main/src/database.ts

AntonOrnatskyi commented 4 days ago

Thanks but result is still same. I use @admin/express, typeorm with sqlite.