This week, I tackled an interesting challenge revealing knowledge gaps – executing an exported function in a TypeScript file without calling it within the file and working with the Node CLI.
For most of the application code, you may write, you may never have to learn such concepts because, in software, we have A LOT of abstractions – mainly in the form of npm packages for fellow JavaScript Developers.
But if you're building systems for other systems to run on, you have to dive deeper and learn the abstractions are.
Context - how seeding in Prisma works
The task involved writing a script would end up being part of a mini-test-suite to ensure that the instructions a user followed wouldn't lead to an error.
One of the steps was seeding a database in a Prisma project. The Prisma CLI exposes a seed
command, but at the time of writing this, it's a preview-feature
and its implementation is being redesigned.
The default way of executing a function in a file is by calling it. It just works. The stable implementation of seeding currently works as follows:
function main(){
/** your seeding logic */
}
main()
.catch((e) => {
console.error(e);
process.exit(1);
})
.finally(async () => {
await prisma.$disconnect();
});
Running npx prisma db seed --preview-feature
would successfully seed your database with the above code example
But... seeding was using a different implementation of the seed
command that the Prisma CLI supports – executing seed function with a default exported seed()
or exported seed()
function in your ./prisma/seed.ts
file:
export default function seed (){
/** your logic */
}
// OR
export function seed(){
/** your logic */
}
Running npx prisma db seed --preview-feature
would work just okay but it isn't always guaranteed to work perfectly. Occasionally, prisma db seed
encounters an error but won't throw an error – indicating a false positive.
The solution
ts-node
🎉
ts-node
is a handy tool for transpiling/ transforming TypeScript into JavaScript.
Unlike the first main()
seeding example, the seed()
function isn't called. Running npx ts-node ./prisma/seed
would only transform the file checking for type errors.
ts-node
exposes the --eval
/ -e
flag from the Node CLI. The --eval
flag accepts a script argument which is valid TypeScript/ JavaScript code. For It has to be valid JavaScript in the case of Node.js.
You can execute the seed()
function with the following command:
npx ts-node -e "import seed from './prisma/seed'; seed()"
OR:
npx ts-node -e "import {seed} from './prisma/seed'; seed()"
As the command is being executed, --eval
creates a "sandbox" – the Node.js REPL (Read-Eval-Print-Loop) – where the code is executed.
Note: You can execute exported functions in your TypeScript project following the above command. E.g.
// path - ./src/starWars.ts
export function fetchStarWarsMovies(){
try{
/** logic here */
} catch (error){
/** error handling */
}
}
yarn ts-node -e "import {fetchStarWarsMovies} from './src/starWars'; fetchStarWarsMovies()"
Besides --eval
flag, you can also use the --print
/-p
. --print
is similar to --eval
but prints the output on the console.
Learning about --eval
and --print
flag in ts-node
and Node.js showed me there's a whole mountain of tools/ software to learn out there. Abstractions are grand, but every once in a while, it's a good idea to understand how to use them instead of installing another npm package :troll_face:
I hope you enjoyed this article. If you have any comments or feedback, my Twitter DM is open.
Till next week. ✌🏽
Top comments (0)