2016-03-21 11 views
2

Ich habe eine Komponente Reagieren erstellt, und ich möchte ein verteilen integrierte Version (gebaut mit großem Schluck) dieser Komponente, so in gulpfile.js ich habe:Bauen Reagiert Komponenten mit Gulp, Browserify und Babel

var gulp = require('gulp'); 
var browserify = require('browserify'); 
var babelify = require('babelify'); 
var source = require('vinyl-source-stream'); 

gulp.task('build-js', function() { 
    return browserify('./src/Foo.js') 
     .transform(babelify) 
     .bundle() 
     .pipe(source('bundle.js')) 
     .pipe(gulp.dest('./dist')); 
}); 

gulp.task('build', ['build-js']); 

in .babelrc:

{ 
    "presets": ["es2015", "react", "stage-0"], 
} 

Und das sind die Abhängigkeiten in package.json:

"dependencies": { 
    "react": "^0.14.7" 
} 
"devDependencies": { 
    "babel-polyfill": "^6.3.14", 
    "babel-preset-es2015": "^6.3.13", 
    "babel-preset-react": "^6.3.13", 
    "babel-preset-stage-0": "^6.3.13", 
    "babelify": "^7.2.0", 
    "browserify": "^13.0.0", 
    "gulp": "^3.9.1", 
    "react": "^0.14.7", 
    "react-dom": "^0.14.7", 
    "vinyl-source-stream": "^1.1.0" 
} 

Wenn ich laufe gulp build (nach npm install) build.js Datei unter /dist erstellt wird, aber wenn ich versuche, diese Komponente zu verwenden, um von anderen App Reagieren bekomme ich den Fehler:

Error: Cannot find module ' ./emptyFunction'.

Wenn ich in diese Datei zu graben (build.js)

var emptyFunction = require('./emptyFunction'); 
... 
var camelize = require('./camelize'); 

diese Dateien existiert nicht unter ./dist, so dass der Fehler ausgelöst wird, wenn ich versuche, die neue Reagieren App Aufruf der Komponente zu erstellen: kann ich diese Zeilen sehen

import Foo from 'my-components-in-node-modules'; 

Was fehlt mir?

bearbeiten:

Wie ich sehen kann, ist die seltsame erfordert kommen aus der Komponentendatei Reagieren erfordern:

var React = require('react'); 
// or import React from 'react'; 

class Foo extends React.Component { 
    static propTypes = {...}; 
    static defaultProps = {...}; 
    render() {...} 
} 
export default Foo; 

Wenn ich var React = require('react'); diejenigen erfordert (emptyFunction, camelize entfernen) verschwinden, und der Fehler ist offensichtlich React is not defined.

Edit2:

Wie @JMM schon sagt, soll ich die Abhängigkeiten (in meinem Fall Reagieren) im dist Ordner, aber wie soll ich es erreichen? Was passiert, wenn meine Komponente mehr Abhängigkeiten hat? Ich dachte, dass ich nur die Abhängigkeiten in package.json definiert haben musste.

Edit3:

ich schließlich erkannte, dass ich nicht browserify brauchen, nur gulp-babel:

var gulp = require('gulp'); 
var babel = require('gulp-babel'); 

gulp.task('bundle', bundle); 

function bundle() { 
    gulp.src('./src/*.js') 
    .pipe(babel()) 
    .pipe(gulp.dest('./dist')); 
} 

gulp.task('build', ['bundle']); 

Und das ist alles. Das vollständige Beispiel ist hier: react-svg-components.

+0

Was ist Ihre Frage? – JMM

+1

@JMM Wenn ich versuche, die Komponente aus einer reaktiven App zu verwenden, gibt gulp den Fehler 'Fehler: Modul nicht gefunden'./EmptyFunction''. – Manolo

+0

Der Fehler ist zur Kompilierzeit oder zur Laufzeit? Sie erhalten eine einzige Datei 'dist/bundle.js', richtig? Alle Abhängigkeiten sollten in diesem Paket enthalten sein. Also sollten die 'require()' Aufrufe, die Sie hervorheben, zu etwas im Bundle aufgelöst werden. – JMM

Antwort

2

Basierend auf Ihrer letzten Erklärung, müssen Sie wahrscheinlich so etwas tun, wenn Ihre Komponente browserifying:

browserify('./src/Foo.js') 
// Note this call: 
.external("react") 
.transform(babelify) 
.bundle() 

Das Problem nichts mit Schluck zu tun hat. Ich weiß auch nicht, wie/wann Sie den Laufzeitfehler erhalten haben, den Sie in den Kommentaren beschrieben haben.Basierend auf Ihren neuesten Informationen besteht das Problem darin, dass Sie das Paket A mit browserify erstellen, dann das Paket B mit browserify erstellen, mit A in seinem Abhängigkeitsdiagramm, und browserify versucht, die relativen require()s aufzulösen, die bereits in A gebündelt sind. Zitiert aus this answer, wie er damit umgehen:

Hier sind ein paar Optionen:

  • Run derequire auf Bündel A vor dem Genuss/Publishing.

  • Versuchen Sie, Ihre App browserifying wie so:

    browserify({ 
        entries: ['./entry'], 
        noParse: ['my-components-in-node-modules'], 
    }) 
    

    Wenn es nicht funktioniert, versuchen Sie einen absoluten Pfad (require.resolve('my-components-in-node-modules')).

  • Reduzieren Sie das Bündel A, bevor Sie es verbrauchen.

Eine ausführlichere Erläuterung dieser Frage kann in substack/node-browserify#1151 finden.

Ich bin nicht sicher, Bündelung Reagieren mit Ihrer Komponente ist der Weg zu gehen. Ich bin mir nicht sicher, aber ich denke in diesem Fall müssen die Leute auf React reagieren (implizit oder explizit). Das Einschließen von React in das Bundle bedeutet, dass verschiedene Komponenten versuchen, verschiedene Instanzen von React zu verwenden, was zu Problemen führen kann, und das Verzeichnis node_modules für jede Komponente, die das tut, auf jeden Fall aufblähen würde.

+1

Danke für die Antwort, aber ich bin mir nicht sicher, ob das für meinen Fall sinnvoll ist. Meine Komponente ist wie die Ausgabe der ersten Frage (ein bisschen mehr ...). Ich brauche nur Reagieren um meine Komponente zu definieren. Jeder, der diese Komponente installieren und verwenden möchte, muss React installiert haben, sodass die Komponente dieselbe Reaction-Instanz verwendet wie die App, die diese Komponente verwendet. Ich habe Probleme, mich klar zu machen: P Ich habe versucht, was du gesagt hast, aber nicht funktioniert, der Verlust ändert nichts, weder die zweite Option, und der letzte wirft mir einen Fehler (mit hässlich): 'TypeError: file.isNull ist keine Funktion'. – Manolo

+0

Ich aktualisierte die Antwort mit einem neuen Vorschlag. Es ist jedoch schwierig zu verstehen, was Sie tun. – JMM

+0

Nun, ich habe es geschafft, es mit einem kleinen Hack arbeiten zu lassen. Ich habe meine Änderungen auf Github übertragen, da sie bereits verwendet werden können. Dies ist das Repo: https://github.com/msalsas/react-svg.Ich möchte auch alle Komponenten von 'src/react-svg.js' exportieren, aber das ist eine andere Geschichte. Der Hack besteht aus run gulp ohne die erforderlichen Methoden und fügt sie dann manuell zu 'build.js' hinzu. Entferne auch die erste und letzte Zeile (es wird in 'gulpfile.js' erklärt). Danke für deine großartige Hilfe :) – Manolo

Verwandte Themen