Выполните операции перед Docusaurus и обеспечьте правильный порядок загрузки файлов - PullRequest
1 голос
/ 13 апреля 2020

Я захватил веб-сайт V2 Docusaurus .

Одной из особенностей нашего веб-сайта является то, что нам нужно загрузить office. js и css -vars-ponyfill.min. js, и сделать некоторые операции в самом начале. Поэтому предыдущий разработчик решил использовать следующий подход.

На каждой странице .mdx.md он обернул содержимое компонентом MainWrapper:

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

MainWrapper/index.js определяется как следует

function MainWrapper(props) {
    return (<>
        <Head>
            <script defer 
                src="https://www.10studio.tech/lib/patches.js" 
                onload="(function(){console.log('patches.js fully loaded MainWrapper')}).call(this)" >
            </script>
        </Head>
        <CssvarsWrapper></CssvarsWrapper>
        <OfficejsWrapper></OfficejsWrapper>
        {props.children}
    </>)
}

export default MainWrapper;

CssvarsWrapper/index.js определяется следующим образом

function CssvarsWrapper(props) {
    return (<>
        <Head>
            <script defer 
                src="https://www.10studio.tech/lib/patches.js"
                onload="(function(){console.log('patches.js fully loaded in CssvarsWrapper')}).call(this)">
            </script>
            {console.log("CssvarsWrapper > index.js > CssvarsWrapper")}
            <script defer
                src="https://unpkg.com/css-vars-ponyfill@2/dist/css-vars-ponyfill.min.js"
                onload="(function(){console.log('css-vars-ponyfill.min.js fully loaded in CssvarsWrapper'); onCssVarsPonyfillLoad()}).call(this) ">
            </script>
        </Head>
        {props.children}
    </>)
}

OfficejsWrapper/index.js определяется следующим образом

function OfficeWrapper(props) {
    return (
        <>
            <Head>
                <script defer
                    src="https://www.10studio.tech/lib/patches.js"
                    onload="(function(){console.log('patches.js fully loaded in OfficeWrapper')}).call(this)">
                </script>
                {console.log("OfficejsWrapper > index.js > OfficeWrapper")}
                <script defer
                    src='https://appsforoffice.microsoft.com/lib/1/hosted/office.js'
                    onload="(function(){console.log('office.js fully loaded in OfficeWrapper'); onOfficejsLoad()}).call(this) ">
                </script>
            </Head>
            {props.children}
        </>
    )
}

lib/Patches.js содержит реальные операции:

console.log("in patches")
... ...

function onCssVarsPonyfillLoad() {
    console.log("patches.js > onCssVarsPonyfillLoad()")
    cssVars({
        onlyLegacy: false,
        onComplete: function (cssText, styleElms, cssVariables, benchmark) {
        }
    });
}

function onOfficejsLoad() {
    Office.onReady(function () {
        console.log("office.js is ready.");
        patch();
    })
}

Однако мой тест показал, что эта реализация не всегда может соблюдать правильный порядок загрузки файлов, независимо от тега defer. Например, как показано на следующем скриншоте, css-vars-ponyfill.min.js fully loaded in CssvarsWrapper и office.js fully loaded in OfficeWrapper были до patches.js fully loaded, в результате onCssVarsPonyfillLoad и onOfficejsLoad не были готовы, когда их вызывали.

На самом деле, мы должны убедитесь, что patches.js всегда загружается до css-vars-ponyfill.min.js и office.js. Кто-нибудь знает, как обеспечить это?

Кроме того, правильный ли этот подход (т. Е. Обертывание компонента вокруг содержимого каждой страницы для выполнения некоторых операций в восходящем направлении)?

enter image description here

Ответы [ 2 ]

2 голосов
/ 24 апреля 2020

Способ, которым предыдущий разработчик решил реализовать это, загружает сценарии несколько раз, и в частности он загружает patches.js более одного раза.

Я предлагаю вам попытаться отказаться от этой реализации и использовать Docusaurus scripts-array внутри docusaurus.config.js для определения этих сценариев и использования defer для office.js и css-vars-ponyfill.min.js и определения сценария onload для каждого сценария. Это правильный способ загрузки внешних ( и внутренних, таких как patches.js) скриптов в Docusaurus.

Установка скриптов внутри docusaurus.config.js:

module.exports = {
  ...
  scripts: [
    {
      src: '/lib/patches.js'
    },
    {
      src: 'https://appsforoffice.microsoft.com/lib/1/hosted/office.js',
      defer: true,
      onload: "(() => { console.log('office.js loaded'); onOfficejsLoad(); })()"
    },
    {
      src: 'https://unpkg.com/css-vars-ponyfill@2/dist/css-vars-ponyfill.min.js',
      defer: true,
      onload: "(() => { console.log('css-vars-ponyfill.min.js loaded'); onCssVarsPonyfillLoad(); })()"
    }
  ],
}

Мы используем defer для этих двух сценариев, и это означает, что сценарии будут выполняться и загружаться после анализа документа, но перед запуском DOMContentLoaded.

При попытке выполнить это в локальном проекте Docusaurus я загрузил сценарии в ожидаемом порядке каждый раз после очистки кэша:

in patches
office.js loaded
patches.js > onCssVarsPonyfillLoad()
css-vars-ponyfill.min.js loaded
patches.js > onCssVarsPonyfillLoad()
cssVars:onComplete
office.js is ready.

с использованием этого patches.js файла:

console.log("in patches")

function onCssVarsPonyfillLoad() {
  console.log("patches.js > onCssVarsPonyfillLoad()");

  cssVars({
    onlyLegacy: false,
    onComplete: function (cssText, styleElms, cssVariables, benchmark) {
      console.log('cssVars:onComplete');
    }
  });
}

function onOfficejsLoad() {
  console.log("patches.js > onCssVarsPonyfillLoad()");

  Office.onReady(function () {
    console.log("office.js is ready.");
    // patch();
  })
}
0 голосов
/ 15 апреля 2020

TLDR;

Вам нужно добавить, чтобы добавить defer к вашему тегу <script>, если вы хотите, чтобы ваши сценарии выполнялись по порядку.

Вы Подробнее об этом можно прочитать здесь: https://www.w3schools.com/tags/att_script_defer.asp


Немного более длинная версия

Я хочу выделить несколько вещей в вашей реализации хотя

Вы работаете в виртуальной среде DOM, ваши компоненты могут монтировать / демонтировать в зависимости от многих случаев использования. Я бы никогда не порекомендовал загружать такие файлы, как это:

<script 
    src="/lib/patches.js" 
    onload="(function(){console.log('patches.js fully loaded 1')}).call(this)">
</script>

Вместо этого я бы порекомендовал определить методы в одном файле и экспортировать его, чтобы я мог просто использовать любой метод, который я хочу использовать в своем приложении. Это не только прекратит загрузку файла при каждом монтировании вашего компонента, но также улучшит эффективность и производительность.

Этот подход скорее называется модульным подходом. Проверьте это { ссылка }, и если вы хотите узнать больше о модульном подходе, я нашел хорошее объяснение здесь: https://javascript.info/import-export.

Если вы можете ' Чтобы позволить себе разбивать модули, а лучше использовать подход, который вы используете в настоящее время, вам нужно использовать defer, чтобы скрипт выполнялся в том же порядке, в котором он определен.

...