cloudflare / workers-sdk

⛅️ Home to Wrangler, the CLI for Cloudflare Workers®
https://developers.cloudflare.com/workers/
Apache License 2.0
2.74k stars 726 forks source link

🐛 BUG: Discrepancy in Node Module Compatibility Between wrangler deploy and vitest-pool-workers Testing #7324

Open zach-is-my-name opened 4 days ago

zach-is-my-name commented 4 days ago

Which Cloudflare product(s) does this pertain to?

Workers Vitest Integration

What version(s) of the tool(s) are you using?

Wrangler 3.83, "vitest": "^2.1.5", "@cloudflare/vitest-pool-workers": "^0.5.28",

What version of Node are you using?

v20.13.1

What operating system and version are you using?

Mac Sonoma 15.3

Describe the Bug

Description:

I'm experiencing an issue where my Cloudflare Worker with Durable Objects works correctly when deployed using wrangler deploy, but fails during testing with vitest-pool-workers due to Node module compatibility problems.

Problem Summary:

Deployment Works as Expected:

Testing Fails Due to Node Dependencies:

Details:

Node Dependencies in Use:

import { https } from 'node:https';
import { Wallet, keccak256 } from 'ethers';

Testing Setup:

Error Messages During Testing:

When running tests, I encounter errors like:

Error: Cannot find module 'node:https'

This indicates that the Node modules are not being resolved or replaced in the testing environment.

Expected Behavior:

Questions and Request for Assistance:

  1. Is there a way to configure vitest-pool-workers to perform the same Node module compatibility transformations as wrangler deploy?

  2. Are there recommended practices for testing Workers that depend on Node modules using vitest-pool-workers?

  3. Could this be a limitation or missing feature in vitest-pool-workers that needs to be addressed?

Steps to Reproduce:

  1. Create a Worker with Node Dependencies:

    • Write a Cloudflare Worker script that imports Node modules like node:https and uses ethers.
  2. Deploy the Worker:

    • Use wrangler deploy to deploy the Worker.
    • Confirm that it works as expected in the production environment.
  3. Set Up Testing Environment:

    • Install vitest and @cloudflare/vitest-pool-workers.
    • Configure vitest.config.ts using defineWorkersProject:

      import { defineWorkersProject } from '@cloudflare/vitest-pool-workers/config';
      import path from 'path';
      
      export default defineWorkersProject({
      test: {
       poolOptions: {
         workers: {
           main: './dist/index.js',
           wrangler: {
             configPath: path.resolve(__dirname, './wrangler.toml'),
           },
         },
       },
      },
      });
  4. Run Tests:

    • Execute vitest to run the tests.
    • Observe the errors related to missing Node modules.

Additional Information:

Conclusion:

I believe there may be a discrepancy between how wrangler deploy and vitest-pool-workers handle Node module compatibility. I would appreciate any guidance on resolving this issue or insights into whether this is a known limitation.

Thank you for your assistance!

Please provide a link to a minimal reproduction

https://github.com/zach-is-my-name/reproduction-vitest-pool-compat-module-error

Please provide any relevant error logs

Click to expand [~/Projects/charli/apps/session-time-tracker]$ bun run test $ vitest run --config tests/vitest.config.ts RUN v2.1.5 /Users/zm/Projects/charli/apps/session-time-tracker Using vars defined in .dev.vars [vpw:inf] Starting isolated runtimes for tests/vitest.config.ts... ❯ tests/sessionTimer.test.ts (0) ❯ SessionTimer Durable Object (0) ❯ tests/websocketEndpoint.test.ts (3) ❯ POST /websocket (3) × should process peer:joined websocket event · should return error for invalid signature · should return error for unsupported event type workerd/server/server.c++:3059: error: Fallback service failed to fetch module; payload = ; spec = /?specifier=node%3Ahttps&referrer=%2FUsers%2Fzm%2FProjects%2Fcharli%2Fapps%2Fsession-time-tracker%2Fnode_modules%2Fethers%2Flib.esm%2Futils%2Fgeturl.js&rawSpecifier=node%3Ahttps workerd/server/server.c++:3059: error: Fallback service failed to fetch module; payload = ; spec = /?specifier=node%3Ahttps&referrer=%2FUsers%2Fzm%2FProjects%2Fcharli%2Fapps%2Fsession-time-tracker%2Fnode_modules%2Fethers%2Flib.esm%2Futils%2Fgeturl.js&rawSpecifier=node%3Ahttps workerd/server/server.c++:3059: error: Fallback service failed to fetch module; payload = ; spec = /?specifier=node%3Ahttps&referrer=%2FUsers%2Fzm%2FProjects%2Fcharli%2Fapps%2Fsession-time-tracker%2Fnode_modules%2Fethers%2Flib.esm%2Futils%2Fgeturl.js&rawSpecifier=node%3Ahttps workerd/server/server.c++:3059: error: Fallback service failed to fetch module; payload = ; spec = /?specifier=node%3Ahttps&referrer=%2FUsers%2Fzm%2FProjects%2Fcharli%2Fapps%2Fsession-time-tracker%2Fnode_modules%2Fethers%2Flib.esm%2Futils%2Fgeturl.js&rawSpecifier=node%3Ahttps workerd/server/server.c++:3059: error: Fallback service failed to fetch module; payload = ; spec = /?specifier=node%3Ahttps&referrer=%2FUsers%2Fzm%2FProjects%2Fcharli%2Fapps%2Fsession-time-tracker%2Fnode_modules%2Fethers%2Flib.esm%2Futils%2Fgeturl.js&rawSpecifier=node%3Ahttps workerd/server/server.c++:3059: error: Fallback service failed to fetch module; payload = ; spec = /?specifier=node%3Ahttps&referrer=%2FUsers%2Fzm%2FProjects%2Fcharli%2Fapps%2Fsession-time-tracker%2Fnode_modules%2Fethers%2Flib.esm%2 ❯ tests/connectionManager.test.ts (0) ❯ tests/initEndpoint.test.ts (0) ❯ tests/sessionTimer.test.ts (0) ❯ SessionTimer Durable Object (0) ❯ tests/webSocketManager.test.ts (0) ❯ tests/webhookEndpoint.test.ts (0) ❯ tests/websocketEndpoint.test.ts (3) ❯ POST /websocket (3) × should process peer:joined websocket event × should return error for invalid signature × should return error for unsupported event type ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ Failed Suites 6 ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ FAIL tests/connectionManager.test.ts [ tests/connectionManager.test.ts ] FAIL tests/initEndpoint.test.ts [ tests/initEndpoint.test.ts ] FAIL tests/webSocketManager.test.ts [ tests/webSocketManager.test.ts ] FAIL tests/webhookEndpoint.test.ts [ tests/webhookEndpoint.test.ts ] Error: No such module "node:https". imported from "Users/zm/Projects/charli/apps/session-time-tracker/node_modules/ethers/lib.esm/utils/geturl.js" ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[1/9]⎯ FAIL tests/sessionTimer.test.ts [ tests/sessionTimer.test.ts ] Error: No test found in suite tests/sessionTimer.test.ts ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[2/9]⎯ FAIL tests/sessionTimer.test.ts > SessionTimer Durable Object Error: No test found in suite SessionTimer Durable Object ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[3/9]⎯ ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ Failed Tests 3 ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ FAIL tests/websocketEndpoint.test.ts > POST /websocket > should process peer:joined websocket event AssertionError: expected 404 to be 200 // Object.is equality - Expected + Received - 200 + 404 ❯ tests/websocketEndpoint.test.ts:51:29 49| }); 50| 51| expect(response.status).toBe(200); | ^ 52| const text = await response.text(); 53| expect(text).toBe('Webhook processed successfully'); ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[4/9]⎯ FAIL tests/websocketEndpoint.test.ts > POST /websocket > should return error for invalid signature AssertionError: expected 404 to be 401 // Object.is equality - Expected + Received - 401 + 404 ❯ tests/websocketEndpoint.test.ts:78:29 76| }); 77| 78| expect(response.status).toBe(401); | ^ 79| const data = await response.json() as { status: string; message: string }; 80| ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[5/9]⎯ FAIL tests/websocketEndpoint.test.ts > POST /websocket > should return error for unsupported event type AssertionError: expected 404 to be 400 // Object.is equality - Expected + Received - 400 + 404 ❯ tests/websocketEndpoint.test.ts:98:29 96| }); 97| 98| expect(response.status).toBe(400); | ^ 99| const data = await response.json() as { status: string; message: string }; 100| ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[6/9]⎯ Test Files 6 failed (6) Tests 3 failed (3) Start at 18:38:11 Duration 918ms (transform 107ms, setup 131ms, collect 51ms, tests 52ms, environment 0ms, prepare 935ms) [vpw:dbg] Shutting down runtimes...