esmock: `invalid moduleId` error when using tsx

I’m trying to use esmock with AVA and TypeScript via transpilation with tsx (i.e. esbuild) on Node.js v18.16.1. My loader chain is effectively

node --loader=tsx --loader=esmock
AVA configuration
"files": [
	"test/*.ts"
],
"extensions": {
	"ts": "module"
},
"nodeArguments": [
	"--loader=tsx",
	"--loader=esmock",
	"--no-warnings=ExperimentalWarning"
]
Project structure
\__ src/
	\__ source-file.ts
\__ test/
    \__ test-file.ts
\__ package.json
\__ tsconfig.json

When trying to mock my source file, I get an invalid moduleId error:

// test/test-file.ts

import test from "ava";
import esmock from "esmock";

test("with mock", async t => {
	const { setExecutableBits } = await esmock("../src/source-file.js", import.meta.url, {
		// ...
	}) as typeof import("../src/source-file.js");

	// ...
});
Rejected promise returned by test. Reason:

  Error {
    message: 'invalid moduleId: "../src/source-file.js" (used by file:///.../test/test-file.ts)',
  }

  › Object.$e (node_modules/esmock/src/esmock.js:1:61)
  › wt (node_modules/esmock/src/esmock.js:2:6113)
  › <anonymous> (node_modules/esmock/src/esmock.js:3:161)

Am I missing something?

About this issue

  • Original URL
  • State: closed
  • Created a year ago
  • Comments: 16 (12 by maintainers)

Most upvoted comments

@tonisives respectfully, the example you gave probably does not use esmock correctly. Call esmock to mock values that are imported by the target module. See this diff, for example, which results in a passing test using the two files attached further below.

diff --git a/src/simpletest.test.ts b/src/simpletest.test.ts
index a1633c6..13a3370 100644
--- a/src/simpletest.test.ts
+++ b/src/simpletest.test.ts
@@ -1,13 +1,14 @@
 import { test } from "uvu"
 import esmock from "esmock"
-import { myFun } from "./simpletest.js"
+import simpletest from "./simpletest.js"
 
 test("test not real", async () => {
   let mock = await esmock("./simpletest.js", {
-    myFun: () => console.log("mocked")
+    "./simplefunctions.js": { myFun: () => console.log("mocked") }
   })
-  
-  myFun()
+
+  mock()
+  simpletest()
 })
 
 test.run()

src/simplefunctions.ts

export const myFun = () => {
  console.log("still real");
}

src/simpletest.ts

import { myFun } from './simplefunctions.js'

export default myFun

Nice find.

At the PR, I removed the invalid moduleId test, because the moduleId was actually invalid (the file path being imported did not exist) and esmock is expected to throw an error in that situation. That is separate from the unknown-file-extension-error which seems to be a real issue.