@@ -2637,128 +2637,102 @@ function pushScript(
26372637 noscriptTagInScope : boolean ,
26382638) : null {
26392639 if ( enableFloat ) {
2640+ const asyncProp = props . async ;
26402641 if (
2642+ typeof props . src !== 'string' ||
2643+ ! props . src ||
2644+ ! (
2645+ asyncProp &&
2646+ typeof asyncProp !== 'function' &&
2647+ typeof asyncProp !== 'symbol'
2648+ ) ||
2649+ props . onLoad ||
2650+ props . onError ||
26412651 insertionMode === SVG_MODE ||
26422652 noscriptTagInScope ||
2643- props . itemProp != null ||
2644- typeof props . src !== 'string' ||
2645- ! props . src
2653+ props . itemProp != null
26462654 ) {
2647- // This script will not be a resource nor can it be preloaded, we bailout early
2648- // and emit it in place.
2655+ // This script will not be a resource, we bailout early and emit it in place.
26492656 return pushScriptImpl ( target , props ) ;
26502657 }
26512658
26522659 const src = props . src ;
26532660 const key = getResourceKey ( 'script' , src ) ;
2654- if ( props . async !== true || props . onLoad || props . onError ) {
2655- // we don't want to preload nomodule scripts
2656- if ( props . noModule !== true ) {
2657- // We can't resourcify scripts with load listeners. To avoid ambiguity with
2658- // other Resourcified async scripts on the server we omit them from the server
2659- // stream and expect them to be inserted during hydration on the client.
2660- // We can still preload them however so the client can start fetching the script
2661- // as soon as possible
2662- let resource = resources . preloadsMap . get ( key ) ;
2663- if ( ! resource ) {
2664- resource = {
2665- type : 'preload ',
2666- chunks : [ ] ,
2667- state : NoState ,
2668- props : preloadAsScriptPropsFromProps ( props . src , props ) ,
2669- } ;
2670- resources . preloadsMap . set ( key , resource ) ;
2671- if ( __DEV__ ) {
2672- markAsImplicitResourceDEV ( resource , props , resource . props ) ;
2661+ // We can make this <script> into a ScriptResource
2662+ let resource = resources . scriptsMap . get ( key ) ;
2663+ if ( __DEV__ ) {
2664+ const devResource = getAsResourceDEV ( resource ) ;
2665+ if ( devResource ) {
2666+ switch ( devResource . __provenance ) {
2667+ case 'rendered ': {
2668+ const differenceDescription = describeDifferencesForScripts (
2669+ // Diff the props from the JSX element, not the derived resource props
2670+ props ,
2671+ devResource . __originalProps ,
2672+ ) ;
2673+ if ( differenceDescription ) {
2674+ console . error (
2675+ 'React encountered a <script async={true} src="%s" .../> that has props that conflict' +
2676+ ' with another hoistable script with the same `src`. When rendering hoistable scripts (async scripts without any loading handlers)' +
2677+ ' the props from the first encountered instance will be used and props from later instances will be ignored.' +
2678+ ' Update the props on both <script async={true} .../> instance so they agree.%s' ,
2679+ src ,
2680+ differenceDescription ,
2681+ ) ;
2682+ }
2683+ break ;
26732684 }
2674- resources . usedScripts . add ( resource ) ;
2675- pushLinkImpl ( resource . chunks , resource . props ) ;
2676- }
2677- }
2678-
2679- if ( props . async !== true ) {
2680- // This is not an async script, we can preloaded it but it still needs to
2681- // be emitted in place since it needs to hydrate on the client
2682- pushScriptImpl ( target , props ) ;
2683- return null ;
2684- }
2685- } else {
2686- // We can make this <script> into a ScriptResource
2687- let resource = resources . scriptsMap . get ( key ) ;
2688- if ( __DEV__ ) {
2689- const devResource = getAsResourceDEV ( resource ) ;
2690- if ( devResource ) {
2691- switch ( devResource . __provenance ) {
2692- case 'rendered' : {
2693- const differenceDescription = describeDifferencesForScripts (
2685+ case 'preinit ': {
2686+ const differenceDescription =
2687+ describeDifferencesForScriptOverPreinit (
26942688 // Diff the props from the JSX element, not the derived resource props
26952689 props ,
2696- devResource . __originalProps ,
2690+ devResource . __propsEquivalent ,
2691+ ) ;
2692+ if ( differenceDescription ) {
2693+ console . error (
2694+ 'React encountered a <script async={true} src="%s" .../> with props that conflict' +
2695+ ' with the options provided to `ReactDOM.preinit("%s", { as: "script", ... })`. React will use the first props or preinitialization' +
2696+ ' options encountered when rendering a hoistable script with a particular `src` and will ignore any newer props or' +
2697+ ' options. The first instance of this script resource was created using the `ReactDOM.preinit()` function.' +
2698+ ' Please note, `ReactDOM.preinit()` is modeled off of module import assertions capabilities and does not support' +
2699+ ' arbitrary props. If you need to have props not included with the preinit options you will need to rely on rendering' +
2700+ ' <script> tags only.%s' ,
2701+ src ,
2702+ src ,
2703+ differenceDescription ,
26972704 ) ;
2698- if ( differenceDescription ) {
2699- console . error (
2700- 'React encountered a <script async={true} src="%s" .../> that has props that conflict' +
2701- ' with another hoistable script with the same `src`. When rendering hoistable scripts (async scripts without any loading handlers)' +
2702- ' the props from the first encountered instance will be used and props from later instances will be ignored.' +
2703- ' Update the props on both <script async={true} .../> instance so they agree.%s' ,
2704- src ,
2705- differenceDescription ,
2706- ) ;
2707- }
2708- break ;
2709- }
2710- case 'preinit' : {
2711- const differenceDescription =
2712- describeDifferencesForScriptOverPreinit (
2713- // Diff the props from the JSX element, not the derived resource props
2714- props ,
2715- devResource . __propsEquivalent ,
2716- ) ;
2717- if ( differenceDescription ) {
2718- console . error (
2719- 'React encountered a <script async={true} src="%s" .../> with props that conflict' +
2720- ' with the options provided to `ReactDOM.preinit("%s", { as: "script", ... })`. React will use the first props or preinitialization' +
2721- ' options encountered when rendering a hoistable script with a particular `src` and will ignore any newer props or' +
2722- ' options. The first instance of this script resource was created using the `ReactDOM.preinit()` function.' +
2723- ' Please note, `ReactDOM.preinit()` is modeled off of module import assertions capabilities and does not support' +
2724- ' arbitrary props. If you need to have props not included with the preinit options you will need to rely on rendering' +
2725- ' <script> tags only.%s' ,
2726- src ,
2727- src ,
2728- differenceDescription ,
2729- ) ;
2730- }
2731- break ;
27322705 }
2706+ break ;
27332707 }
27342708 }
27352709 }
2736- if ( ! resource ) {
2737- resource = {
2738- type : 'script' ,
2739- chunks : [ ] ,
2740- state : NoState ,
2741- props : null ,
2742- } ;
2743- resources . scriptsMap . set ( key , resource ) ;
2744- if ( __DEV__ ) {
2745- markAsRenderedResourceDEV ( resource , props ) ;
2746- }
2747- // Add to the script flushing queue
2748- resources . scripts . add ( resource ) ;
2749-
2750- let scriptProps = props ;
2751- const preloadResource = resources . preloadsMap . get ( key ) ;
2752- if ( preloadResource ) {
2753- // If we already had a preload we don't want that resource to flush directly.
2754- // We let the newly created resource govern flushing.
2755- preloadResource . state |= Blocked ;
2756- scriptProps = { ...props } ;
2757- adoptPreloadPropsForScriptProps ( scriptProps , preloadResource . props ) ;
2758- }
2759- // encode the tag as Chunks
2760- pushScriptImpl ( resource . chunks , scriptProps) ;
2710+ }
2711+ if ( ! resource ) {
2712+ resource = {
2713+ type : 'script ',
2714+ chunks : [ ] ,
2715+ state : NoState ,
2716+ props : null ,
2717+ } ;
2718+ resources . scriptsMap . set ( key , resource ) ;
2719+ if ( __DEV__ ) {
2720+ markAsRenderedResourceDEV ( resource , props ) ;
27612721 }
2722+ // Add to the script flushing queue
2723+ resources . scripts . add ( resource ) ;
2724+
2725+ let scriptProps = props ;
2726+ const preloadResource = resources . preloadsMap . get ( key ) ;
2727+ if ( preloadResource ) {
2728+ // If we already had a preload we don't want that resource to flush directly.
2729+ // We let the newly created resource govern flushing.
2730+ preloadResource. state |= Blocked ;
2731+ scriptProps = { ...props } ;
2732+ adoptPreloadPropsForScriptProps ( scriptProps , preloadResource . props ) ;
2733+ }
2734+ // encode the tag as Chunks
2735+ pushScriptImpl ( resource . chunks , scriptProps ) ;
27622736 }
27632737
27642738 if ( textEmbedded ) {
@@ -4234,9 +4208,6 @@ export function writePreamble(
42344208 resources . scripts . forEach ( flushResourceInPreamble , destination ) ;
42354209 resources . scripts . clear ( ) ;
42364210
4237- resources . usedScripts . forEach ( flushResourceInPreamble , destination ) ;
4238- resources . usedScripts . clear ( ) ;
4239-
42404211 resources . explicitStylesheetPreloads . forEach (
42414212 flushResourceInPreamble ,
42424213 destination ,
@@ -4314,9 +4285,6 @@ export function writeHoistables(
43144285 resources . scripts . forEach ( flushResourceLate , destination ) ;
43154286 resources . scripts . clear ( ) ;
43164287
4317- resources . usedScripts . forEach ( flushResourceLate , destination ) ;
4318- resources . usedScripts . clear ( ) ;
4319-
43204288 resources . explicitStylesheetPreloads . forEach ( flushResourceLate , destination ) ;
43214289 resources . explicitStylesheetPreloads . clear ( ) ;
43224290
@@ -4862,7 +4830,6 @@ export type Resources = {
48624830 precedences : Map < string , Set < StyleResource> > ,
48634831 stylePrecedences : Map < string , StyleTagResource> ,
48644832 scripts : Set < ScriptResource > ,
4865- usedScripts : Set < PreloadResource > ,
48664833 explicitStylesheetPreloads : Set < PreloadResource > ,
48674834 // explicitImagePreloads: Set<PreloadResource>,
48684835 explicitScriptPreloads : Set < PreloadResource > ,
@@ -4889,7 +4856,6 @@ export function createResources(): Resources {
48894856 precedences : new Map ( ) ,
48904857 stylePrecedences : new Map ( ) ,
48914858 scripts : new Set ( ) ,
4892- usedScripts : new Set ( ) ,
48934859 explicitStylesheetPreloads : new Set ( ) ,
48944860 // explicitImagePreloads: new Set(),
48954861 explicitScriptPreloads : new Set ( ) ,
@@ -5469,19 +5435,6 @@ function preloadAsStylePropsFromProps(href: string, props: any): PreloadProps {
54695435 } ;
54705436}
54715437
5472- function preloadAsScriptPropsFromProps ( href : string , props : any ) : PreloadProps {
5473- return {
5474- rel : 'preload' ,
5475- as : 'script' ,
5476- href,
5477- crossOrigin : props . crossOrigin ,
5478- fetchPriority : props . fetchPriority ,
5479- integrity : props . integrity ,
5480- nonce : props . nonce ,
5481- referrerPolicy : props . referrerPolicy ,
5482- } ;
5483- }
5484-
54855438function stylesheetPropsFromPreinitOptions (
54865439 href : string ,
54875440 precedence : string ,
@@ -5598,29 +5551,6 @@ function markAsImperativeResourceDEV(
55985551 }
55995552}
56005553
5601- function markAsImplicitResourceDEV (
5602- resource : Resource ,
5603- underlyingProps : any ,
5604- impliedProps : any ,
5605- ) : void {
5606- if ( __DEV__ ) {
5607- const devResource : ImplicitResourceDEV = ( resource : any ) ;
5608- if ( typeof devResource . __provenance === 'string' ) {
5609- console . error (
5610- 'Resource already marked for DEV type. This is a bug in React.' ,
5611- ) ;
5612- }
5613- devResource . __provenance = 'implicit' ;
5614- devResource . __underlyingProps = underlyingProps ;
5615- devResource . __impliedProps = impliedProps ;
5616- } else {
5617- // eslint-disable-next-line react-internal/prod-error-codes
5618- throw new Error (
5619- 'markAsImplicitResourceDEV was included in a production build. This is a bug in React.' ,
5620- ) ;
5621- }
5622- }
5623-
56245554function getAsResourceDEV (
56255555 resource : null | void | Resource ,
56265556) : null | ResourceDEV {
0 commit comments