2017-03-07 4 views
0

So verwende ich react-router zusammen mit require.ensure und Webpack, um meine Routen zu chunk out. Dies hat sich jedoch von vorformulierten in einem viel Folge:Wie erstellt Const in einer Schleife für require.ensure?

const getTermsAndConditions = (nextState, cb) => { 
    require.ensure([], require => { 
    cb(null, require('../containers/TermsAndConditions/TermsAndConditions')) 
    }, 'terms') 
} 
const getThread = (nextState, cb) => { 
    require.ensure([], require => { 
    cb(null, require('../components/Thread/Thread')) 
    }, 'inbox') 
} 
const getPrivacyPolicy = (nextState, cb) => { 
    require.ensure([], require => { 
    cb(null, require('../containers/PrivacyPolicy/PrivacyPolicy')) 
    }, 'privacy-policy') 
} 

Ich habe etwa 25 dieser Erklärungen in einer Reihe, und dann in der eigentlichen Render-Funktion:

<Route path='privacy' getComponent={getPrivacyPolicy} /> 
...etc 

ich nicht Denken Sie daran, dass die Routen fest codiert sind, da sie eine gute Vorstellung vom Gesamtlayout der Anwendung geben, aber ich möchte das Muster für die Typenkennzeichen getPrivacyPolicy reduzieren. Wie kann ich das machen?

EDIT: Ich habe genommen, nachdem @ Michael Jungo Antwort haben, aber das Ergebnis der getComponentFactory produziert Funktionen gefunden, die noch var Namen in sich haben, nicht fest einprogrammiert Saiten.

ZB:

const PrivacyPolicy = getComponentFactory('../containers/PrivacyPolicy/PrivacyPolicy', 'privacy-policy') 

Und dann console.log(PrivacyPolicy) kehrt:

PrivacyPolicy: function (nextState, cb) { 
    require.ensure([], function (require) { 
    return cb(null, require(path)) 
    }, chunkName) 
} 

So beide path und chunkName nicht durch ihre tatsächlichen String-Werte ersetzt ...

+0

Natürlich gibt es keine fest codierten Zeichenketten sind, das ist nur, wie Verschlüsse funktionieren! (Sie können dies umgehen, indem Sie 'eval' verwenden, aber ich nehme nicht an, dass Sie das wollen). Da Sie jedoch keine explizite Abhängigkeit angeben, sollten Sie in der Lage sein, Ihre 'require'-Aufrufe anzupassen, um die Warnung zu vermeiden. Vielleicht möchtest du [eine separate Frage stellen] (http://stackoverflow.com/questions/ask) darüber. – Bergi

+0

@Bergi Ich wüsste nicht mal, was ich fragen soll. Stört es Sie zu erklären, wie ich die "require" Anrufe anpassen würde? Nach dem Ausführen meines Webpack-Builds sieht es so aus, als ob diese Chunks nicht einmal generiert werden, also ist es kein einfacher Fehler. –

+0

Ah, ich habe verpasst, dass Webpack versucht, diese Dinge zu analysieren, um Chunks zu erstellen. Ich ging davon aus, dass das Skript zumindest ausführbar wäre, wenn man das AMD-Format "require" (mit einem Callback) verwendet. Auch finde ich es ziemlich merkwürdig, dass Sie 'require.ensure' verwenden, aber keine Abhängigkeiten angeben. – Bergi

Antwort

3

Leider können Sie‘ t reduzieren den Code wirklich mehr, weil require und require.ensure String-Literal erhalten müssen s, Variablen werden nicht funktionieren. Es muss zur Kompilierzeit ohne Programmablaufanalyse bekannt sein. Diese getComponent Funktionen enthalten nur die require.ensure-Anweisung, so dass Sie stecken alle explizit schreiben.


Alte Antwort

Du hast recht, das ist eine Menge von vorformulierten, aber es ist sehr einfach loswerden die meisten davon zu bekommen, weil man so ziemlich ist nur den gleichen Code zu duplizieren mit unterschiedlichem Argumente.

Bevor Sie in den Code einsteigen, ist es wichtig zu wissen, dass Funktionen erstklassige Bürger in JavaScript sind. Das heißt, Sie können eine Funktion als Parameter verwenden, einen Wert zurückgeben und ihn einer Variablen zuweisen, genau wie jeder andere Wert auch. Genau das haben Sie getan, Sie haben function expression verwendet und einer Variablen zugewiesen (z. B. getPrivacyPolicy). Nun, Sie haben arrow functions verwendet, was eine spezielle Syntax für Funktionsausdrücke ist (mit einigen Unterschieden, wie in der Dokumentation gezeigt). Die Variable dient nur dazu, einen Verweis darauf zu haben, den Sie später verwenden können. Sie benötigen diese Referenzen nicht unbedingt, und Sie können sie direkt an das Attribut getComponent übergeben.

In diesem Sinne können Sie beginnen, Ihre Funktionen zu refaktorieren. In Ihren Funktionen ist alles gleich, außer für die path, die Sie benötigen, und die chunkName. Daher werden Sie eine Funktion erstellen, die path und chunkName als Parameter und eine neue Funktion zurückgibt, die in getComponent verwendet wird.

const getComponentFactory = (path, chunkName) => { 
    // Return the function that will be passed to getComponent 
    return (nextState, cb) => { 
    require.ensure([], require => cb(null, require(path)), chunkName); 
    }; 
} 

Jetzt können Sie ganz einfach die Funktionen, die Sie durch den Aufruf getComponentFactory zum Beispiel haben erstellen:

const getThread = getComponentFactory('../components/Thread/Thread', 'inbox'); 

Und wie bereits erwähnt, bevor Sie wirklich nicht, diese Funktion zu einer Variablen zugewiesen werden müssen, aber Sie kann es in Ihrem Route direkt verwenden, wenn Sie wollen:

<Route 
    path='inbox' 
    getComponent={getComponentFactory('../components/Thread/Thread', 'inbox')} 
/> 

Hinweis: vergessen Sie nicht den Unterschied zwischen einem Spaß Aufruf ction und übergeben es.

console.log(func);  // The function func is printed 
console.log(func(args)); // The return value of func is printed 
+0

Sie können sogar den' ../ components/'Teil und die Vervielfältigung des Modulnamens in die Factory – Bergi

+0

@Michael Jungo - dies verschieben erzeugt den folgenden Fehler 'require Funktion wird in einer Weise verwendet, in der Abhängigkeiten nicht statisch extrahiert werden können '... irgendeine Idee warum? –

+0

@Michael Jungo Es sieht so aus, als ob eine Funktion zurückgegeben wird, die 'path' und' chunkName' nicht durch Strings ersetzt hat. Wie stellst du eine Funktion mit fest codierten Saiten her? –

Verwandte Themen