Separate enums and constants from the rest of the generated client
See original GitHub issueProblem
You cannot easily import enum in client code.
// src/app.ts
import { MyEnum } from '@prisma/client'
console.log(MyEnum)
The problem is that all enums are in the same file with the rest of the prism code. This leads to two problems for bundlers:
- Tree-shacking. To import a single enum, you need to analyse and import the entire Prisma dependency tree. Which is not without its side effects. Because of this, shaking the tree is impossible.
- https://github.com/prisma/prisma/issues/12504#issuecomment-1136126199
Suggested solution
Divide the generated client file into several separate ones.
// .prisma/client/index.js
// ...
exports.Prisma = Prisma
exports.MyEnum = required('./enums').MyEnum
// .prisma/client/enums.js
function makeEnum(x) { return x; }
exports.MyEnum = makeEnum({ /* ... */ })
// will be tree-shaked
exports.AnotherEnum = makeEnum({ /* ... */ })
// @prisma/client/enums
module.exports = {
...require('.prisma/client/enums'),
}
This allows you import single enum from separate file
import { MyEnum } from '@prisma/client/enums'
That will not require the bundler to analyze the entire dependency tree. This will allow you to import enums into client code and work around this issue
Workaround
Create own enums end use it
// my-enums/user-role.ts
// Import original enum as type only
import type { UserRoleEnum as UserRoleEnumOrigin } from '@prisma/client'
// Re-export enum for runtime with origin name and type
export const UserRoleEnum = {
Role1: 'Role1',
Role2: 'Role2',
} satisfies UserRoleEnumOrigin // require ts v4.9 or higher
// usage
import { UserRoleEnum } from 'my-enums/user-role.ts'
console.log(UserRoleEnum.Role1)
console.log(UserRoleEnum.Role3) // Property 'Role3' does not exist on type '{ Role1: "Role1"; Role2: "Role2"; }'.
Issue Analytics
- State:
- Created a year ago
- Reactions:10
- Comments:5 (1 by maintainers)
Top Results From Across the Web
constants/enums in API - Software Engineering Stack Exchange
We use a lot of mappings to numbers (to save space) and I was wondering what the best technique is. I can hard...
Read more >How to make the most of Java enums - Oracle Blogs
Enum declarations are full classes, and the values listed are constant names referring to separate instances of these classes. The enum ...
Read more >What is the right place to keep Constants and Enums? [closed]
As far as I use the strategy, I keep all 'Constants' in a separate class named 'Constants' but I am not sure whether...
Read more >Java Enum: An Introduction to the Java Enum Class
Each item in a Java enum is called a constant, an immutable variable — a value that cannot be changed. Constants are frequently...
Read more >Build Enumerations of Constants With Python's Enum
The enum module defines a general-purpose enumeration type with iteration and comparison capabilities. You can use this type to create sets of ...
Read more >Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start FreeTop Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Top GitHub Comments
Workaround
For the each enum model, Prisma does not only give you a
const
from@prisma/client
but also the type as string literal, for example:…which means you can force only importing the type easily:
import type { PostSegmentImagePosition } from '@prisma/client'
You can now use the string literal directly, or, if you want to use them in an “enum way”, you can build your own:
This will give you the typical autocomplete:
The good thing about this that TypeScript will yell at you if you forget a field/value in your definition:
Using this workaround fixes
@prisma/client
being part of the bundle as you only import the type and not the constant.I have the same problem, in my case with a Next.js app.
According to Next.js’ bundle analyzer, this adds ~13 KB to the client bundle:
@cawa-93 Would you mind adding something like “client bundle” to the issue title for better discoverability?
Additionally - and I haven’t tried this out yet - is this maybe also true for Prisma’s
validator
? You cannot destructure imports, so you’ll always have to importPrisma
: