保证文件的异步加载和函数的执行

Ensure asynchronous loading of files and execution of functions

我要接手 a website by V2 Docusaurus

我们网站的一个特殊性是我们需要在一开始就加载 office.js and css-vars-ponyfill.min.js, and run some functions in patches.js。所以之前的开发者决定使用下面的方法。

在每个.mdx.md页面中,他用一个组件包裹内容MainWrapper:

<MainWrapper>
    ... ...
    Real content
    ... ...
</MainWrapper>

MainWrapper/index.js定义如下

import React from 'react';
import Head from '@docusaurus/Head';

function MainWrapper(props) {
    return (<>
        <Head>
            <script
                src="/lib/patches.js" 
                onload="(function(){console.log('patches.js has been fully loaded')}).call(this)" >
            </script>
            <script async defer 
                src='https://unpkg.com/css-vars-ponyfill@2/dist/css-vars-ponyfill.min.js'
                onload="(function(){console.log('css-vars-ponyfill.min.js has been fully loaded'); onCssVarsPonyfillLoad();}).call(this)">
            </script>
            <script async defer 
                src='https://appsforoffice.microsoft.com/lib/1/hosted/office.js'
                onload="(function(){console.log('office.js has been fully loaded'); onOfficejsLoad();}).call(this)">
            </script>
        </Head>
        {props.children}
    </>)
}

export default MainWrapper;

lib/Patches.js包含实际操作:

var pushStateRef = history.pushState;
var replaceStateRef = history.replaceState;

console.log("already inside patches.js")
console.log("history.pushSate and replaceState have been saved")

function patch() {
    if (!history.pushState) {
        history.pushState = pushStateRef;
        history.replaceState = replaceStateRef;
        console.log("history.pushState and replaceState have been set back")
    };
}

... ...

function onCssVarsPonyfillLoad() {
    console.log("already inside patches.js > onCssVarsPonyfillLoad()")
    ... ...
}

function onOfficejsLoad() {
    Office.onReady(function () {
        console.log("already inside Office.onReady");
        patch();
    })
}

我的测试表明,有时,此实现可以确保在 office.jscss-vars-ponyfill.min.js 之前加载 patches.js,就像 <script async defer 那样。但是,有时无法确保此顺序:

@docusarus/Head 使用 react-helmet。有谁知道如何解决这个加载顺序问题?我想要的是先加载 patches.js,有什么解决方法吗?

一种解决方法是将 patches.js 的全部代码放在 <script>... ...</script> 中其他文件之前,如下所示:

import React from 'react';
import Head from '@docusaurus/Head';
import CssvarsWrapper from '../CssvarsWrapper';
import OfficejsWrapper from '../OfficejsWrapper';

class MainWrapper extends React.Component {        
    render() {
        return (
            <>
                <Head>
                    <script>{`
                        console.log("begin patches")
                        ... ... // the body of patches.js
                    `}</script>
                    <script async defer 
                        src='https://unpkg.com/css-vars-ponyfill@2/dist/css-vars-ponyfill.min.js'
                        onload="(function(){console.log('css-vars-ponyfill.min.js has been fully loaded'); onCssVarsPonyfillLoad();}).call(this)">
                    </script>
                    <script async defer 
                        src='https://appsforoffice.microsoft.com/lib/1/hosted/office.js'
                        onload="(function(){console.log('office.js has been fully loaded'); onOfficejsLoad();}).call(this)">
                    </script>
                </Head>
                {this.props.children}
            </>
        )  
    }
}

export default MainWrapper;