Reputation: 21
Hello Stack Overflow community,
I'm working on a project using NestJS and AdminJS, and I've encountered an issue where TypeScript cannot find the module @adminjs/nestjs or its corresponding type declarations. This issue is preventing me from integrating AdminJS with my NestJS application.
"@adminjs/nestjs": "^6.1.0",
What i tried:
Installation: I first attempted to install the @adminjs/nestjs package using npm, ensuring that the package was correctly added to my project's package.json file. Importing and Usage: After installation, I imported the AdminModule from @adminjs/nestjs into my NestJS module and attempted to use it according to the documentation and examples provided. TypeScript Configuration: I reviewed my TypeScript configuration to ensure that it was set up to recognize the types from @adminjs/nestjs. This included checking my tsconfig.json file for any relevant settings that might affect module resolution. Searching for Solutions: I searched for similar issues on Stack Overflow, GitHub, and other developer forums. I also checked the official documentation and GitHub issues for @adminjs/nestjs to see if others had encountered and resolved the same problem. Environment Check: I verified that my development environment, including Node.js, NestJS, and TypeScript versions, were compatible with the @adminjs/nestjs package requirements.
Upvotes: 1
Views: 1676
Reputation: 1
I just wanted to share my experience working through the ESM/CJS issues when integrating latest AdminJS, NestJS, and Prisma. After battling with the module resolution issues and figuring out the correct setup, I finally have a working sample project that might be helpful to others who are facing similar challenges.
You can find the full working example here: AdminJS, NestJS, Prisma Sample Project
The sample project includes:
I hope this helps someone out there who’s facing the same setup issues. Feel free to fork the repo and reach out if you run into any questions!
Good luck!
Upvotes: 0
Reputation: 41
The newest version of AdminJS is ESM only - meaning it is no longer compatible with a default NestJS application. https://docs.adminjs.co/installation/plugins/nest
You basically have 3 ways to go about this:
The way you go about it is by creating the following method
export const dynamicImport = async (packageName: string) =>
new Function(`return import('${packageName}')`)();
This allows you to import any ESM package from a CommonJS app without it being automatically converted to a 'require' call.
Then, in your Nest app main.ts:
async function bootstrap() {
const app = await NestFactory.create(AdminDashboardModule);
app.useGlobalPipes(
new ValidationPipe({
transform: true,
whitelist: true,
}),
);
const adminJSModule = await dynamicImport('adminjs');
const AdminJS = adminJSModule.default;
const AdminJSMongoose = await dynamicImport('@adminjs/mongoose');
AdminJS.registerAdapter({
Resource: AdminJSMongoose.Resource,
Database: AdminJSMongoose.Database, // Change with whatever adapter you want to use
});
const globalPrefix = 'admin';
const port = process.env.PORT || 3010;
await app.listen(port);
Logger.log(`🚀 Application is running on: http://localhost:${port}/${globalPrefix}`);
}
bootstrap();
In your module imports:
dynamicImport('@adminjs/nestjs').then(({ AdminModule }) => AdminModule.createAdminAsync(.......)
And just in case you were using the uploadComponent (example AWS config for image files):
const uploadModule = await dynamicImport('@adminjs/upload');
const uploadFeature = uploadModule.default;
const adminjs = await dynamicImport('adminjs');
const { ComponentLoader } = adminjs;
const componentLoader = new ComponentLoader();
......
features: [
uploadFeature({
componentLoader,
provider: {
aws: {
region: configService.get(CONFIG_KEYS.AWS_S3.REGION),
bucket: configService.get(CONFIG_KEYS.AWS_S3.IMAGE_BUCKET_NAME),
accessKeyId: configService.get(CONFIG_KEYS.AWS_S3.ACCESS_KEY),
secretAccessKey: configService.get(CONFIG_KEYS.AWS_S3.SECRET_ACCESS_KEY),
},
},
// Set filename as uuidv4 + extension
uploadPath: (record, filename) => FileUtil.generateFileKey(filename),
properties: {
key: 's3Key',
mimeType: 'mime',
bucket: 'bucket',
},
validation: {
maxSize: configService.get(CONFIG_KEYS.IMAGE.MAX_IMAGE_SIZE_MB) * 1024 * 1024,
mimeTypes: ['image/jpeg', 'image/png', 'image/gif', 'image/webp'],
},
}),
],
SLIGHT EDIT: The above code for the upload functionality will not work. The interface for the AWS provider has been changed. You'll need to set it up like this:
provider: {
aws: {
region: configService.get(CONFIG_KEYS.AWS_S3.REGION),
bucket: configService.get(CONFIG_KEYS.AWS_S3.IMAGE_BUCKET_NAME),
credentials: {
accessKeyId: configService.get(CONFIG_KEYS.AWS_S3.ACCESS_KEY),
secretAccessKey: configService.get(CONFIG_KEYS.AWS_S3.SECRET_ACCESS_KEY)
}
},
}
Upvotes: 4