I am trying to upgrade node from version 16 => 20
I also decided to try and upgrade some other libraries altogether
I tried starting my backend after the upgrades
% yarn run dev
[nodemon] 3.0.1
[nodemon] to restart at any time, enter `rs`
[nodemon] watching path(s): src/**/*
[nodemon] watching extensions: ts
[nodemon] starting `ts-node --transpileOnly --files src/index.ts`
soon followed by
/Users/.../backend/node_modules/ts-node/dist/index.js:851
return old(m, filename);
^
Error [ERR_REQUIRE_ESM]: require() of ES Module /Users/.../backend/node_modules/file-type/index.js from /Users/.../backend/src/feature-core/upload-file.ts not supported.
Instead change the require of index.js in /Users/.../backend/src/feature-core/upload-file.ts to a dynamic import() which is available in all CommonJS modules.
at require.extensions.<computed> [as .js] (/Users/.../backend/node_modules/ts-node/dist/index.js:851:20)
I am not sure what needs to be updated or how, I tried making some changes following some github issues but could’t find a solution.
Update
This is where the error takes place:
import { protectedProcedure } from '../trpc/initialize'
import { randomString } from '../utils/rand'
import { uploadFile as uploadFileToS3 } from '../lib/s3'
import { TRPCError } from '@trpc/server'
import { fileTypeFromBuffer } from 'file-type'
export const uploadFileBase64 = protectedProcedure.input(z.object({ body: z.string() })).mutation(async ({ input }) => {
const buffer = Buffer.from(input.body, 'base64')
const fileType = await fileTypeFromBuffer(buffer)
if (fileType === undefined) {
throw new TRPCError({ code: 'BAD_REQUEST', message: 'ファイルの種類を判定できませんでした' })
}
const key = `${randomString()}.${fileType.ext}`
await uploadFileToS3({
key,
body: buffer,
contentType: fileType.mime,
})
return { key: '' }
})
I am not using require, neither here nor in any other file, so according to the answers I am guessing I need to add "type": "module"
to my package.json
.
However after adding that I got this error instead:
TypeError [ERR_UNKNOWN_FILE_EXTENSION]: Unknown file extension ".ts" for /Users/.../backend/src/index.ts
at new NodeError (node:internal/errors:405:5)
at Object.getFileProtocolModuleFormat [as file:] (node:internal/modules/esm/get_format:99:9)
at defaultGetFormat (node:internal/modules/esm/get_format:142:36)
at defaultLoad (node:internal/modules/esm/load:91:20)
at DefaultModuleLoader.load (node:internal/modules/esm/loader:263:26)
at DefaultModuleLoader.moduleProvider (node:internal/modules/esm/loader:179:22)
at new ModuleJob (node:internal/modules/esm/module_job:63:26)
at DefaultModuleLoader.#createModuleJob (node:internal/modules/esm/loader:203:17)
at DefaultModuleLoader.getJobFromResolveResult (node:internal/modules/esm/loader:156:34)
at DefaultModuleLoader.getModuleJob (node:internal/modules/esm/loader:141:17) {
code: 'ERR_UNKNOWN_FILE_EXTENSION'
}
[nodemon] app crashed - waiting for file changes before starting...
So I am guessing there is still something I am missing.
2
Answers
Quick Answer
putting this inside an async function should do the trick
Explanation
As explained by @monim the library
file-type
became ESM-only package after an upgrade, which required me to add"type": "module"
and change all my imports to ESM format.Did I want to change to ESM?
No, only one library had become ESM-only, and inside a pretty large directory I would rather keep the changes I make minimal. So as suggested by @Evert I tried using
await import
inside an async function.This worked perfectly, and everything ran smoothly except tslint which gave me this error:
And after a quick search I found out that changing the code to
eval('await import())
could fix the tslint error message.If you are not using tslint this should work fine as well:
this error occurs because a package you are importing has been converted to an ESM-only package (ECMAScript modules ), which means that the package cannot be imported with require() anymore. so as you said you upgraded some libraries first you have to check if they no longer support ESM .
to solve this error use imports/exports instead of require() .
don’t forget to add
"type": "module"
to your package.json file: .