Edge Side включает в себя самозакрывающийся тег - PullRequest
0 голосов
/ 14 декабря 2018

У меня есть приложение nextjs (v7) , в которое мы пытаемся добавить некоторые теги Edge Side Include, к которым были предоставлены:

<esi:include src="https://example.com/head" />
<esi:include src="https://example.com/menu" />
<esi:include src="https://example.com/footer" />

Мы добавили их в наш custom _document.js (который используется всеми скомпилированными страницами nextjs / реагировать) примерно так:

  import Document, { Head } from 'next/document'
  import React from 'react'
  export default class MyDocument extends Document {
    render () {
      const { html } = this.props
      return (
        <html>
          <Head>
            React.createElement('esi:include', { src: 'https://example.com/head }, null)}
          </Head>
          <body>
            React.createElement('esi:include', { src: 'https://example.com/menu }, null)}
            <div id='__next' dangerouslySetInnerHTML={{ __html: html }} />
            React.createElement('esi:include', { src: 'https://example.com/footer }, null)}
          </body>
        </html>
      )
    }
  }

Проблема в том, что при компиляции / переносе добавляются закрывающие теги кesi: включайте элементы и не оставляйте их как самозакрывающийся тег-элемент в стиле void:

<html>
  <head>
    ... metas, titles
    <esi:include src="https://example.com/head" class="next-head"></esi:include>
  </head>
  <body>   
    ... stylesheets and preload links
    <div>
      <esi:include src="https://example.com/menu"></esi:include>
    </div>
    <div id="__next">
      ... main app container
      <esi:include src="https://example.com/footer"></esi:include>
    </div>
  </body>
</html>

Я подумал, что это, вероятно, будет хорошо, и Edge-сервер, как мы надеемся, должен распознавать его точно так же, но не какEdge Server должен иметь его с самозакрывающимся тегом (в соответствии с разделом 3.1 здесь, в specs ), чтобы найти его и выполнить внедрение кода.

Мы пытались использовать некоторые опасноSetInnerHTML-решения.но происходит то же самое, закрывающий тег добавляется вместо того, чтобы оставить самозакрывающийся тег как есть.Таким образом, я подозреваю, что это не связано с тем, как мы делаем это в коде JSX, а происходит где-то в веб-пакете, компиляция / перенос бабел, чтобы сделать его действительным html5, но я не уверен, как обойти это.Похоже, что спецификации ESI, для которых требуется, чтобы тег include был самозакрывающимся, и HTML5 specs , которые допускают использование пустого (самозакрывающегося) элемента только небольшого указанного набора, несовместимы.

Есть какие-нибудь идеи относительно того, как я могу настроить Webpack или Babel, чтобы сохранить самозакрывающиеся теги?Заранее благодарим за любую помощь!

----- ЧАСТИЧНАЯ РАБОТА ПО ОБНОВЛЕНИЮ -----

Нам удалось частично обойти эту проблему, добавив 3 статических html-файла.в назначенную статическую папку для экспресс-сервера, который обслуживает приложение nextjs / реагировать.Затем 3 файла (head.html, menu.html и foot.html) внедряются с помощью некоторого клиентского javascript, добавляемого в пользовательский _document.js, например так:

  import Document, { Head } from 'next/document'
  import React from 'react'
  export default class MyDocument extends Document {
    render () {
      const { html } = this.props
      return (
        <html>
          <Head>
          </Head>
          <body>
            <div id='__next' dangerouslySetInnerHTML={{ __html: html }} />
            <script>
            var esiHeadReq = new XMLHttpRequest();
            esiHeadReq.open('GET', '/static/esi-head.html', true);
            esiHeadReq.send(null);
            esiHeadReq.onreadystatechange = function () {
               if (esiHeadReq.readyState === 4) {
                  document.head.insertAdjacentHTML('beforeend', esiHeadReq.responseText);
               }
            }

            var esiMenuReq = new XMLHttpRequest();
            esiMenuReq.open('GET', '/static/esi-menu.html', true);
            esiMenuReq.send(null);
            esiMenuReq.onreadystatechange = function () {
               if (esiMenuReq.readyState === 4) {
                  document.body.insertAdjacentHTML('afterbegin', esiMenuReq.responseText);
               }
            }

            var esiFootReq = new XMLHttpRequest();
            esiFootReq.open('GET', '/static/esi-foot.html', true);
            esiFootReq.send(null);
            esiFootReq.onreadystatechange = function () {
               if (esiFootReq.readyState === 4) {
                  document.body.insertAdjacentHTML('beforeend', esiFootReq.responseText);
               }
            }
            </script>
          </body>
        </html>
      )
    }
  }

Это работает в этом EdgeСервер теперь корректно внедряет код заголовка / меню / нижнего колонтитула в html-файлы (не переносимые через веб-пакеты или вавилонскую оболочку), но когда мы добавили скрипт для вставки кода в основной DOM, используемый страницами реакции, он не связывает некоторые варианты поведенияправильно в каком-то вставленном javascript и поэтому меню на самом деле не работает.Вероятно, это связано с добавлением его в DOM с использованием insertAdjacentHTML после того, как все остальные рендеринг и привязка JS выполнены.Так что все еще не решение ...

...