miniflare
miniflare copied to clipboard
Service binding not work in miniflare 3
Hi,
I can't setup the service binding with miniflare 3, here is my test code:
import { Miniflare } from "miniflare";
const mf = new Miniflare({
host: "0.0.0.0",
port: 8787,
workers: [
{
name: "my-invest-gateway",
serviceBindings: {
AUTH: 'my-invest-auth',
async CHAT(request) {
// `request` is the incoming `Request` object.
return new Response('');
},
},
scriptPath: './index.ts',
},
{
name: "my-invest-auth",
script: `
addEventListener('fetch', event => {
event.respondWith(new Response('Hello world'));
});
`,
},
],
});
afterAll(() => {
mf.dispose();
});
describe('Chat', () => {
test('GET /chat', async () => {
const res = await mf.dispatchFetch('http://127.0.0.1:8787/chat/hello/jack')
expect(res.status).toBe(200)
const body = await res.text()
expect(body).toEqual('Hello, world!')
})
})
and here is my code:
import { Context, Hono } from 'hono'
import { logger } from 'hono/logger'
type Bindings = {
AUTH: Fetcher;
CHAT: Fetcher;
}
const app = new Hono<{ Bindings: Bindings }>()
app.use('*', logger())
// API routes
const chat = new Hono()
chat.get('/hello/:user', async (c: Context) => {
console.log(JSON.stringify(c.env));
// TODO: check if the user exists
const authResponse = await c.env.AUTH.fetch(c.req.raw.clone());
const authBody = await authResponse.json();
console.log(`authResponse: ${JSON.stringify(authBody)}`);
if (authResponse.status !== 200) {
return authResponse;
}
return await c.env.CHAT.fetch(c.req.raw, {
headers: {
'X-Auth-Header': 'abcd',
'X-User-Agent': 'gateway',
},
});
});
app.route('/chat', chat)
export default app
when I run npm run test
, there is an error:
MiniflareCoreError [ERR_SERVICE_NOT_MOUNTED]: Service "my-invest-auth" for binding "AUTH" not found.
Make sure "my-invest-auth" is mounted so Miniflare knows where to find it.
Hey! 👋 ERR_SERVICE_NOT_MOUNTED
will only be thrown by Miniflare 2. Could you double check the version of Miniflare you've got installed? It's possible multiple versions are installed and the wrong one is being picked up? Running npm why miniflare
may help here.
Unrelated, but you'll also want to import Response
from miniflare
in your test to make sure you're using the right implementation:
import { Miniflare, Response } from "miniflare";
Hi @mrbbot Thanks, but the version is 3.2.
Hmmm, very strange. A few other things to try:
- Remove your
node_modules
folder and rerunnpm install
- Check you haven't got
jest-environment-miniflare
installed (this hasn't been upgraded to Miniflare 3 yet). Could you share your Jest config here too? - Run the
node
REPL in your project thenrequire.resolve("miniflare")
and share that here. This should show us where Miniflare is being loaded from.
Hi, @mrbbot Thanks!
package.json file:
{
"name": "my-invest-gateway",
"version": "0.0.1",
"private": true,
"main": "src/index.ts",
"scripts": {
"deploy": "wrangler deploy src/index.ts",
"dev": "wrangler dev src/index.ts --local",
"test": "jest"
},
"dependencies": {
"@cfworker/uuid": "^1.12.4",
"hono": "^3.1.5"
},
"devDependencies": {
"@cloudflare/workers-types": "^4.20230518.0 ",
"@types/jest": "^29.5.2",
"esbuild": "^0.15.1",
"esbuild-jest": "^0.5.0",
"jest": "^29.1.2",
"jest-environment-miniflare": "^2.6.0",
"miniflare": "^3.20230628.0",
"wrangler": "^3.0.0"
}
}
jest.config.js
module.exports = {
transform: {
'^.+\\.(ts|tsx)$': 'esbuild-jest',
},
testEnvironment: 'miniflare',
}
node REPL:
Welcome to Node.js v18.15.0.
Type ".help" for more information.
> require.resolve("miniflare")
'~/myInvestGateway/node_modules/miniflare/dist/src/index.js'
>
Ah, when using Miniflare's API for testing (new Miniflare(...)
), you shouldn't set testEnvironment: 'miniflare'
in your Jest config. This runs your tests inside a workers environment, rather than the Node.js environment Miniflare expects. Removing testEnvironment: 'miniflare'
from your config should fix the issue.
Thanks @mrbbot But it still can't test 😢
> [email protected] test
> jest
console.error
service core:user:my-invest-gateway: Uncaught SyntaxError: Cannot use import statement outside a module
at Interface.<anonymous> (node_modules/miniflare/src/runtime/index.ts:58:39)
console.error
at core:user:my-invest-gateway:1
at Interface.<anonymous> (node_modules/miniflare/src/runtime/index.ts:58:39)
FAIL src/index.test.ts
Chat
✕ GET /chat (154 ms)
● Chat › GET /chat
MiniflareCoreError [ERR_RUNTIME_FAILURE]: The Workers runtime failed to start. There is likely additional logging output above.
29 | afterAll(() => {
30 | mf.dispose();
> 31 | });
| ^
32 |
33 | describe('Chat', () => {
34 | test('GET /chat', async () => {
at Miniflare.#assembleAndUpdateConfig (node_modules/miniflare/src/index.ts:853:13)
at Miniflare.#init (node_modules/miniflare/src/index.ts:537:5)
at Mutex.runWith (node_modules/miniflare/src/shared/sync.ts:63:48)
at Miniflare.#waitForReady (node_modules/miniflare/src/index.ts:880:5)
at Miniflare.dispatchFetch (node_modules/miniflare/src/index.ts:928:5)
at Object.<anonymous> (src/index.test.ts:31:17)
Test Suites: 1 failed, 1 total
Tests: 1 failed, 1 total
Snapshots: 0 total
Time: 0.548 s, estimated 1 s
Ran all test suites.
node:internal/process/promises:288
triggerUncaughtException(err, true /* fromPromise */);
^
MiniflareCoreError [ERR_RUNTIME_FAILURE]: The Workers runtime failed to start. There is likely additional logging output above.
Even I add "type": "module"
to package.json file and rename the jest.config.js to jest.config.cjs, the same error.
Same issue!
if I remove testEnvironment: "miniflare",
I lose the miniflare methodes such as getMiniflareFetchMock
@madawei2699 apologies for not following up here! This got completely buried in my inbox. 😢 If you're still working on this project, you'll need to build your TypeScript source code first, then point Miniflare to the built output. npx wrangler build
should do this for you. Replace scriptPath: "src/index.ts"
with scriptPath: "dist/index.js", modules: true
(assuming wrangler build
produces a file called dist/index.js
)
@AbdallahAbis if this is still an issue for you, would you be able to create a new GitHub issue?