This template implements minimal architecture on TypeScript + Next.js + MikroORM + tRPC + Tailwind CSS stack to help you start your next full-stack React application.
- Minimal full-stack application example;
- Bunch of utilities and helpers;
- Tests with AVA, docker-compose and MySQL setup;
- CI workflow config for GitHub Actions.
If you want to test a demo app built upon this template, just follow these steps:
- Clone this repository:
git clone git@github.com:octet-stream/next-mikro-orm-trpc-template.git quick-demo && cd quick-demo
- Run
./quick-demo.sh --build
script (or vianpm run demo -- --build
). To skip the build step, run this script without--build
flag. - Once the app is up and running, open http://localhost:3000 in your browser
- To stop demo app, press
Ctrl+C
During my attempts to integrate MikroORM with Next.js I had to fall into several issues worth to mention, so here's the list of those:
-
MikroORM can't discover entity, when you're trying to use class constructos to instaniate your entities and them persist and flus the data. I'm not sure why is this happening, but to avoid this problem use
EntiyManager
only with entity classes, not with their instances, so that the entity could be discovered (by it's name).So, do this:
const note = orm.em.create(Note, data) // Discovers `Note` entity by `Note.name` and then creates an instance of this entity class filled with given `data` await orm.em.persistAndFlush(note)
Instead of this:
const note = new Note(data) await orm.em.persistAndFlush(note) // Fails on the 2nd attempt to use it with the `Note` instance.
-
MikroORM can't discover native TypeScipt enums if you were to define those in a separate file. To fix avoid this problem, you'll have to extract emun values manually (but remember about TS enum quirks) and put those to
items
option of theEnum
decorator, along with thetype
options set to needed column type. Here's how you can do this:import {Entity, Enum} from "@mikro-orm/core" import {isString} from "lodash" import {NoteStatus} from "server/trpc/type/common/NoteStatus" const statuses = Object.values(NoteStatus).filter(isString) @Entity() class Note { @Enum({type: "string", items: statuses}) status: NoteStatus = NoteStatus.INCOMPLETED }
- Since recently (at least from v14 or v13.5) Next.js minifies class names by default, which breaks MikroORM's ability to get table names from class names. To fix that, use
tableName
option ofEntity
decorator
@Entity({tableName: "note"}) class Note { // entity definition... }
- Since recently (at least from v14 or v13.5) Next.js minifies class names by default, which breaks MikroORM's ability to get table names from class names. To fix that, use