env vars in prisma db seed (prisma/seed.ts)
What's the easiest way to use env vars from
src/env.mjs
in this prisma/seed.ts
file?
I tried import { env } from '../src/env.mjs'
but got this error
Error [ERR_REQUIRE_ESM]: require() of ES Module /app/src/env.mjs not supported.
Instead change the require of /app/src/env.mjs to a dynamic import() which is available in all CommonJS modules.
An error occurred while running the seed command:
Error: Command failed with exit code 1: ts-node --compiler-options {"module":"CommonJS"} prisma/seed.ts
23 Replies
Can you post the code or a snippet of its usage
In the mean time I think I may have found something coming from here https://javascript.info/modules-dynamic-imports.
You could try this instead
let me know if that works 👍
I tried this
import { PrismaClient, Prisma, Category } from '@prisma/client'
const { env } = await import('../src/env.mjs')
const prisma = new PrismaClient()
async function main() {
await prisma.category.upsert({
where: { id: 1 },
update: { name: env.FORUM_ROOT_NAME },
create: { name: env.FORUM_ROOT_NAME },
});
}
main()
.then(async () => {
await prisma.$disconnect()
})
.catch(async (e) => {
console.error(e)
await prisma.$disconnect()
process.exit(1)
})
but it failed
docker-dev-1 | Environment variables loaded from .env
docker-dev-1 | Running seed command
ts-node --compiler-options {"module":"CommonJS"} prisma/seed.ts ...
docker-dev-1 | /app/node_modules/.pnpm/[email protected]_uayvamxqnl5yeiojjysxwopmsy/node_modules/ts-node/src/index.ts:859
docker-dev-1 | return new TSError(diagnosticText, diagnosticCodes, diagnostics);
docker-dev-1 | ^
docker-dev-1 | TSError: ⨯ Unable to compile TypeScript:
docker-dev-1 | prisma/seed.ts(2,17): error TS1378: Top-level 'await' expressions are only allowed when the 'module' option is set to 'es2022', 'esnext', 'system', 'node16', or 'nodenext', and the 'target' option is set to 'es2017' or higher.
Let me know if you want more infoAre you using ct3 ?
yes
Did you change the tsconfig file ?
oh wait
I don't think so
Just realize
why did you add this compiler option here ?
the prisma docs told me to do so. https://www.prisma.io/docs/guides/database/seed-database
Prisma
Seeding your database
Learn how to seed your database using Prisma's integrated seeding functionality and Prisma Client
Hmm honestly never had a problem without it
try this instead ts-node prisma/seed.ts for your seed scipt
in your package.json
docker-dev-1 | Running seed command
ts-node prisma/seed.ts
...
docker-dev-1 | (node:1866) Warning: To load an ES module, set "type": "module" in the package.json or use the .mjs extension.
docker-dev-1 | (Use node --trace-warnings ...
to show where the warning was created)
docker-dev-1 | /app/prisma/seed.ts:1
docker-dev-1 | import { PrismaClient } from '@prisma/client';
docker-dev-1 | ^^^^^^
docker-dev-1 |
docker-dev-1 | SyntaxError: Cannot use import statement outside a module
docker-dev-1 | at Object.compileFunction (node:vm:360:18)
docker-dev-1 | at wrapSafe (node:internal/modules/cjs/loader:1119:15)
docker-dev-1 | at Module._compile (node:internal/modules/cjs/loader:1155:27)
docker-dev-1 | at Module.m._compile (/app/node_modules/.pnpm/[email protected]_uayvamxqnl5yeiojjysxwopmsy/node_modules/ts-node/src/index.ts:1618:23)
docker-dev-1 | at Module._extensions..js (node:internal/modules/cjs/loader:1245:10)
docker-dev-1 | at Object.require.extensions.<computed> [as .ts] (/app/node_modules/.pnpm/[email protected]_uayvamxqnl5yeiojjysxwopmsy/node_modules/ts-node/src/index.ts:1621:12)
docker-dev-1 | at Module.load (node:internal/modules/cjs/loader:1069:32)
docker-dev-1 | at Function.Module._load (node:internal/modules/cjs/loader:904:12)
docker-dev-1 | at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:81:12)
docker-dev-1 | at phase4 (/app/node_modules/.pnpm/[email protected]_uayvamxqnl5yeiojjysxwopmsy/node_modules/ts-node/src/bin.ts:649:14)
docker-dev-1 |
docker-dev-1 | An error occurred while running the seed command:
docker-dev-1 | Error: Command failed with exit code 1: ts-node prisma/seed.tshonestly this is why i hate modules sigh
I got it working
import { PrismaClient, Prisma, Category } from '@prisma/client'
const prisma = new PrismaClient()
const rootName = process.env.FORUM_ROOT_NAME || 'root'
async function main() {
await prisma.category.upsert({
where: { id: 1 },
update: { name: rootName },
create: { name: rootName },
});
}
main()
.then(async () => {
await prisma.$disconnect()
})
.catch(async (e) => {
console.error(e)
await prisma.$disconnect()
process.exit(1)
})
so the solution was to use process.env
instead of trying to use src/env.mjs
👍
GL
thanks @tropic
I did nothing xD
Was going to suggest that as a last resort as I assumed, wrongly of me, that you wanted to validate the env variables before using them
yea it would have been nice to validate them, but oh well
if you would like you could try to change mjs to js and them import them the normal way
const { env } = require('../src/env.js');
I do believe mjs way is faster and allows for the nice import syntax
and some more flexability
but with prisma seed it may actually pose a problem in this case
i usually just avoid using it because some library always had a problem with it
so this would be with the compiler option
{"module":"CommonJS"}
so that I can also import { PrismaClient } from '@prisma/client'
, right?yeah
ok, I will try
docker-dev-1 | Running seed command
ts-node --compiler-options {"module":"CommonJS"} prisma/seed.ts ...
docker-dev-1 |
docker-dev-1 | 🌱 The seed command has been executed.
docker-dev-1 |
docker-dev-1 | > [email protected] dev /app
docker-dev-1 | > next dev
docker-dev-1 |
docker-dev-1 | node:fs:1583
docker-dev-1 | handleErrorFromBinding(ctx);
docker-dev-1 | ^
docker-dev-1 |
docker-dev-1 | Error: ENOTDIR: not a directory, stat '/app/src/env.js/index.js'
docker-dev-1 | at statSync (node:fs:1583:3)
docker-dev-1 | at tryStatSync (node:internal/modules/esm/resolve:183:13)
docker-dev-1 | at finalizeResolution (node:internal/modules/esm/resolve:323:17)
docker-dev-1 | at moduleResolve (node:internal/modules/esm/resolve:907:10)
docker-dev-1 | at defaultResolve (node:internal/modules/esm/resolve:1115:11)
docker-dev-1 | at nextResolve (node:internal/modules/esm/loader:163:28)
docker-dev-1 | at ESMLoader.resolve (node:internal/modules/esm/loader:841:30)
docker-dev-1 | at ESMLoader.getModuleJob (node:internal/modules/esm/loader:424:18)
docker-dev-1 | at ESMLoader.import (node:internal/modules/esm/loader:525:22)
docker-dev-1 | at importModuleDynamically (node:internal/modules/esm/translators:110:35) {
docker-dev-1 | errno: -20,
docker-dev-1 | syscall: 'stat',
docker-dev-1 | code: 'ENOTDIR',
docker-dev-1 | path: '/app/src/env.js/index.js'
docker-dev-1 | }
docker-dev-1 | ELIFECYCLE Command failed with exit code 1.
wait... was this vscode changing imports wrong 🤔it looks like that
which is annoying
i dont know enough about t3 app to sugest changing tsconfig options
so just go with the one that worked
just ensure to check your envs
there's this in the
next.config.mjs
file:
// @ts-check
/**
* Run
build or
dev with
SKIP_ENV_VALIDATION to skip env validation.
* This is especially useful for Docker builds.
*/
!process.env.SKIP_ENV_VALIDATION && (await import("./src/env.js/index.js"));
/** @type {import("next").NextConfig} */
const config = {
reactStrictMode: true,
/**
* If you have the "experimental: { appDir: true }" setting enabled, then you
* must comment the below
i18n config out.
*
* @see https://github.com/vercel/next.js/issues/41980
*/
i18n: {
locales: ["en"],
defaultLocale: "en",
},
};
export default config;
FYI I am not skipping env validation even tho I am using docker, what I'm doing is
set -a; source .env; set +a; docker-compose -f docker/docker-compose.dev.yml up
and the docker-compose.dev.yml file passes the env vars to the container which is built from Dockerfile.dev which mounts my code directory (so hot reload works) and runs next dev
but yes, I will go with the option that worked but does not validate the env variablesTry this and make it an iife maybe