2022-03-07
|~2 min read
|295 words
I added a script to a Next.JS project recently which I wanted to run as part of a pre-build step with ts-node
.
The script lived in a scripts folder in the root of my project:
import { ExpandedNote } from "../types/note"
const fs = require("fs")
const path = require("path")
const lunr = require("lunr")
const { extractNoteData } = require("../utils/extractFrontmatter")
function builder() {
//....
}
builder()
The issue is that every time I ran this, there was a module in the dependency graph and the script would error:
% npm run pre-build
> blog-next@0.1.0 pre-build
> ts-node scripts/build.ts
(node:43492) Warning: To load an ES module, set "type": "module" in the package.json or use the .mjs extension.
(Use `node --trace-warnings ...` to show where the warning was created)
/Users/stephen.weiss/code/blog-next/scripts/build.ts:136
export {};
^^^^^^
SyntaxError: Unexpected token 'export'
at wrapSafe (internal/modules/cjs/loader.js:1001:16)
at Module._compile (internal/modules/cjs/loader.js:1049:27)
at Module.m._compile (/Users/stephen.weiss/code/blog-next/node_modules/ts-node/src/index.ts:1459:23)
at Module._extensions..js (internal/modules/cjs/loader.js:1114:10)
at Object.require.extensions.<computed> [as .ts] (/Users/stephen.weiss/code/blog-next/node_modules/ts-node/src/index.ts:1462:12)
at Module.load (internal/modules/cjs/loader.js:950:32)
at Function.Module._load (internal/modules/cjs/loader.js:790:14)
at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:76:12)
at main (/Users/stephen.weiss/code/blog-next/node_modules/ts-node/src/bin.ts:389:12)
at Object.<anonymous> (/Users/stephen.weiss/code/blog-next/node_modules/ts-node/src/bin.ts:539:3)
I was not the first person to run into a similar situation with ts-node
and I found this answer in a Github thread that solved the problem nicely.
The issue appeared to be a mismatch between module types of ES Modules and CommonJS in my script. Meanwhile Next.JS sets the compiler options for modules to ESNext
by default, so I couldn’t just change my project without breaking Next.
Luckily, Typescript has an escape hatch that can be added to the tsconfig.json
, from the ts-node README:
{
"compilerOptions": {
"module": "ESNext"
},
"ts-node": {
"compilerOptions": {
"module": "CommonJS"
}
}
}
With this small change to my tsconfig.json
my scripts now run successfully with type support and my app runs like before!
Hi there and thanks for reading! My name's Stephen. I live in Chicago with my wife, Kate, and dog, Finn. Want more? See about and get in touch!