webentwicklung-frage-antwort-db.com.de

Einbettbares Javascript-Plugin mit React & Webpack schreiben

Ich möchte in der Lage sein, meine React-App mit Webpack zu bündeln, sodass verteilte Kopien, die auf einem CDN abgelegt werden, mit einer Reihe von für einen Client relevanten configs aufgerufen, aufgerufen und initialisiert werden können.

Nach dem Lesen von this und this stelle ich meine Webpack-Eingabedatei wie folgt ein:

// ... React requires etc.

(() => {
  this.MyApp = (config) => {
    // some constructor code here
  }

  MyApp.prototype.init = () => {
    ReactDOM.render(<MyReactApp config={MyApp.config} />, someSelector);
  }
})();

Die Idee ist, dass ich in meinem Kunden so etwas wie das Folgende machen kann:

<script src="./bundle.js" type="text/javascript"></script>
<script type="text/javascript">
  MyApp.init({
    some: "config"
  });
</script>

Und meine MyApp#init-Funktion wird meine React-App in einem Container auf dem Client darstellen.

Denk ich richtig darüber nach? Gibt es einen einfacheren oder effizienteren Weg, dies zu tun?

Mein Fehler ist Uncaught TypeError: Cannot set property 'MyApp' of undefined, da this im IIFE undefined ist. Ich möchte wirklich gerne verstehen, warum dies geschieht, und Ratschläge, wie das Problem behoben werden kann.

Danke im Voraus!

20
mattsch

Also fand ich irgendwie eine Lösung dafür, wie beschrieben hier

Wenn ich meine webpack.config.js-Datei ändere, um dem output-Objekt die folgenden Attribute hinzuzufügen, d. H.

var config = {
  // ...
  output: {
    // ...
    library: 'MyApp',
    libraryTarget: 'umd',
    umdNamedDefine: true,
  }
}

Dies gibt die Datei an, die mit webpack als UMD-Modul gebündelt wird. Wenn ich also eine Funktion in dieser Datei habe und sie exportiere ...

export const init = (config) => {
  ReactDOM.render(<MyReactApp config={config} />, someSelector);
}

Ich kann dann in meinem Kunden folgendes tun.

<script src="./bundle.js" type="text/javascript"></script>
<script type="text/javascript">
  MyApp.init({
    some: "config"
  }); 
</script>

Und meine React-App wird wiedergegeben.

Wenn jemand denkt, dass dies eine dumme Art ist, würde ich es gerne hören!

29
mattsch

Sie haben ein Gehäuse um Ihre Klasse.

MyApp muss exportiert oder an das globale Fensterobjekt angehängt werden, bevor Sie es so aufrufen können. 

In Ihrer Situation rufen Sie zwar nicht MyApp.init () auf, aber Sie rufen window.MyApp.init () auf, aber das globale Objektfenster hat kein Objekt, das MyApp angehängt ist.

// ... Simple attaching MyApp to the window (as a function)
window.MyApp = (config) => {
  ...
}

// ... Using class and export
class MyApp {
  constructor(config){...}
}
export default MyApp

// or simply attach to the window
window.MyApp = MyApp

Ich würde es vorziehen, Klassen- und Exportmodule mit Export zu erstellen. Erstellen Sie dann eine weitere Datei, die Sie nur an das Fenster anhängen können. Da es nicht als bewährte Methode angesehen wird, Klassen so an das Fenster anzuhängen.

// Import module and attach it to the window
import MyApp from '.my-app'
window.MyApp = MyApp

Sie können nach erweiterten Optionen zum Exportieren von Modulen wie UMD, AMD ... suchen.

0