Beispiele für ein React- und JavaScript-Codebeispiel

Für das Looker-Erweiterungs-Framework wird demnächst ein neuer Lademechanismus verwendet. Der neue Ladeprogramm kann Fehler verursachen, wenn vorhandene Erweiterungen geladen werden. Wie Sie Ihre Erweiterungen mit dem neuen Ladeprogramm testen können, bevor sie in Looker-Umgebungen offiziell aktiviert werden, erfahren Sie im Artikel Testen des neuen Frameworks-Ladeprogramms für Erweiterungen in der Looker-Hilfe.

Diese Seite enthält Codebeispiele, die in React und JavaScript für gängige Funktionen geschrieben wurden, die Sie in Ihren Erweiterungen verwenden können.

Looker Extension SDK verwenden

Wenn Sie Funktionen aus dem Looker Extension SDK hinzufügen möchten, müssen Sie zuerst einen Verweis auf das SDK anfordern. Das kann entweder vom Anbieter oder global erfolgen. Anschließend können Sie SDK-Funktionen wie in jeder JavaScript-Anwendung aufrufen.

  • So greifen Sie über den Anbieter auf das SDK zu:
  import { ExtensionContext2 } from '@looker/extension-sdk-react'

  export const Comp1 = () => {
    const extensionContext = useContext(
      ExtensionContext2
    )
    const { extensionSDK, coreSDK } = extensionContext
  • So greifen Sie global auf das SDK zu (die Erweiterung muss vor dem Aufruf initialisiert werden):
    const coreSDK = getCoreSDK2()

Sie können das SDK jetzt wie in jeder JavaScript-Anwendung verwenden:

  const GetLooks = async () => {
    try {
      const looks = await sdk.ok(sdk.all_looks('id'))
      // process looks
      . . .
    } catch (error) {
      // do error handling
      . . .
    }
}

Weil die Erweiterung in einem Sandbox-iFrame ausgeführt wird, können Sie an keiner anderen Stelle in der Looker-Instanz navigieren, indem Sie das window.location-Objekt des übergeordneten Elements aktualisieren. Die Navigation ist mit dem Looker Extension SDK möglich.

Für diese Funktion ist die Berechtigung navigation erforderlich.

import { ExtensionContext2 } from '@looker/extension-sdk-react'

. . .

  const extensionContext = useContext(
    ExtensionContext2
  )
  const { extensionSDK } = extensionContext

. . .

  extensionSDK.updateLocation('/browse')

Neues Browserfenster öffnen

Da die Erweiterung in einem iFrame ausgeführt wird, der in einer Sandbox ausgeführt wird, können Sie mit dem übergeordneten Fenster kein neues Browserfenster öffnen. Mit dem Looker Extension SDK können Sie ein Browserfenster öffnen.

Für diese Funktion ist entweder die Berechtigung new_window erforderlich, um ein neues Fenster zu einem Speicherort in der aktuellen Looker-Instanz zu öffnen, oder die Berechtigung new_window_external_urls, um ein neues Fenster zu öffnen, das auf einem anderen Host ausgeführt wird.

import { ExtensionContext2 } from '@looker/extension-sdk-react'

. . .

  const extensionContext = useContext(
    ExtensionContext2
  )
  const { extensionSDK } = extensionContext

. . .
  extensionSDK.openBrowserWindow('/browse', '_blank')
. . .
  extensionSDK.openBrowserWindow('https://docs.looker.com/reference/manifest-params/application#entitlements', '_blank')

Routing und Deeplinks

Folgendes gilt für reaktionsbasierte Erweiterungen:

Die Komponenten ExtensionProvider und ExtensionProvider2 erstellen automatisch einen React-Router namens MemoryRouter, den Sie verwenden können. Versuchen Sie nicht, ein BrowserRouter zu erstellen, da es nicht in iFrames funktioniert, die in einer Sandbox ausgeführt werden. Versuchen Sie nicht, ein HashRouter zu erstellen, da es in Sandbox-iFrames für die nicht Chromium-basierte Version des Microsoft Edge-Browsers nicht funktioniert.

Wenn die MemoryRouter verwendet wird und Sie react-router in der Erweiterung verwenden, synchronisiert das Framework der Erweiterung automatisch den Router Ihrer Erweiterung mit dem Looker-Host-Router. Das bedeutet, dass die Erweiterung bei Klicks auf die Schaltfläche „Zurück“ und „Vorwärts“ im Browser und bei der Aktualisierung der Seite benachrichtigt wird. Das bedeutet auch, dass die Erweiterung Deeplinks automatisch unterstützen soll. Beispiele für die Verwendung von react-router finden Sie in den Erweiterungsbeispielen.

Kontextdaten der Erweiterung

Kontextdaten des Erweiterungsframeworks dürfen nicht mit React-Kontexten verwechselt werden.

Erweiterungen haben die Möglichkeit, Kontextdaten für alle Nutzer einer Erweiterung freizugeben. Kontextdaten können für Daten verwendet werden, die sich nicht oft ändern und keine besonderen Sicherheitsanforderungen haben. Seien Sie vorsichtig, wenn Sie die Daten schreiben, da es keine Datensperre gibt und der letzte Schreibvorgang gewinnt. Die Kontextdaten sind sofort nach dem Start für die Erweiterung verfügbar. Das Looker Extension SDK bietet Funktionen zum Aktualisieren der Kontextdaten.

Die Kontextdaten dürfen maximal 16 MB groß sein. Kontextdaten werden in einen JSON-String serialisiert, sodass das auch berücksichtigt werden muss, wenn Sie Kontextdaten für Ihre Erweiterung verwenden.

import { ExtensionContext2 } from '@looker/extension-sdk-react'

. . .

  const extensionContext = useContext(
    ExtensionContext2
  )
  const { extensionSDK } = extensionContext

. . .

  // Get loaded context data. This will reflect any updates that have
  // been made by saveContextData.
  let context = await extensionSDK.getContextData()

. . .

  // Save context data to Looker server.
  context = await extensionSDK.saveContextData(context)

. . .

  // Refresh context data from Looker server.
  context = await extensionSDK.refreshContextData()

Nutzerattribute

Das Looker Extension SDK bietet eine API für den Zugriff auf Looker-Nutzerattribute. Es gibt zwei Arten von Zugriffsrechten für Nutzerattribute:

  • Auf einen Bereich – Mit der Erweiterung verknüpft. Ein auf einen Bereich beschränktes Nutzerattribut wird als Namespace auf die Erweiterung festgelegt und das Nutzerattribut muss in der Looker-Instanz definiert werden, bevor es verwendet werden kann. Wenn Sie ein Nutzerattribut mit einem Namespace versehen möchten, stellen Sie dem Attributnamen den Erweiterungsnamen voran. Bindestriche und die Zeichen „#“ im Namen der Erweiterung müssen durch einen Unterstrich ersetzt werden, da Bindestriche und Doppelpunkte nicht in Nutzerattributnamen verwendet werden dürfen.

    Beispiel: Für ein auf Nutzer beschränktes Nutzerattribut namens my_value, das mit der Erweiterungs-ID my-extension::my-extension verwendet wird, muss der Nutzerattributname my_extension_my_extension_my_value festgelegt sein. Nach der Definition kann das Nutzerattribut von der Erweiterung gelesen und aktualisiert werden.

  • Global: Dies sind globale Nutzerattribute und schreibgeschützt. Ein Beispiel hierfür ist das Nutzerattribut locale.

Im Folgenden finden Sie eine Liste der API-Aufrufe für Nutzerattribute:

  • userAttributeGetItem: Liest ein Nutzerattribut. Es kann ein Standardwert definiert werden und wird verwendet, wenn für den Nutzer kein Nutzerattributwert vorhanden ist.
  • userAttributeSetItem: Speichert ein Nutzerattribut für den aktuellen Nutzer. Fehler bei globalen Nutzerattributen. Der gespeicherte Wert ist nur für den aktuellen Nutzer sichtbar.
  • userAttributeResetItem: Setzt ein Nutzerattribut für den aktuellen Nutzer auf den Standardwert zurück. Fehler bei globalen Nutzerattributen.

Um auf Nutzerattribute zuzugreifen, musst du die Attributnamen in den Berechtigungen global_user_attributes und/oder scoped_user_attributes angeben. In der LookML-Projektdatei von LookML würden Sie beispielsweise Folgendes hinzufügen:

  entitlements: {
    scoped_user_attributes: ["my_value"]
    global_user_attributes: ["locale"]
  }
import { ExtensionContext2 } from '@looker/extension-sdk-react'

. . .

  const extensionContext = useContext(
    ExtensionContext2
  )
  const { extensionSDK } = extensionContext

  // Read global user attribute
  const locale = await extensionSDK.userAttributeGetItem('locale')

  // Read scoped user attribute
  const value = await extensionSDK.userAttributeGetItem('my_value')

  // Update scoped user attribute
  const value = await extensionSDK.userAttributeSetItem('my_value', 'abcd1234')

  // Reset scoped user attribute
  const value = await extensionSDK.userAttributeResetItem('my_value')

Lokale Speicherung

iFrames in einer Sandbox bieten keinen Zugriff auf den lokalen Browserspeicher. Das Looker Extension SDK ermöglicht es einer Erweiterung, im lokalen Speicher des übergeordneten Fensters zu lesen und zu schreiben. Der lokale Speicher ist als Namespace für die Erweiterung definiert. Das bedeutet, dass der lokale Speicher nicht gelesen werden kann, wenn das übergeordnete Fenster oder andere Erweiterungen erstellt wurden.

Für die Verwendung des lokalen Speichers ist die Berechtigung local_storage erforderlich.

Die Localhost API-Erweiterung ist asynchron und nicht synchron.

import { ExtensionContext2 } from '@looker/extension-sdk-react'

. . .

  const extensionContext = useContext(
    ExtensionContext2
  )
  const { extensionSDK } = extensionContext

  // Read from local storage
  const value = await extensionSDK.localStorageGetItem('my_storage')

  // Write to local storage
  await extensionSDK.localStorageSetItem('my_storage', 'abcedefh')

  // Delete item from local storage
  await extensionSDK.localStorageRemoveItem('my_storage')

Seitentitel wird aktualisiert

Der aktuelle Seitentitel wird eventuell durch Erweiterungen aktualisiert. Für diese Aktion sind keine Berechtigungen erforderlich.

import { ExtensionContext2 } from '@looker/extension-sdk-react'

. . .

  const extensionContext = useContext(
    ExtensionContext2
  )
  const { extensionSDK } = extensionContext

  extensionSDK.updateTitle('My Extension Title')

In die Zwischenablage schreiben

iFrames in iFrames erlauben keinen Zugriff auf die Systemzwischenablage. Mit dem Looker Extension SDK können Erweiterungen Texte in die Systemzwischenablage schreiben. Aus Sicherheitsgründen darf die Erweiterung nicht aus der Zwischenablage des Systems gelesen werden.

Zum Schreiben in die Zwischenablage benötigen Sie die Berechtigung use_clipboard.

import { ExtensionContext2 } from '@looker/extension-sdk-react'

. . .

const extensionContext = useContext(
    ExtensionContext2
  )
  const { extensionSDK } = extensionContext

    // Write to system clipboard
    try {
      await extensionSDK.clipboardWrite(
        'My interesting information'
      )
      . . .
    } catch (error) {
      . . .
    }

Dashboards, Looks und Erkundungen einbetten

Das Framework für Erweiterungen unterstützt das Einbetten von Dashboards, Looks und Explores. Es können sowohl reguläre Dashboards als auch ältere Dashboards eingebettet werden.

Die Berechtigung use_embeds ist erforderlich. Wir empfehlen, Inhalte mit dem Looker JavaScript Embed SDK einzubetten. Weitere Informationen findest du in der Dokumentation zum SDK zum Einbetten.

import { ExtensionContext2 } from '@looker/extension-sdk-react'

. . .

  const extensionContext = useContext(
    ExtensionContext2
  )
  const { extensionSDK } = extensionContext

. . .

  const canceller = (event: any) => {
    return { cancel: !event.modal }
  }

  const updateRunButton = (running: boolean) => {
    setRunning(running)
  }

  const setupDashboard = (dashboard: LookerEmbedDashboard) => {
    setDashboard(dashboard)
  }

  const embedCtrRef = useCallback(
    (el) => {
      const hostUrl = extensionContext?.extensionSDK?.lookerHostData?.hostUrl
      if (el && hostUrl) {
        el.innerHTML = ''
        LookerEmbedSDK.init(hostUrl)
        const db = LookerEmbedSDK.createDashboardWithId(id as number)
          .withNext()
          .appendTo(el)
          .on('dashboard:loaded', updateRunButton.bind(null, false))
          .on('dashboard:run:start', updateRunButton.bind(null, true))
          .on('dashboard:run:complete', updateRunButton.bind(null, false))
          .on('drillmenu:click', canceller)
          .on('drillmodal:explore', canceller)
          .on('dashboard:tile:explore', canceller)
          .on('dashboard:tile:view', canceller)
          .build()
          .connect()
          .then(setupDashboard)
          .catch((error: Error) => {
            console.error('Connection error', error)
          })
      }
    },
    []
  )

  return (<EmbedContainer ref={embedCtrRef} />)

In den Erweiterungsbeispielen werden Komponenten mit Stil verwendet, um dem generierten iFrame ein einfaches Design zu geben. Beispiel:

import styled from "styled-components"

export const EmbedContainer = styled.div`
  width: 100%;
  height: 95vh;
  & > iframe {
    width: 100%;
    height: 100%;
  }

Auf externe API-Endpunkte zugreifen

Das Framework der Erweiterung bietet zwei Methoden für den Zugriff auf externe API-Endpunkte:

  • Der Server-Proxy – Greift über den Looker-Server auf den Endpunkt zu. Mit diesem Mechanismus können Client-IDs und geheime Schlüssel sicher vom Looker-Server festgelegt werden.
  • Der Abruf-Proxy - Greift vom Browser des Benutzers auf den Endpunkt zu. Der Proxy ist die Looker-UI.

In beiden Fällen müssen Sie den externen API-Endpunkt in der external_api_urls-Berechtigung der Erweiterung angeben.

Server-Proxy

Im folgenden Beispiel wird gezeigt, wie mit dem Server-Proxy ein Zugriffstoken zur Verwendung durch den Abruf-Proxy abgerufen wird. Die Client-ID und das Secret müssen als Nutzerattribute für die Erweiterung definiert werden. Normalerweise wird der Standardwert bei der Einrichtung des Nutzerattributs auf die Client-ID oder das Secret festgelegt.

import { ExtensionContext2 } from '@looker/extension-sdk-react'

. . .

  const extensionContext = useContext(
    ExtensionContext2
  )
  const { extensionSDK } = extensionContext

. . .
  const requestBody = {
    client_id: extensionSDK.createSecretKeyTag('my_client_id'),
    client_secret: extensionSDK.createSecretKeyTag('my_client_secret'),
  },
  try {
    const response = await extensionSDK.serverProxy(
      'https://myaccesstokenserver.com/access_token',
      {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
        },
        body: JSON.stringify(requestBody),
      }
    )
    const { access_token, expiry_date } = response.body
. . .
  } catch (error) {
    // Error handling
    . . .
  }

Der Name des Nutzerattributs muss der Erweiterung zugeordnet werden. Striche müssen durch Unterstriche ersetzt werden und :: Zeichen müssen durch einen Unterstrich ersetzt werden.

Wenn die Erweiterung beispielsweise den Namen „my-extension::my-extension“ hat, müssen die Nutzerattribute, die im obigen Beispiel definiert werden müssen, so aussehen:

my_extension_my_extension_my_client_id
my_extension_my_extension_'my_client_secret'

Proxy abrufen

Im folgenden Beispiel wird die Verwendung des Abrufproxys veranschaulicht. Es verwendet das Zugriffstoken aus dem vorherigen Server-Proxy-Beispiel.

import { ExtensionContext2 } from '@looker/extension-sdk-react'

. . .

  const extensionContext = useContext(
    ExtensionContext2
  )
  const { extensionSDK } = extensionContext

. . .

  try {
    const response = await extensionSDK.fetchProxy(
      'https://myaccesstokenserver.com/myendpoint',
      {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
          Authorization: `Bearer ${accessToken}`,
        },
        body: JSON.stringify({
          some_value: someValue,
          another_value: anotherValue,
        }),
      }
    )
    // Handle success

. . .

  } catch (error) {
    // Handle failure

. . .

  }

OAuth-Integration

Das Framework der Erweiterung unterstützt die Integration mit OAuth-Anbietern. OAuth kann verwendet werden, um ein Zugriffstoken für eine bestimmte Ressource abzurufen, z. B. ein Dokument in Goorgle.

Du musst den OAuth-Serverendpunkt in der Berechtigung extension oauth2_urls angeben. Möglicherweise müssen Sie auch zusätzliche URLs in der Berechtigung external_api_urls angeben.

Die Frameworks für Erweiterungen unterstützen die folgenden Abläufe:

  • Impliziter Ablauf
  • Art der Autorisierungscode-Freigabe mit geheimem Schlüssel
  • PKCE-Identitätsbestätigung und -Verifizierung

Im Allgemeinen wird ein untergeordnetes Fenster geöffnet, in dem eine OAuth-Serverseite geladen wird. Der OAuth-Server authentifiziert den Nutzer und leitet Sie zurück an den Looker-Server, mit zusätzlichen Details, die zum Abrufen eines Zugriffstokens verwendet werden können.

Impliziter Ablauf:

import { ExtensionContext2 } from '@looker/extension-sdk-react'

. . .

  const extensionContext = useContext(
    ExtensionContext2
  )
  const { extensionSDK } = extensionContext

. . .

    const response = await extensionSDK.oauth2Authenticate(
      'https://accounts.google.com/o/oauth2/v2/auth',
      {
        client_id: GOOGLE_CLIENT_ID!,
        scope: GOOGLE_SCOPES,
        response_type: 'token',
      }
    )
    const { access_token, expires_in } = response

Berechtigungsart für Autorisierungscode mit geheimem Schlüssel:

  const authenticateParameters: Record<string, string> = {
    client_id: GITHUB_CLIENT_ID!,
    response_type: 'code',
  }
  const response = await extensionSDK.oauth2Authenticate(
    'https://github.com/login/oauth/authorize',
    authenticateParameters,
   'GET'
  )
  const exchangeParameters: Record<string, string> = {
    client_id: GITHUB_CLIENT_ID!,
    code: response.code,
    client_secret: extensionSDK.createSecretKeyTag('github_secret_key'),
  }
  const codeExchangeResponse = await extensionSDK.oauth2ExchangeCodeForToken(
    'https://github.com/login/oauth/access_token',
    exchangeParameters
  )
  const { access_token, error_description } = codeExchangeResponse

PKCE-Code-Herausforderung und -Verifizierer:

import { ExtensionContext2 } from '@looker/extension-sdk-react'

. . .

  const extensionContext = useContext(
    ExtensionContext2
  )
  const { extensionSDK } = extensionContext

. . .

  const authRequest: Record<string, string> = {
    client_id: AUTH0_CLIENT_ID!,
    response_type: 'code',
    scope: AUTH0_SCOPES,
    code_challenge_method:  'S256',
  }
  const response = await extensionSDK.oauth2Authenticate(
    'https://sampleoauthserver.com/authorize',
    authRequest,
    'GET'
  )
  const exchangeRequest: Record<string, string> = {
    grant_type: 'authorization_code',
    client_id: AUTH0_CLIENT_ID!,
    code: response.code,
  }
  const codeExchangeResponse = await extensionSDK.oauth2ExchangeCodeForToken(
    'https://sampleoauthserver.com/login/oauth/token',
    exchangeRequest
  )
  const { access_token, expires_in } = codeExchangeResponse

Spartanisch

Spartan bezeichnet eine Methode, bei der die Looker-Instanz als Umgebung verwendet wird, um Erweiterungen (nur Erweiterungen) einer bestimmten Gruppe von Nutzern zur Verfügung zu stellen. Ein spartanischer Nutzer, der zu einer Looker-Instanz navigiert, wird mit dem Anmeldevorgang angezeigt, den der Looker-Administrator konfiguriert hat. Nach der Authentifizierung wird dem Nutzer eine Erweiterung entsprechend seinem landing_page Nutzerattribut angezeigt (siehe unten). Der Nutzer kann nur auf Erweiterungen und nicht auf andere Bereiche von Looker zugreifen. Wenn der Nutzer Zugriff auf mehrere Erweiterungen hat, kann er mit extensionSDK.updateLocation steuern, wie er die anderen Erweiterungen aufrufen kann. Es gibt eine spezifische Looker Extension SDK-Methode, mit der sich Nutzer von der Looker-Instanz abmelden können.

import { ExtensionContext2 } from '@looker/extension-sdk-react'

. . .

  const extensionContext = useContext(
    ExtensionContext2
  )
  const { extensionSDK } = extensionContext

. . .
  // Navigate to another extension
  extensionSDK.updateLocation('/spartan/another::extension')

. . .
  // Logout
  extensionSDK.spartanLogout()

Spartanische Nutzer definieren

Wenn Sie einen spartanischen Nutzer definieren möchten, müssen Sie eine Gruppe namens „Nur Erweiterungen“ erstellen.

Nachdem die Gruppe „Nur Erweiterungen“ erstellt wurde, rufen Sie im Abschnitt Admin von Looker die Seite Nutzerattribute auf und bearbeiten Sie das Nutzerattribut landing_page. Wählen Sie den Tab Gruppenwerte aus und fügen Sie die Gruppe "Nur Erweiterungen" hinzu. Der Wert sollte auf /spartan/my_extension::my_extension/ gesetzt werden, wobei my_extension::my_extension die ID Ihrer Erweiterung ist. Wenn dieser Nutzer sich anmeldet, wird der Nutzer zur angegebenen Erweiterung weitergeleitet.

Codeaufteilung

Bei der Codeaufteilung wird Code nur dann angefordert, wenn er erforderlich ist. In der Regel werden Codeblöcke mit React-Routen verknüpft, bei denen jede Route einen eigenen Codeblock erhält. In Reaktion darauf erfolgt dies mit den Komponenten Suspense und React.lazy. Die Komponente Suspense zeigt eine Fallback-Komponente an, während der Codeblock geladen wird. React.lazy ist für das Laden des Codeblocks verantwortlich.

Einrichtung der Codeaufteilung:

import { AsyncComp1 as Comp1 } from './Comp1.async'
import { AsyncComp1 as Comp2 } from './Comp2.async'

. . .

                <Suspense fallback={<div>Loading...</div>}>
                  <Switch>
                      <Route path="/comp1">
                        <Comp1 />
                      </Route>
                      <Route path="/comp2">
                        <Comp2 />
                      </Route>
                  </Switch>
                <Suspense>

Die Lazy-Load-Komponente wird so implementiert:

import { lazy } from 'react'

const Comp1 = lazy(
 async () => import(/* webpackChunkName: "comp1" */ './Comp1')
)

export const AsyncComp1 = () => &#60;Home />

Die Komponente wird folgendermaßen implementiert. Die Komponente muss als Standardkomponente exportiert werden:

const Comp1 = () => {
  return (
    &#60;div&#62;Hello World&#60;/div&#62;
  )
}

export default Comp1

Baumschütteln

Looker-SDKs unterstützen zwar das Schütteln von Bäumen, sind aber noch nicht perfekt. Wir ändern unsere SDKs ständig, um die Unterstützung für Baumschütteln zu verbessern. Für einige dieser Änderungen ist es unter Umständen erforderlich, den Code zu refaktorieren, um die Vorteile nutzen zu können. In diesen Fällen wird der Code aber in den Versionshinweisen dokumentiert.

Wenn Sie das Baumschütteln des verwendeten Moduls nutzen möchten, müssen Sie es als Esmodule exportieren. Die importierten Funktionen dürfen keine Nebeneffekte haben. All das ist mithilfe des Looker SDK for TypeScript/JavaScript, der Looker SDK Runtime Library, der Looker UI Components, des Looker Extension SDK und des Extension SDK for React möglich.

In einer Erweiterung sollten Sie eines der Looker SDKs (3.1 oder 4.0) auswählen und die Komponente ExtensionProvider2 aus dem Extension SDK for React verwenden. Wenn Sie beide SDKs benötigen, verwenden Sie weiterhin die Komponente „ExtensionProvider“, aber die endgültige Set-Größe erhöht sich.

Mit dem folgenden Code wird der Erweiterungsanbieter eingerichtet. Sie müssen dem Anbieter mitteilen, welches SDK Sie verwenden möchten:

import { MyExtension } from './MyExtension'
import { ExtensionProvider2 } from '@looker/extension-sdk-react'
import { Looker40SDK } from '@looker/sdk/lib/4.0/methods'
import { hot } from 'react-hot-loader/root'

export const App = hot(() => {

  return (
    &#60;ExtensionProvider2 type={Looker40SDK}&#62;
      &#60;MyExtension /&#62;
    &#60;/ExtensionProvider2&#62;
  )
})

Verwenden Sie in Ihrer Erweiterung nicht den folgenden Importstil:

import * as lookerComponents from `@looker/components`

Im Beispiel oben ist alles aus dem Modul enthalten. Importieren Sie stattdessen nur die Komponenten, die Sie wirklich brauchen. Beispiel:

import { Paragraph }  from `@looker/components`

Glossar

  • Codeaufteilung: Eine Technik zum Lazy Loading von JavaScript, bis sie tatsächlich benötigt wird. Idealerweise sollten Sie das anfänglich geladene JavaScript-Bundle so klein wie möglich halten. Dies lässt sich mithilfe der Codeaufteilung erreichen. Funktionen, die nicht sofort benötigt werden, werden erst geladen, wenn sie wirklich gebraucht werden.
  • IDE: Integrierte Entwicklungsumgebung Ein Editor zum Erstellen und Ändern einer Erweiterung. Beispiele hierfür sind Visual Studio Code, Intellij und WebStorm.
  • Scene – In der Regel ein Seitenaufruf in Looker. Szenen sind auf den Hauptrouten zu sehen. Manchmal enthält eine Szene untergeordnete Szenen, die den untergeordneten Routen der Hauptroute zugeordnet sind.
  • Transpile — Der Prozess, bei dem Quellcode in eine Sprache geschrieben und in eine andere Sprache mit einer ähnlichen Abstraktionsebene umgewandelt wird. Ein Beispiel hierfür ist TypeScript für JavaScript.