当前位置: 首页 > news >正文

React19源码系列之 API(react-dom)

API之 preconnect

preconnect – React 中文文档

preconnect 函数向浏览器提供一个提示,告诉它应该打开到给定服务器的连接。如果浏览器选择这样做,则可以加快从该服务器加载资源的速度。

preconnect(href)

一、使用例子

import { preconnect } from 'react-dom';function AppRoot() {preconnect("https://example.com");return ...;
}

import { preconnect } from 'react-dom';function CallToAction() {const onClick = () => {preconnect('http://example.com');startWizard();}return (<button onClick={onClick}>Start Wizard</button>);
}

二、源码

function preconnect(href: string, options?: ?PreconnectOptions) {if (typeof href === 'string') {const crossOrigin = options? getCrossOriginString(options.crossOrigin): null;ReactDOMSharedInternals.d /* ReactDOMCurrentDispatcher */.C(/* preconnect */ href, crossOrigin);}
}

ReactDOMSharedInternals.d.C

preconnect 函数的主要功能是发起一个 preconnect 操作,用于提前建立与指定 href 对应的服务器连接。 

function preconnect(href: string, crossOrigin?: ?CrossOriginEnum) {previousDispatcher.C(/* preconnect */ href, crossOrigin);preconnectAs('preconnect', href, crossOrigin);
}

API之 prefetchDNS

prefetchDNS – React 中文文档

prefetchDNS 函数向浏览器提供一个提示,告诉它应该查找给定服务器的 IP 地址。如果浏览器选择这样做,则可以加快从该服务器加载资源的速度。

一、使用示范

prefetchDNS 允许提前查找期望从中加载资源的服务器的 IP。

prefetchDNS("https://example.com");

二、源码分析

function prefetchDNS(href: string) {if (typeof href === 'string') {ReactDOMSharedInternals.d /* ReactDOMCurrentDispatcher */.D(/* prefetchDNS */ href);}
}

ReactDOMSharedInternals.d.D

prefetchDNS 函数的主要作用是预获取指定 href 对应的 DNS 信息。 

function prefetchDNS(href: string) {previousDispatcher.D(/* prefetchDNS */ href);preconnectAs('dns-prefetch', href, null);
}

preconnectAs

preconnectAs 函数用于创建 rel="preconnect"rel="dns-prefetch"link 元素,以提前建立与目标服务器的连接或解析 DNS,从而优化后续资源加载的性能。它会检查是否已存在相同配置的预连接标签,避免重复创建。

function preconnectAs(rel: 'preconnect' | 'dns-prefetch',href: string,crossOrigin: ?CrossOriginEnum,
) {// 获取documentconst ownerDocument = getGlobalDocument();if (ownerDocument && typeof href === 'string' && href) {const limitedEscapedHref =escapeSelectorAttributeValueInsideDoubleQuotes(href);// let key = `link[rel="${rel}"][href="${limitedEscapedHref}"]`;if (typeof crossOrigin === 'string') {key += `[crossorigin="${crossOrigin}"]`;}if (!preconnectsSet.has(key)) {preconnectsSet.add(key);const preconnectProps = {rel, crossOrigin, href};if (null === ownerDocument.querySelector(key)) {const instance = ownerDocument.createElement('link');// 设置link元素的属性setInitialProperties(instance, 'link', preconnectProps);// 标记可提升markNodeAsHoistable(instance);// 往head元素中添加子元素link标签(ownerDocument.head: any).appendChild(instance);}}}
}
类型作用使用场景
preconnect提前建立完成连接。(包括dns解析、tcp握手和 TLS协商)确定会理解加载跨域资源(如字体、API)
dns-prefetch仅提前解析dns,不建立TCP、TLS连接。

可能会在未来加载的资源(如广告、第三方内容),减少dns解析延迟。

 API之 preinit

preinit – React 中文文档

preinit 函数向浏览器提供一个提示,告诉它应该开始下载并执行给定的资源,这可以节省时间。preinit 的脚本在下载完成后执行。预初始化的样式表被插入到文档中,这会使它们立即生效。

preinit(href, options) 

参数

  • href:字符串,要下载并执行的资源的 URL。
  • options:对象,可以包含以下属性:
    • as:必需的字符串,表示资源的类型,可能的值包括 scriptstyle
    • precedence:字符串,与样式表一起使用时必需。指定样式表相对于其他样式表的插入位置。具有较高优先级的样式表可以覆盖具有较低优先级的样式表,可能的值包括 resetlowmediumhigh
    • crossOrigin:字符串,表示要使用的 CORS 策略,可能的值为 anonymoususe-credentials
    • integrity:字符串,为资源的加密哈希,用于 验证其真实性。
    • nonce:字符串,表示使用严格内容安全策略时允许资源的 加密随机数。
    • fetchPriority:字符串,表示建议获取资源的相对优先级,可能的值为 auto(默认值)、highlow

一、使用例子

1、加载script资源

import { preinit } from 'react-dom';function AppRoot() {preinit("https://example.com/script.js", {as: "script"});return ...;
}

2、加载style样式资源 

import { preinit } from 'react-dom';function AppRoot() {preinit("https://example.com/style.css", {as: "style", precedence: "medium"});return ...;
}

3、在事件程序中使用加载资源 

import { preinit } from 'react-dom';function CallToAction() {const onClick = () => {preinit("https://example.com/wizardStyles.css", {as: "style"});startWizard();}return (<button onClick={onClick}>Start Wizard</button>);
}

二、源码

function preinit(href: string, options: PreinitOptions) {if (typeof href === 'string' && options && typeof options.as === 'string') {// 获取要下载的资源类型const as = options.as;// 获取crossorigin属性的值,可能为use-credentials、空字符串或undefinedconst crossOrigin = getCrossOriginStringAs(as, options.crossOrigin);// 资源加密哈希const integrity =typeof options.integrity === 'string' ? options.integrity : undefined;// 资源优先级const fetchPriority =typeof options.fetchPriority === 'string'? options.fetchPriority: undefined;// 资源为样式表if (as === 'style') {ReactDOMSharedInternals.d /* ReactDOMCurrentDispatcher */.S(/* preinitStyle */href,// 资源链接typeof options.precedence === 'string'? options.precedence: undefined,// 资源优先级{crossOrigin,//integrity,//fetchPriority,//},);// 资源为script脚本} else if (as === 'script') {ReactDOMSharedInternals.d /* ReactDOMCurrentDispatcher */.X(/* preinitScript */ href, {crossOrigin,integrity,fetchPriority,nonce: typeof options.nonce === 'string' ? options.nonce : undefined,//安全策略随机数});}}
}

ReactDOMSharedInternals.d.S(preinitStyle)

preinitStyle 函数的主要功能是预处理样式资源。它会检查指定的样式资源(通过 href 标识)是否已存在于全局文档的样式资源中。如果不存在,会创建一个新的样式资源实例(link 元素),设置其属性,并插入到文档中,同时缓存该资源的相关信息。

function preinitStyle(href: string,precedence: ?string,options?: ?PreinitStyleOptions,
) {previousDispatcher.S(/* preinitStyle */ href, precedence, options);// 获取document对象const ownerDocument = getGlobalDocument();if (ownerDocument && href) {// 获取样式表信息,map类型const styles = getResourcesFromRoot(ownerDocument).hoistableStyles;// 将href解析返回 格式为‘href=xxxxx’const key = getStyleKey(href);precedence = precedence || 'default';// Check if this resource already existslet resource = styles.get(key);if (resource) {// We can early return. The resource exists and there is nothing// more to doreturn;}// 初始化资源const state = {loading: NotLoaded,preload: null,};// Attempt to hydrate instance from DOM// 查询选取器let instance: null | Instance = ownerDocument.querySelector(// `link[rel="stylesheet"][${key}]`getStylesheetSelectorFromKey(key),);if (instance) {// 资源已加载并插入state.loading = Loaded | Inserted;} else {// Construct a new instance and insert it// 处理link相关属性const stylesheetProps = Object.assign(({rel: 'stylesheet',href,'data-precedence': precedence,}: StylesheetProps),options,);const preloadProps = preloadPropsMap.get(key);if (preloadProps) {// 设置stylesheetProps对象中的属性,如title,crossOrigin,refferPolicyadoptPreloadPropsForStylesheet(stylesheetProps, preloadProps);}// 创建link标签const link = (instance = ownerDocument.createElement('link'));//标记markNodeAsHoistable(link);// 设置属性setInitialProperties(link, 'link', stylesheetProps);// 为link设置promise(link: any)._p = new Promise((resolve, reject) => {link.onload = resolve;link.onerror = reject;});// 处理 load 和 error 事件link.addEventListener('load', () => {state.loading |= Loaded;});link.addEventListener('error', () => {state.loading |= Errored;});state.loading |= Inserted;// 插入文档insertStylesheet(instance, precedence, ownerDocument);}// Construct a Resource and cache itresource = {type: 'stylesheet',instance,count: 1,state,};// 缓存资源styles.set(key, resource);return;}
}const preloadPropsMap: Map<string, PreloadProps | PreloadModuleProps> =new Map();

type LoadingState = number;
const NotLoaded = /*       */ 0b000;//0 未加载
const Loaded = /*          */ 0b001;//1 加载
const Errored = /*         */ 0b010;//2 出错
const Settled = /*         */ 0b011;//3
const Inserted = /*        */ 0b100;//4 插入

type StylesheetProps = {rel: 'stylesheet',href: string,'data-precedence': string,[string]: mixed,
};

function adoptPreloadPropsForStylesheet(stylesheetProps: StylesheetProps,preloadProps: PreloadProps | PreloadModuleProps,
): void {if (stylesheetProps.crossOrigin == null)stylesheetProps.crossOrigin = preloadProps.crossOrigin;if (stylesheetProps.referrerPolicy == null)stylesheetProps.referrerPolicy = preloadProps.referrerPolicy;if (stylesheetProps.title == null) stylesheetProps.title = preloadProps.title;
}

ReactDOMSharedInternals.d.X(preinitScript)

preinitScript 函数的主要功能是预初始化 JavaScript 脚本资源。它会检查指定 src 的脚本是否已存在于文档中,如果不存在则创建并插入一个新的 script 标签,同时缓存该资源的相关信息。该函数支持从现有 DOM 中复用脚本实例,也能处理预加载属性,并确保脚本以异步方式加载。

function preinitScript(src: string, options?: ?PreinitScriptOptions) {previousDispatcher.X(/* preinitScript */ src, options);// 获取document对象const ownerDocument = getGlobalDocument();if (ownerDocument && src) {// 获取资源const scripts = getResourcesFromRoot(ownerDocument).hoistableScripts;// src=xxxxconst key = getScriptKey(src);// Check if this resource already existslet resource = scripts.get(key);if (resource) {// We can early return. The resource exists and there is nothing// more to doreturn;}// Attempt to hydrate instance from DOMlet instance: null | Instance = ownerDocument.querySelector(getScriptSelectorFromKey(key),);if (!instance) {// Construct a new instance and insert itconst scriptProps = Object.assign(({src,async: true,// 异步加载}: ScriptProps),options,);// Adopt certain preload propsconst preloadProps = preloadPropsMap.get(key);if (preloadProps) {// 设置属性integrity、referrerPolicy、crossOriginadoptPreloadPropsForScript(scriptProps, preloadProps);}// 创建script标签instance = ownerDocument.createElement('script');// 打标记markNodeAsHoistable(instance);// 设置属性setInitialProperties(instance, 'link', scriptProps);// 添加(ownerDocument.head: any).appendChild(instance);}// Construct a Resource and cache itresource = {type: 'script',instance,count: 1,state: null,};scripts.set(key, resource);return;}
}

function getScriptSelectorFromKey(key: string): string {return 'script[async]' + key;
}

function adoptPreloadPropsForScript(scriptProps: ScriptProps,preloadProps: PreloadProps | PreloadModuleProps,
): void {if (scriptProps.crossOrigin == null)scriptProps.crossOrigin = preloadProps.crossOrigin;if (scriptProps.referrerPolicy == null)scriptProps.referrerPolicy = preloadProps.referrerPolicy;if (scriptProps.integrity == null)scriptProps.integrity = preloadProps.integrity;
}

API之 preinitModule

preinitModule – React 中文文档

preinitModule 函数向浏览器提供一个提示,告诉它应该开始下载并执行给定的模块,这可以节省时间。预初始化的模块在下载完成后执行。

preinitModule(href, options) 

参数

  • href:字符串,要下载并执行的模块的 URL。
  • options:对象,可以包含以下属性:
    • as:必需的字符串,只能是 script
    • crossOrigin:字符串,表示要使用的 CORS 策略,可能的值为 anonymoususe-credentials
    • integrity:字符串,为资源的加密哈希,用于 验证其真实性。
    • nonce:字符串,表示使用严格内容安全策略时允许资源的 加密随机数。

一、使用示范

import { preinitModule } from 'react-dom';function AppRoot() {preinitModule("https://example.com/module.js", {as: "script"});return ...;
}

import { preinitModule } from 'react-dom';function CallToAction() {const onClick = () => {preinitModule("https://example.com/module.js", {as: "script"});startWizard();}return (<button onClick={onClick}>Start Wizard</button>);
}

二、源码分析

function preinitModule(href: string, options?: ?PreinitModuleOptions) {if (typeof href === 'string') {if (typeof options === 'object' && options !== null) {if (options.as == null || options.as === 'script') {const crossOrigin = getCrossOriginStringAs(options.as,options.crossOrigin,);ReactDOMSharedInternals.d /* ReactDOMCurrentDispatcher */.M(/* preinitModuleScript */ href, {crossOrigin,integrity:typeof options.integrity === 'string'? options.integrity: undefined,nonce:typeof options.nonce === 'string' ? options.nonce : undefined,});}} else if (options == null) {ReactDOMSharedInternals.d /* ReactDOMCurrentDispatcher */.M(/* preinitModuleScript */ href);}}
}

ReactDOMSharedInternals.d.M

preinitModuleScript 函数的核心功能是预初始化 ES6 模块脚本资源。它会检查指定 src 的模块脚本是否已存在于文档中,如果不存在则创建并插入一个新的 script 标签(设置为 type="module"),同时缓存该资源的相关信息。

function preinitModuleScript(src: string,options?: ?PreinitModuleScriptOptions,
) {previousDispatcher.M(/* preinitModuleScript */ src, options);// 获取document对象const ownerDocument = getGlobalDocument();if (ownerDocument && src) {// 获取资源const scripts = getResourcesFromRoot(ownerDocument).hoistableScripts;const key = getScriptKey(src);// Check if this resource already existslet resource = scripts.get(key);if (resource) {// We can early return. The resource exists and there is nothing// more to doreturn;}// Attempt to hydrate instance from DOMlet instance: null | Instance = ownerDocument.querySelector(getScriptSelectorFromKey(key),);if (!instance) {// Construct a new instance and insert itconst scriptProps = Object.assign(({src,async: true,//异步加载type: 'module',// 模块}: ScriptProps),options,);// Adopt certain preload propsconst preloadProps = preloadPropsMap.get(key);if (preloadProps) {// 如果存在预加载属性 preloadProps,则将其应用到脚本属性中(如 integrity、referrerPolicy、crossOrigin 等)。adoptPreloadPropsForScript(scriptProps, preloadProps);}instance = ownerDocument.createElement('script');// 标记可提升markNodeAsHoistable(instance);setInitialProperties(instance, 'link', scriptProps);(ownerDocument.head: any).appendChild(instance);}// Construct a Resource and cache itresource = {type: 'script',instance,count: 1,state: null,};scripts.set(key, resource);return;}
}

API之 preload

preload – React 中文文档

preload 函数的主要作用是对资源进行预加载操作。它会先对传入的参数进行有效性检查,确保参数类型符合要求,然后触发资源的预加载。

preload(href, options)

参数

  • href:字符串,要下载的资源的 URL。
  • options:对象,可以包含以下属性:
    • as:必需的字符串,表示资源的类型,可能的值 包括 audio、document、embed、fetch、font、image、object、script、style、track、video 与 worker。
    • crossOrigin:字符串,表示要使用的 CORS 策略,可能的值为 anonymous 与 use-credentials。当 as 设置为 "fetch" 时是必需的。
    • referrerPolicy:字符串,表示在获取时发送的 referer 请求头,可能的值为 no-referrer-when-downgrade(默认值)、no-referrer、origin、origin-when-cross-origin 与 unsafe-url。
    • integrity:字符串,为资源的加密哈希,用于 验证其真实性。
    • type:字符串,表示资源的 MIME 类型。
    • nonce:字符串,表示使用严格内容安全策略时允许资源的 加密随机数。
    • fetchPriority:字符串,为获取资源建议的相对优先级,可能的值为 auto(默认值)、high 与 low。
    • imageSrcSet:字符串,仅与 as: "image" 一起使用,用于指定 图像的源集。
    • imageSizes:字符串,仅与 as: "image" 一起使用,用于指定 图像的尺寸。

 一、使用示范

  1. 渲染时进行预加载
  2. 在事件处理程序中预加载

preload 可以预获取期望使用的资源,比如样式表、字体或外部脚本。

preload("https://example.com/font.woff2", {as: "font"});
    import { preload } from 'react-dom';function AppRoot() {preload("https://example.com/style.css", {as: "style"});preload("https://example.com/font.woff2", {as: "font"});return ...;
    }

    二、源码

    function preload(href: string, options: PreloadOptions) {if (typeof href === 'string' &&typeof options === 'object' &&options !== null &&typeof options.as === 'string') {// as:从 options 对象中提取 as 属性的值,该属性通常用于指定预加载资源的类型,如 'script'、'style' 等。const as = options.as;// 调用 getCrossOriginStringAs 函数,根据 as 和 options.crossOrigin 生成跨域相关的字符串。const crossOrigin = getCrossOriginStringAs(as, options.crossOrigin);ReactDOMSharedInternals.d /* ReactDOMCurrentDispatcher */.L(/* preload */ href, as, {crossOrigin,integrity:typeof options.integrity === 'string' ? options.integrity : undefined,nonce: typeof options.nonce === 'string' ? options.nonce : undefined,type: typeof options.type === 'string' ? options.type : undefined,fetchPriority:typeof options.fetchPriority === 'string'? options.fetchPriority: undefined,referrerPolicy:typeof options.referrerPolicy === 'string'? options.referrerPolicy: undefined,imageSrcSet:typeof options.imageSrcSet === 'string'? options.imageSrcSet: undefined,imageSizes:typeof options.imageSizes === 'string'? options.imageSizes: undefined,media: typeof options.media === 'string' ? options.media : undefined,});}
    }
    

    ReactDOMSharedInternals.d.L

    preload 函数主要用于预加载资源,通过创建 rel="preload"link 元素来实现。它会根据资源的类型(as)和相关选项(options)生成合适的选择器和属性,检查资源是否已存在于文档中,若不存在则插入新的 link 元素进行预加载,同时处理 Safari 中关于图片 imageSrcSet 的特殊情况。

    function preload(href: string, as: string, options?: ?PreloadImplOptions) {previousDispatcher.L(/* preload */ href, as, options);// 获取document对象const ownerDocument = getGlobalDocument();if (ownerDocument && href && as) {// 预加载选择器let preloadSelector = `link[rel="preload"][as="${escapeSelectorAttributeValueInsideDoubleQuotes(as,)}"]`;// 当资源类型为image时,处理if (as === 'image') {if (options && options.imageSrcSet) {preloadSelector += `[imagesrcset="${escapeSelectorAttributeValueInsideDoubleQuotes(options.imageSrcSet,)}"]`;if (typeof options.imageSizes === 'string') {preloadSelector += `[imagesizes="${escapeSelectorAttributeValueInsideDoubleQuotes(options.imageSizes,)}"]`;}} else {preloadSelector += `[href="${escapeSelectorAttributeValueInsideDoubleQuotes(href,)}"]`;}} else {// 对于非图片类型的资源,直接向选择器中添加 href 属性值。preloadSelector += `[href="${escapeSelectorAttributeValueInsideDoubleQuotes(href,)}"]`;}let key = preloadSelector;switch (as) {case 'style':// 当资源类型为 style 时,将 key 更新为 getStyleKey(href) 的返回值key = getStyleKey(href);break;case 'script':// 当资源类型为 script 时,将 key 更新为 getScriptKey(href) 的返回值key = getScriptKey(href);break;}if (!preloadPropsMap.has(key)) {// 创建预加载属性const preloadProps = Object.assign(({rel: 'preload',href:as === 'image' && options && options.imageSrcSet ? undefined : href,as,}: PreloadProps),options,);preloadPropsMap.set(key, preloadProps);if (null === ownerDocument.querySelector(preloadSelector)) {if (as === 'style' &&ownerDocument.querySelector(getStylesheetSelectorFromKey(key))) {// 若资源类型为 style 且已存在对应样式表(通过 getStylesheetSelectorFromKey(key) 检查),则返回,不进行预加载。// We already have a stylesheet for this key. We don't need to preload it.return;} else if (as === 'script' &&ownerDocument.querySelector(getScriptSelectorFromKey(key))) {// 若资源类型为 script 且已存在对应脚本(通过 getScriptSelectorFromKey(key) 检查),则返回,不进行预加载。// We already have a stylesheet for this key. We don't need to preload it.return;}// 创建link元素const instance = ownerDocument.createElement('link');// 设置初始属性setInitialProperties(instance, 'link', preloadProps);// 标记可提升markNodeAsHoistable(instance);// 往head标签中插入子节点(ownerDocument.head: any).appendChild(instance);}}}
    }

    API之 preloadModule

    preloadModule – React 中文文档

    preloadModule 可以急切地预获取期望使用的 ESM 模块。

    preloadModule("https://example.com/module.js", {as: "script"});

    参考语法

    preloadModule(href, options)

    参数

    • href:字符串,要下载的资源的 URL。
    • options:对象,可以包含以下属性:
      • as:必需的字符串,表示资源的类型,可能的值 包括 audio、document、embed、fetch、font、image、object、script、style、track、video 与 worker。
      • crossOrigin:字符串,表示要使用的 CORS 策略,可能的值为 anonymous 与 use-credentials。当 as 设置为 "fetch" 时是必需的。
      • integrity:字符串,为资源的加密哈希,用于 验证其真实性。
      • nonce:字符串,表示使用严格内容安全策略时允许资源的 加密随机数。

    一、使用示范

    import { preloadModule } from 'react-dom';function CallToAction() {const onClick = () => {preloadModule("https://example.com/module.js", {as: "script"});startWizard();}return (<button onClick={onClick}>Start Wizard</button>);
    }

    二、源码

    function preloadModule(href: string, options?: ?PreloadModuleOptions) {if (typeof href === 'string') {if (options) {const crossOrigin = getCrossOriginStringAs(options.as,options.crossOrigin,);ReactDOMSharedInternals.d /* ReactDOMCurrentDispatcher */.m(/* preloadModule */ href, {as:typeof options.as === 'string' && options.as !== 'script'? options.as: undefined,crossOrigin,integrity:typeof options.integrity === 'string'? options.integrity: undefined,});} else {ReactDOMSharedInternals.d /* ReactDOMCurrentDispatcher */.m(/* preloadModule */ href);}}}
    

    ReactDOMSharedInternals.d.m

    preloadModule 函数用于预加载 ES6 模块资源,通过创建 rel="modulepreload"link 元素来实现。它会根据资源类型(as)和相关选项生成合适的选择器和属性,检查资源是否已存在于文档中,若不存在则插入新的 link 元素进行预加载。

    function preloadModule(href: string, options?: ?PreloadModuleImplOptions) {previousDispatcher.m(/* preloadModule */ href, options);// 获取document对象const ownerDocument = getGlobalDocument();if (ownerDocument && href) {const as =options && typeof options.as === 'string' ? options.as : 'script';// 生成预加载选择器 preloadSelector,包含 rel="modulepreload"、资源类型 as 和资源链接 href。const preloadSelector = `link[rel="modulepreload"][as="${escapeSelectorAttributeValueInsideDoubleQuotes(as,)}"][href="${escapeSelectorAttributeValueInsideDoubleQuotes(href)}"]`;let key = preloadSelector;switch (as) {case 'audioworklet':case 'paintworklet':case 'serviceworker':case 'sharedworker':case 'worker':case 'script': {key = getScriptKey(href);break;}}if (!preloadPropsMap.has(key)) {const props: PreloadModuleProps = Object.assign(({rel: 'modulepreload',href,}: PreloadModuleProps),options,);preloadPropsMap.set(key, props);if (null === ownerDocument.querySelector(preloadSelector)) {switch (as) {case 'audioworklet':case 'paintworklet':case 'serviceworker':case 'sharedworker':case 'worker':case 'script': {if (ownerDocument.querySelector(getScriptSelectorFromKey(key))) {return;}}}const instance = ownerDocument.createElement('link');setInitialProperties(instance, 'link', props);markNodeAsHoistable(instance);(ownerDocument.head: any).appendChild(instance);}}}
    }

    工具函数之 getCrossOriginStringAs

    返回值只有三种情况:use-credentials、空字符串、undefined。

    function getCrossOriginStringAs(as: ?string,// 资源类型input: ?string,// crossorigin属性值
    ): ?CrossOriginString {// 字体类型返回空字符串if (as === 'font') {return '';}if (typeof input === 'string') {// 如果crossorigin值为use-credentials,否则返回空字符串return input === 'use-credentials' ? input : '';}return undefined;
    }

    工具函数之 getCrossOriginString

    返回值只有三种情况:use-credentials、空字符串、undefined。

    function getCrossOriginString(input: ?string): ?CrossOriginString {if (typeof input === 'string') {return input === 'use-credentials' ? input : '';}return undefined;
    }

    工具函数之 getGlobalDocument

    获取document对象。

    const globalDocument = typeof document === 'undefined' ? null : document;function getGlobalDocument(): ?Document {return globalDocument;
    }

    工具函数之 getResourcesFromRoot 

    获取资源,当资源不存在时进行初始化操作后返回。

    function getResourcesFromRoot(root: HoistableRoot): RootResources {// 获取资源let resources = (root: any)[internalRootNodeResourcesKey];if (!resources) {// 设置资源resources = (root: any)[internalRootNodeResourcesKey] = {hoistableStyles: new Map(),hoistableScripts: new Map(),};}return resources;
    }const internalRootNodeResourcesKey = '__reactResources$' + randomKey;
    export type HoistableRoot = Document | ShadowRoot;
    export type HoistableRoot = Document | ShadowRoot;
    export type RootResources = {hoistableStyles: Map<string, StyleResource>,hoistableScripts: Map<string, ScriptResource>,
    };

    工具函数之 markNodeAsHoistable 

    设置节点为可提升。

    function markNodeAsHoistable(node: Node) {(node: any)[internalHoistableMarker] = true;
    }const internalHoistableMarker = '__reactMarker$' + randomKey;

    工具函数之 getStyleKey

    function getStyleKey(href: string) {const limitedEscapedHref =escapeSelectorAttributeValueInsideDoubleQuotes(href);return `href="${limitedEscapedHref}"`;
    }

    工具函数之 getScriptKey

    function getScriptKey(src: string): string {const limitedEscapedSrc = escapeSelectorAttributeValueInsideDoubleQuotes(src);return `[src="${limitedEscapedSrc}"]`;
    }

    工具函数之 escapeSelectorAttributeValueInsideDoubleQuotes

    // 正则表达式用于匹配字符串中的换行符(\n)、双引号(")和反斜杠(\\)。g 标志表示全局匹配
    const escapeSelectorAttributeValueInsideDoubleQuotesRegex = /[\n\"\\]/g;function escapeSelectorAttributeValueInsideDoubleQuotes(value,
    ) {return value.replace(escapeSelectorAttributeValueInsideDoubleQuotesRegex,ch => '\\' + ch.charCodeAt(0).toString(16) + ' ',);
    }

    const input = 'This is a string with "quotes" and \n newlines and \\ backslashes.';
    const escaped = escapeSelectorAttributeValueInsideDoubleQuotes(input);
    console.log(escaped);
    // This is a string with \22 quotes\22  and \a  newlines and \5c  backslashes.

    工具函数之 getStylesheetSelectorFromKey 

    function getStylesheetSelectorFromKey(key: string) {return `link[rel="stylesheet"][${key}]`;
    }
    

    工具函数之 insertStylesheet

    insertStylesheet 函数的主要作用是将样式元素(linkstyle)按照特定的优先级规则插入到文档中。它会根据元素的 data-precedence 属性值来确定插入位置,确保相同优先级的样式元素相邻排列,并且按照优先级从高到低的顺序排列在文档中。

    function insertStylesheet(instance: Element,precedence: string,// 优先级root: HoistableRoot,
    ): void {// 使用 querySelectorAll 查找根节点 root 下所有带有 data-precedence 属性的样式元素(包括 link 和 style)。const nodes = root.querySelectorAll('link[rel="stylesheet"][data-precedence],style[data-precedence]',);// 最后一个const last = nodes.length ? nodes[nodes.length - 1] : null;let prior = last;for (let i = 0; i < nodes.length; i++) {const node = nodes[i];// 获取优先级const nodePrecedence = node.dataset.precedence;// 如果当前元素的 data-precedence 与目标优先级 precedence 相同,则更新 prior 为该元素。if (nodePrecedence === precedence) {prior = node;} else if (prior !== last) {// 退出循环break;}}if (prior) {// 新元素插入到 prior 的下一个兄弟节点之前((prior.parentNode: any): Node).insertBefore(instance, prior.nextSibling);} else {const parent =root.nodeType === DOCUMENT_NODE// 将元素插入到文档的 head 中作为第一个子元素? ((((root: any): Document).head: any): Element)// 插入到 Shadow DOM 的根节点中作为第一个子元素: ((root: any): ShadowRoot);parent.insertBefore(instance, parent.firstChild);}
    }

    相关文章:

  1. Spring Boot配置文件
  2. Spring Boot 项目中什么时候会抛出 FeignException?
  3. dockerdesktop 重新安装
  4. Spring Boot中HTTP连接池的配置与优化实践
  5. 解决 MinIO 对象存储“AccessDenied”问题及 Docker 操作全解析
  6. Kotlin 中的作用域函数
  7. 配置Hadoop集群-上传文件
  8. 基于Java和PostGIS的AOI面数据球面面积计算实践
  9. 【SpringBoot】从零开始全面解析Spring MVC (一)
  10. Ascend的aclgraph(六)AclConcreteGraph
  11. [经验总结]删除gitlab仓库分支报错:错误:无法推送一些引用到“http:”
  12. c语言第一个小游戏:贪吃蛇小游戏06
  13. Visual Studio 项目 .gitignore 文件指南
  14. 在 Qt Creator 中为 QDockWidget 设置隐藏和显示按钮
  15. 通过anaconda安装jupyter
  16. 【Redis 进阶】缓存
  17. Mac显卡的工作原理及特殊之处
  18. 【 Redis | 实战篇 秒杀实现 】
  19. 移动端(手机)ECharts 的myChart.on(‘click‘,还生效吗我怎么触发不了,没得鼠标触发不了点击事件
  20. Qt事件循环机制
  21. 持续8年仍难终了的纠纷:败诉方因拒执罪被立案,胜诉方银行账户遭冻结
  22. 英国收紧移民政策,技术工作签证、大学招生面临更严要求
  23. 比特币挖矿公司GRYP股价涨超171%:将与特朗普儿子创设的公司合并
  24. 上海国际电影节特设“今日亚洲”单元
  25. 《单身情歌》制作人韩贤光去世,林志炫发文悼念
  26. 礼来公布头对头研究详细结果:替尔泊肽在所有减重目标中均优于司美格鲁肽