Repository: remix-run/react-router
File: integration/prefetch-test.ts (TypeScript)

Code before:
          await page.waitForSelector(
            "#nav link[rel='prefetch'][as='fetch'][href='/with-loader.data']",
            { state: "attached" }
          );
          await page.waitForSelector(
            "#nav link[rel='modulepreload'][href^='/assets/with-loader-']",
            { state: "attached" }
          );

          // Only asset fetch for /without-loader
          await page.waitForSelector(
            "#nav link[rel='modulepreload'][href^='/assets/without-loader-']",
            { state: "attached" }
          );

          // These 2 are common and duped for both - but they've already loaded on
          // page load so they don't trigger network requests
          await page.waitForSelector(
            "#nav link[rel='modulepreload'][href^='/assets/with-props-']",
            { state: "attached" }
          );
          await page.waitForSelector(
            // Look for either Rollup or Rolldown chunks
            [
              // Rollup bundles RR (and transitively React) into an index chunk
              "#nav link[rel='modulepreload'][href^='/assets/index-']",
              "#nav link[rel='modulepreload'][href^='/assets/jsx-runtime-']",
            ].join(","),
            { state: "attached" }
          );

          // Ensure no other links in the #nav element
          expect(await page.locator("#nav link").count()).toBe(7);
        });
      });

      test.describe("prefetch=intent (hover)", () => {
        let fixture: Fixture;
        let appFixture: AppFixture;

        test.beforeAll(async () => {
          fixture = await createFixture(fixtureFactory("intent", templateName));
          appFixture = await createAppFixture(fixture);
        });

        test.afterAll(() => {
          appFixture.close();
        });

        test("does not render prefetch tags during SSR", async ({ page }) => {
          let res = await fixture.requestDocument("/");

Review comment (suggestion):
@markdalgleish Does this feel expected or unexpected to you now that I added the external config to ESM?  I'm temped to remove it so we stick with the prior ESM handling...

Code after:
          await page.waitForSelector(
            "#nav link[rel='prefetch'][as='fetch'][href='/with-loader.data']",
            { state: "attached" }
          );
          await page.waitForSelector(
            "#nav link[rel='modulepreload'][href^='/assets/with-loader-']",
            { state: "attached" }
          );

          // Only asset fetch for /without-loader
          await page.waitForSelector(
            "#nav link[rel='modulepreload'][href^='/assets/without-loader-']",
            { state: "attached" }
          );

          // These 2 are common and duped for both - but they've already loaded on
          // page load so they don't trigger network requests
          await page.waitForSelector(
            "#nav link[rel='modulepreload'][href^='/assets/with-props-']",
            { state: "attached" }
          );
          await page.waitForSelector(
            // Look for either Rollup or Rolldown chunks
            [
              "#nav link[rel='modulepreload'][href^='/assets/chunk-']",
              "#nav link[rel='modulepreload'][href^='/assets/jsx-runtime-']",
            ].join(","),
            { state: "attached" }
          );

          // Ensure no other links in the #nav element
          expect(await page.locator("#nav link").count()).toBe(7);
        });
      });

      test.describe("prefetch=intent (hover)", () => {
        let fixture: Fixture;
        let appFixture: AppFixture;

        test.beforeAll(async () => {
          fixture = await createFixture(fixtureFactory("intent", templateName));
          appFixture = await createAppFixture(fixture);
        });

        test.afterAll(() => {
          appFixture.close();
        });

        test("does not render prefetch tags during SSR", async ({ page }) => {
          let res = await fixture.requestDocument("/");
          expect(res.status).toBe(200);