Использование внешних библиотек JS в веб-компоненте - PullRequest
0 голосов
/ 05 июня 2018

Я занимаюсь разработкой веб-компонента с использованием Polymer 2 и хотел бы использовать стороннюю библиотеку JavaScript, которая не была специально разработана для использования с веб-компонентами.Насколько я знаю, единственный способ сделать это - включить тег <script>, ссылающийся на библиотеку, в файл HTML моего веб-компонента.

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

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

  2. Внешняя библиотека может выполнять запросы или обновления DOM, которыене сможет получить доступ к shadow-dom веб-компонента, который их использует, поэтому внешняя библиотека может вообще не работать или может снова обновить DOM страницы хоста, нарушая инкапсуляцию.

Итак, я что-то упустил или это означает, что включение внешних библиотек в веб-компонент - действительно плохая идея?Если это так, то это кажется огромным ограничением этой технологии, поскольку мы не можем воспользоваться огромным количеством уже существующих библиотек JS.

Ответы [ 2 ]

0 голосов
/ 08 июня 2018

Если у вас есть внешняя библиотека, которая выполняет такие функции, как document.querySelector, тогда у вас есть два варианта:

  1. Выберите, чтобы не использовать ShadowDOM ни с одним из ваших компонентов.Если это не вариант, или вы действительно ДЕЙСТВИТЕЛЬНО хотите использовать shadowDOM, тогда:
  2. Вам нужно изменить стороннюю библиотеку, чтобы разрешить указывать корневой элемент вместо того, чтобы всегда использовать document.

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

Полагаю, другой вариант - переоценитьстороннюю библиотеку и посмотрите, стоит ли ДЕЙСТВИТЕЛЬНО использовать.

В моей команде мы не используем сторонние библиотеки, которые представляют собой не просто основную логику.Такие вещи, как moment.js - это просто логика, и мы можем использовать их без проблем.

Но что-то вроде jQuery?Тьфу!Я не вижу необходимости чего-то подобного для компонента.

Удачи!

0 голосов
/ 07 июня 2018

Мне на самом деле пришлось столкнуться с той же самой проблемой вчера, поэтому хорошее время;) В моем случае представление на первой странице состоит из двух разделов, один из которых содержит переключатели и из-за требований бизнеса, зависящих от выбора переключателя пользователя, ввод текстас картами Google автозаполнение будет включено (или останется отключенным)

В этом сценарии было гораздо более эффективно загружать страницу без библиотек карт Google, а затем динамически загружать код gmaps после полной визуализации веб-компонента, что приводитдо 50% времени, затрачиваемого на интерактив :) Вот что я в итоге сделал.

ПРИМЕЧАНИЕ. Метод loadGoogleMaps () и объявление переменной initCalled находятся вне класса и, следовательно, за пределами веб-компонента (я поставилих под заявлениями на импорт).Я также пропустил большую часть кода класса из примера, так как он не относился к вашему вопросу:)

import { html } from '@polymer/lit-element';
import { PageViewElement } from './page-view-element.js';
import { SharedStyles } from './shared-styles.js';
import '@vaadin/vaadin-radio-button/vaadin-radio-button.js';
import '@vaadin/vaadin-radio-button/vaadin-radio-group.js';
import { spinner } from './my-icons.js';

let initCalled;

function loadGoogleMaps() {
  //Only load gmaps if it has not been loaded before (tracked by the initCalled flag)
  if (!initCalled) {
    //Dynamically import the library and append it to the document header
    const script = document.createElement('script');
    script.type = 'text/javascript';
    script.async = true;
    script.onload = function () {
      //Code to execute after the library has been downloaded parsed and processed by the browser starts here :)
      initCalled = true;

      //TODO: Refactor this DOM traversing logic
      const searchAutocomplete = document.querySelector('my-app').shadowRoot.querySelector("home-property-view")
        .shadowRoot.querySelector('home-property').shadowRoot.querySelector("input[type='text']");

      const autocomplete = new google.maps.places.Autocomplete(
        searchAutocomplete, {
          types: ['address'],
          componentRestrictions: {  //Limit to only US addresses
            'country': 'us'
          }
        });

      autocomplete.addListener('place_changed', function () {
        const place = autocomplete.getPlace();
        dispatchEvent(new CustomEvent('propertyAddressChanged', {
          bubbles: true,
          composed: true,
          detail: place
        }));
      });
    };
    //Specify the location of the gmaps library
    script.src = '//maps.googleapis.com/maps/api/js?v=3.33&key=<YOUR-API-KEY-GOES-HERE>&libraries=places';

    //Append it to the document header
    document.head.appendChild(script);
  }
}

class HomeProperty extends PageViewElement {
  //....omitted class code for brevity...

  _didRender(props, changedProps, prevProps) {
    loadGoogleMaps();
  }

  //....omitted class code for brevity...
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...