Repository: facebook/react
Pull request: [Float][Fizz]: Don't preload nomodule scripts

We attempt to preload scripts that we detect during Fizz rendering however when `noModule={true}` we should not because it will force modern browser to fetch scripts they will never execute

Hoisted script resources already don't preload because we just emit the resource immediately. This change currently on affects the preloads for scripts that aren't hoistable

Changed files:
filename: packages/react-dom-bindings/src/server/ReactDOMServerFormatConfig.js
patch: @@ -2056,25 +2056,28 @@ function pushScript(
     const src = props.src;
     const key = getResourceKey('script', src);
     if (props.async !== true || props.onLoad || props.onError) {
-      // We can't resourcify scripts with load listeners. To avoid ambiguity with
-      // other Resourcified async scripts on the server we omit them from the server
-      // stream and expect them to be inserted during hydration on the client.
-      // We can still preload them however so the client can start fetching the script
-      // as soon as possible
-      let resource = resources.preloadsMap.get(key);
-      if (!resource) {
-        resource = {
-          type: 'preload',
-          chunks: [],
-          state: NoState,
-          props: preloadAsScriptPropsFromProps(props.src, props),
-        };
-        resources.preloadsMap.set(key, resource);
-        if (__DEV__) {
-          markAsImplicitResourceDEV(resource, props, resource.props);
+      // we don't want to preload nomodule scripts
+      if (props.noModule !== true) {
+        // We can't resourcify scripts with load listeners. To avoid ambiguity with
+        // other Resourcified async scripts on the server we omit them from the server
+        // stream and expect them to be inserted during hydration on the client.
+        // We can still preload them however so the client can start fetching the script
+        // as soon as possible
+        let resource = resources.preloadsMap.get(key);
+        if (!resource) {
+          resource = {
+            type: 'preload',
+            chunks: [],
+            state: NoState,
+            props: preloadAsScriptPropsFromProps(props.src, props),
+          };
+          resources.preloadsMap.set(key, resource);
+          if (__DEV__) {
+            markAsImplicitResourceDEV(resource, props, resource.props);
+          }
+          resources.usedScripts.add(resource);
+          pushLinkImpl(resource.chunks, resource.props);
         }
-        resources.usedScripts.add(resource);
-        pushLinkImpl(resource.chunks, resource.props);
       }
 
       if (props.async !== true) {

filename: packages/react-dom/src/__tests__/ReactDOMFloat-test.js
patch: @@ -2639,6 +2639,29 @@ body {
     );
   });
 
+  it('does not preload nomodule scripts', async () => {
+    await actIntoEmptyDocument(() => {
+      renderToPipeableStream(
+        <html>
+          <body>
+            <script src="foo" noModule={true} data-meaningful="" />
+            <script async={true} src="bar" noModule={true} data-meaningful="" />
+          </body>
+        </html>,
+      ).pipe(writable);
+    });
+    expect(getMeaningfulChildren(document)).toEqual(
+      <html>
+        <head>
+          <script async="" src="bar" nomodule="" data-meaningful="" />
+        </head>
+        <body>
+          <script src="foo" nomodule="" data-meaningful="" />
+        </body>
+      </html>,
+    );
+  });
+
   describe('ReactDOM.prefetchDNS(href)', () => {
     it('creates a dns-prefetch resource when called', async () => {
       function App({url}) {