wake-up-neo.com

Dynamische ES6-Importe mit Webpack und Babel

Ich habe Webpack für mein ES6 JS-Projekt verwendet und lief gut, bis ich mit dynamischen Importen angefangen habe.

Was hatte ich damit gemacht (router.js):

import { navigo } from "Navigo"; // router
import { clients } from "Controllers/clients.js";

const navigo = new Navigo();

navigo_router.on({
  '/clients': () => {
    clients.init();
  }
});

Aber je mehr Seiten/Routen ich hinzufüge, desto mehr Importe werden im Kopf des Moduls gestapelt. Dies ist eine relativ große App und ich muss viele Seiten/Routen hinzufügen. Daher muss ich sie dynamisch laden, um die Größe der anfänglichen Seitenlast zu reduzieren.

Nach der Dokumentation von Webpack für dynamische Importe habe ich Folgendes versucht, wodurch das Controller-Modul nur geladen wird, wenn die relative Route aufgerufen wird:

import { navigo } from "Navigo"; // router

const navigo = new Navigo();

navigo_router.on({
  '/clients': () => {
    import("Controllers/clients.js").then((clients) => {
      clients.init();
    });
  }
});

Das Speichern in meinem Editor führte jedoch zu einem Babel-Transiling-Fehler. SyntaxError: 'import' und 'export' werden möglicherweise nur auf oberster Ebene angezeigt und clients.init() wird nicht aufgerufen, wenn sie im Browser getestet werden.

Nach einigem Lesen entdeckte ich, dass ich ein Babel-Plugin benötigte, um die dynamische import() in require.ensure zu transpilieren. Also habe ich das Plugin mit folgendem Befehl installiert:

npm install babel-plugin-dynamic-import-webpack --save-dev

Und das Plugin in meiner babel.rc-Datei deklariert

{ "plugins": ["dynamic-import-webpack"] }

Nach der Installation des Plugins verschwand der Transpiling-Fehler und die Überprüfung meines transpiled-Codes ergab, dass die dynamischen import()s tatsächlich wie erwartet in require.ensure geändert wurden. Nun bekomme ich beim Testen jedoch folgende Browserfehler:

Error: Loading chunk 0 failed.
Stack trace:
[email protected]://<mydomain.com>/js/app.bundle.js:1:871
SyntaxError: expected expression, got '<' 0.app.bundle.js:1
Error: Loading chunk 0 failed.

Ich verstand nicht, warum er mit dem Präfix 0.app.bundle.js auf 0. verwies, also habe ich meinen Ausgabe/dist-Ordner überprüft und habe jetzt eine neue Datei mit dem Namen 0.app.bundle.js:

0.app.bundle.js      1,962bytes
app.bundle.js        110,656bytes

Ich kann mir vorstellen, dass es sich bei dieser neuen gebündelten Datei um das dynamisch importierte Modul clients.js handelt.

Ich habe nur dynamischen Import zu dieser einen Route hinzugefügt und habe alle anderen Routen so gelassen wie sie waren. Während des Testens kann ich also alle Routen mit Ausnahme der einen /clients-Route anzeigen, die jetzt die obigen Fehler auslöst.

Ich bin an diesem Punkt total verloren und hoffe, dass mir jemand helfen kann, mich über die Ziellinie zu bringen. Was ist diese neue Datei 0.app.bundle.js und wie soll ich sie verwenden/in meine Anwendung aufnehmen?

Ich hoffe, ich habe mich klar genug erklärt und freue mich auf alle Antworten.

7
Martin James

Am Ende habe ich es geschafft, mein eigenes Problem zu lösen, also werde ich mitteilen, was ich in einer Antwort gefunden habe.

Die Chunk-Datei wurde nicht geladen, weil Webpack im falschen Verzeichnis danach gesucht hat. Ich habe auf der Registerkarte Netzwerk meiner Entwicklerkonsole festgestellt, dass die Chunk-Datei/das -Modul von meinem Stammverzeichnis / aus aufgerufen wurde und nicht in /js-Verzeichnis, wo es hingehört.

Gemäß der Webpack-Dokumentation habe ich meiner Webpack-Konfigurationsdatei Folgendes hinzugefügt:

output: {
  path: path.resolve(__dirname, 'dist/js'),
  publicPath: "/js/", //<---------------- added this
  filename: 'app.bundle.js'
},

Nach meinem Verständnis ist path für die statischen Module von Webpack und publicPath für dynamische Module.

Dies führte zu einem korrekten Laden des Chunks, aber ich hatte auch weitere Probleme zu lösen, da client.init() nicht aufgerufen wurde und der folgende Fehler ausgegeben wurde:

TypeError: e.init is not a function

Um dies zu beheben, musste ich auch Folgendes ändern:

import("Controllers/clients.js").then((clients) => {
  clients.init();
});

Zu:

import("Controllers/clients.js").then(({clients}) => {
  clients.init();
});

Beachten Sie die geschweiften Klammern im Pfeilfunktionsparameter.

Ich hoffe, das hilft jemand anderem.

3
Martin James

Für das Debuggen müssen Sie das tun

import("Controllers/clients.js").then((clients) => {
    console.log(clients);
});

vielleicht arbeiten 

import("Controllers/clients.js").then((clients) => {
    clients.default.init();
});
0
Igor Ognichenko