@@ -2642,128 +2642,102 @@ function pushScript(
26422642 noscriptTagInScope : boolean ,
26432643) : null {
26442644 if ( enableFloat ) {
2645+ const asyncProp = props . async ;
26452646 if (
2647+ typeof props . src !== 'string' ||
2648+ ! props . src ||
2649+ ! (
2650+ asyncProp &&
2651+ typeof asyncProp !== 'function' &&
2652+ typeof asyncProp !== 'symbol'
2653+ ) ||
2654+ props . onLoad ||
2655+ props . onError ||
26462656 insertionMode === SVG_MODE ||
26472657 noscriptTagInScope ||
2648- props . itemProp != null ||
2649- typeof props . src !== 'string' ||
2650- ! props . src
2658+ props . itemProp != null
26512659 ) {
2652- // This script will not be a resource nor can it be preloaded, we bailout early
2653- // and emit it in place.
2660+ // This script will not be a resource, we bailout early and emit it in place.
26542661 return pushScriptImpl ( target , props ) ;
26552662 }
26562663
26572664 const src = props . src ;
26582665 const key = getResourceKey ( 'script' , src ) ;
2659- if ( props . async !== true || props . onLoad || props . onError ) {
2660- // we don't want to preload nomodule scripts
2661- if ( props . noModule !== true ) {
2662- // We can't resourcify scripts with load listeners. To avoid ambiguity with
2663- // other Resourcified async scripts on the server we omit them from the server
2664- // stream and expect them to be inserted during hydration on the client.
2665- // We can still preload them however so the client can start fetching the script
2666- // as soon as possible
2667- let resource = resources . preloadsMap . get ( key ) ;
2668- if ( ! resource ) {
2669- resource = {
2670- type : 'preload ',
2671- chunks : [ ] ,
2672- state : NoState ,
2673- props : preloadAsScriptPropsFromProps ( props . src , props ) ,
2674- } ;
2675- resources . preloadsMap . set ( key , resource ) ;
2676- if ( __DEV__ ) {
2677- markAsImplicitResourceDEV ( resource , props , resource . props ) ;
2666+ // We can make this <script> into a ScriptResource
2667+ let resource = resources . scriptsMap . get ( key ) ;
2668+ if ( __DEV__ ) {
2669+ const devResource = getAsResourceDEV ( resource ) ;
2670+ if ( devResource ) {
2671+ switch ( devResource . __provenance ) {
2672+ case 'rendered ': {
2673+ const differenceDescription = describeDifferencesForScripts (
2674+ // Diff the props from the JSX element, not the derived resource props
2675+ props ,
2676+ devResource . __originalProps ,
2677+ ) ;
2678+ if ( differenceDescription ) {
2679+ console . error (
2680+ 'React encountered a <script async={true} src="%s" .../> that has props that conflict' +
2681+ ' with another hoistable script with the same `src`. When rendering hoistable scripts (async scripts without any loading handlers)' +
2682+ ' the props from the first encountered instance will be used and props from later instances will be ignored.' +
2683+ ' Update the props on both <script async={true} .../> instance so they agree.%s' ,
2684+ src ,
2685+ differenceDescription ,
2686+ ) ;
2687+ }
2688+ break ;
26782689 }
2679- resources . usedScripts . add ( resource ) ;
2680- pushLinkImpl ( resource . chunks , resource . props ) ;
2681- }
2682- }
2683-
2684- if ( props . async !== true ) {
2685- // This is not an async script, we can preloaded it but it still needs to
2686- // be emitted in place since it needs to hydrate on the client
2687- pushScriptImpl ( target , props ) ;
2688- return null ;
2689- }
2690- } else {
2691- // We can make this <script> into a ScriptResource
2692- let resource = resources . scriptsMap . get ( key ) ;
2693- if ( __DEV__ ) {
2694- const devResource = getAsResourceDEV ( resource ) ;
2695- if ( devResource ) {
2696- switch ( devResource . __provenance ) {
2697- case 'rendered' : {
2698- const differenceDescription = describeDifferencesForScripts (
2690+ case 'preinit ': {
2691+ const differenceDescription =
2692+ describeDifferencesForScriptOverPreinit (
26992693 // Diff the props from the JSX element, not the derived resource props
27002694 props ,
2701- devResource . __originalProps ,
2695+ devResource . __propsEquivalent ,
2696+ ) ;
2697+ if ( differenceDescription ) {
2698+ console . error (
2699+ 'React encountered a <script async={true} src="%s" .../> with props that conflict' +
2700+ ' with the options provided to `ReactDOM.preinit("%s", { as: "script", ... })`. React will use the first props or preinitialization' +
2701+ ' options encountered when rendering a hoistable script with a particular `src` and will ignore any newer props or' +
2702+ ' options. The first instance of this script resource was created using the `ReactDOM.preinit()` function.' +
2703+ ' Please note, `ReactDOM.preinit()` is modeled off of module import assertions capabilities and does not support' +
2704+ ' arbitrary props. If you need to have props not included with the preinit options you will need to rely on rendering' +
2705+ ' <script> tags only.%s' ,
2706+ src ,
2707+ src ,
2708+ differenceDescription ,
27022709 ) ;
2703- if ( differenceDescription ) {
2704- console . error (
2705- 'React encountered a <script async={true} src="%s" .../> that has props that conflict' +
2706- ' with another hoistable script with the same `src`. When rendering hoistable scripts (async scripts without any loading handlers)' +
2707- ' the props from the first encountered instance will be used and props from later instances will be ignored.' +
2708- ' Update the props on both <script async={true} .../> instance so they agree.%s' ,
2709- src ,
2710- differenceDescription ,
2711- ) ;
2712- }
2713- break ;
2714- }
2715- case 'preinit' : {
2716- const differenceDescription =
2717- describeDifferencesForScriptOverPreinit (
2718- // Diff the props from the JSX element, not the derived resource props
2719- props ,
2720- devResource . __propsEquivalent ,
2721- ) ;
2722- if ( differenceDescription ) {
2723- console . error (
2724- 'React encountered a <script async={true} src="%s" .../> with props that conflict' +
2725- ' with the options provided to `ReactDOM.preinit("%s", { as: "script", ... })`. React will use the first props or preinitialization' +
2726- ' options encountered when rendering a hoistable script with a particular `src` and will ignore any newer props or' +
2727- ' options. The first instance of this script resource was created using the `ReactDOM.preinit()` function.' +
2728- ' Please note, `ReactDOM.preinit()` is modeled off of module import assertions capabilities and does not support' +
2729- ' arbitrary props. If you need to have props not included with the preinit options you will need to rely on rendering' +
2730- ' <script> tags only.%s' ,
2731- src ,
2732- src ,
2733- differenceDescription ,
2734- ) ;
2735- }
2736- break ;
27372710 }
2711+ break ;
27382712 }
27392713 }
27402714 }
2741- if ( ! resource ) {
2742- resource = {
2743- type : 'script' ,
2744- chunks : [ ] ,
2745- state : NoState ,
2746- props : null ,
2747- } ;
2748- resources . scriptsMap . set ( key , resource ) ;
2749- if ( __DEV__ ) {
2750- markAsRenderedResourceDEV ( resource , props ) ;
2751- }
2752- // Add to the script flushing queue
2753- resources . scripts . add ( resource ) ;
2754-
2755- let scriptProps = props ;
2756- const preloadResource = resources . preloadsMap . get ( key ) ;
2757- if ( preloadResource ) {
2758- // If we already had a preload we don't want that resource to flush directly.
2759- // We let the newly created resource govern flushing.
2760- preloadResource . state |= Blocked ;
2761- scriptProps = { ...props } ;
2762- adoptPreloadPropsForScriptProps ( scriptProps , preloadResource . props ) ;
2763- }
2764- // encode the tag as Chunks
2765- pushScriptImpl ( resource . chunks , scriptProps) ;
2715+ }
2716+ if ( ! resource ) {
2717+ resource = {
2718+ type : 'script ',
2719+ chunks : [ ] ,
2720+ state : NoState ,
2721+ props : null ,
2722+ } ;
2723+ resources . scriptsMap . set ( key , resource ) ;
2724+ if ( __DEV__ ) {
2725+ markAsRenderedResourceDEV ( resource , props ) ;
2726+ }
2727+ // Add to the script flushing queue
2728+ resources . scripts . add ( resource ) ;
2729+
2730+ let scriptProps = props ;
2731+ const preloadResource = resources . preloadsMap . get ( key ) ;
2732+ if ( preloadResource ) {
2733+ // If we already had a preload we don't want that resource to flush directly.
2734+ // We let the newly created resource govern flushing.
2735+ preloadResource. state |= Blocked ;
2736+ scriptProps = { ...props } ;
2737+ adoptPreloadPropsForScriptProps ( scriptProps , preloadResource . props ) ;
27662738 }
2739+ // encode the tag as Chunks
2740+ pushScriptImpl ( resource . chunks , scriptProps ) ;
27672741 }
27682742
27692743 if ( textEmbedded ) {
@@ -4239,9 +4213,6 @@ export function writePreamble(
42394213 resources . scripts . forEach ( flushResourceInPreamble , destination ) ;
42404214 resources . scripts . clear ( ) ;
42414215
4242- resources . usedScripts . forEach ( flushResourceInPreamble , destination ) ;
4243- resources . usedScripts . clear ( ) ;
4244-
42454216 resources . explicitStylesheetPreloads . forEach (
42464217 flushResourceInPreamble ,
42474218 destination ,
@@ -4319,9 +4290,6 @@ export function writeHoistables(
43194290 resources . scripts . forEach ( flushResourceLate , destination ) ;
43204291 resources . scripts . clear ( ) ;
43214292
4322- resources . usedScripts . forEach ( flushResourceLate , destination ) ;
4323- resources . usedScripts . clear ( ) ;
4324-
43254293 resources . explicitStylesheetPreloads . forEach ( flushResourceLate , destination ) ;
43264294 resources . explicitStylesheetPreloads . clear ( ) ;
43274295
@@ -4873,7 +4841,6 @@ export type Resources = {
48734841 precedences : Map < string , Set < StyleResource> > ,
48744842 stylePrecedences : Map < string , StyleTagResource> ,
48754843 scripts : Set < ScriptResource > ,
4876- usedScripts : Set < PreloadResource > ,
48774844 explicitStylesheetPreloads : Set < PreloadResource > ,
48784845 // explicitImagePreloads: Set<PreloadResource>,
48794846 explicitScriptPreloads : Set < PreloadResource > ,
@@ -4900,7 +4867,6 @@ export function createResources(): Resources {
49004867 precedences : new Map ( ) ,
49014868 stylePrecedences : new Map ( ) ,
49024869 scripts : new Set ( ) ,
4903- usedScripts : new Set ( ) ,
49044870 explicitStylesheetPreloads : new Set ( ) ,
49054871 // explicitImagePreloads: new Set(),
49064872 explicitScriptPreloads : new Set ( ) ,
@@ -5563,19 +5529,6 @@ function preloadAsStylePropsFromProps(href: string, props: any): PreloadProps {
55635529 } ;
55645530}
55655531
5566- function preloadAsScriptPropsFromProps ( href : string , props : any ) : PreloadProps {
5567- return {
5568- rel : 'preload' ,
5569- as : 'script' ,
5570- href,
5571- crossOrigin : props . crossOrigin ,
5572- fetchPriority : props . fetchPriority ,
5573- integrity : props . integrity ,
5574- nonce : props . nonce ,
5575- referrerPolicy : props . referrerPolicy ,
5576- } ;
5577- }
5578-
55795532function stylesheetPropsFromPreinitOptions (
55805533 href : string ,
55815534 precedence : string ,
@@ -5694,29 +5647,6 @@ function markAsImperativeResourceDEV(
56945647 }
56955648}
56965649
5697- function markAsImplicitResourceDEV (
5698- resource : Resource ,
5699- underlyingProps : any ,
5700- impliedProps : any ,
5701- ) : void {
5702- if ( __DEV__ ) {
5703- const devResource : ImplicitResourceDEV = ( resource : any ) ;
5704- if ( typeof devResource . __provenance === 'string' ) {
5705- console . error (
5706- 'Resource already marked for DEV type. This is a bug in React.' ,
5707- ) ;
5708- }
5709- devResource . __provenance = 'implicit' ;
5710- devResource . __underlyingProps = underlyingProps ;
5711- devResource . __impliedProps = impliedProps ;
5712- } else {
5713- // eslint-disable-next-line react-internal/prod-error-codes
5714- throw new Error (
5715- 'markAsImplicitResourceDEV was included in a production build. This is a bug in React.' ,
5716- ) ;
5717- }
5718- }
5719-
57205650function getAsResourceDEV (
57215651 resource : null | void | Resource ,
57225652) : null | ResourceDEV {
0 commit comments