Search code examples
javascriptstreamjestjscloudflarecloudflare-workers

ReferenceError: TransformStream is not defined


I'm attempting to test the implementation of Fast Google Fonts with Cloudflare Workers, from Cloudflare's blog for inlining the Google Fonts stylesheet directly into the HTML. The implementation itself seems to be working fine when running via the Cloudflare worker. But I wrote some tests, and when running the tests, I get this error that says TransformStream is not defined.

Error when running my Jest test via npm run test:

ReferenceError: TransformStream is not defined

This is the code that the test is hitting:

async function processHtmlResponse(request, response) {
  ...

  // This is where the reference error comes up 
  const { readable, writable } = new TransformStream();

  const newResponse = new Response(readable, response);
  modifyHtmlStream(response.body, writable, request, embedStylesheet);

  return newResponse;
}

This test looks something like this, where we basically expect that the stylesheet link will be replaced by the stylesheet itself, containing all the @font-face styles.

describe('inlineGoogleFontsHtml', () => {
  it('inlines the response of a Google Fonts stylesheet link within an HTML response', async () => {
    const request = new Request('https://example.com')
    const response = new Response(
        '<html><head><link rel="stylesheet" media="screen" href="https://fonts.googleapis.com/css?family=Lato:300"></head><body></body></html>',
        {
          headers: {
            'Content-Type': 'text/html'
          }
        }
    )
    const rewrittenResponse = processHtmlResponse(request, response)
    const rewrittenResponseText = await rewrittenResponse.text()
    expect(rewrittenResponseText).toContain('@font-face')
})

I'm not really sure what the issue is here. Does TransformStream work in Node? Is there some polyfill that's needed?

Related: Cloudflare streams


Solution

  • TransformStream is part of the Streams API, a browser-side standard. It is not implemented by Node (because they had their own streams long before this spec existed), so you will need a polyfill when testing your code in Node.

    Incidentally, the example you're following is fairly old. These days, it would be better to use HTMLRewriter to implement this kind of transformation -- it is much more efficient for rewriting HTML specifically. (However, it is a Cloudflare-specific feature, so you wouldn't be able to test it under Node at all.)