2015-07-25 7 views
10

TLDR: Sono in grado di require di tutto per rendere la corsa app, ma se mi require moduli dall'interno di un test (che è in app - vedere la struttura dir di seguito) file, l'intera catena di dipendenze si rompe.creare un punto di ingresso di prova a reagire webpack applicazione

sto avendo qualche difficoltà require -ing componenti dalla mia directory app/test (nel mio webpack applicazione React.js) al di sotto che non ho difficoltà a require -ing da qualsiasi altro file nella cartella /app. Questa è la struttura di directory

app 
    /components/checkout.jsx 
    /components/button.jsx 
    /test/test.js 
    index.jsx 
dist 
node_modules 
webpack.config.js 
package.json 

nei miei webpack.config.js, ce l'ho messa a punto di utilizzare la JSX-loader per la mia applicazione Reagire come questo

entry: { 
    app: "./app/index" 
}, 
module: { 
    loaders: [ 
     { 
      test: /\.jsx$/, 
      loader: 'jsx-loader?insertPragma=React.DOM&harmony', 
    } 
    ] 
}, 
resolve: { 
extensions: ['', '.js', '.jsx'] 
} 

Questo mi permette di richiedere i file con estensione in estensione .jsx. Per esempio, in /app/index.jsx richiedo /app/components/checkout.jsx facendo

var Checkout = require('./components/Checkout') 

E dentro /app/components/checkout.jsx, richiedo il pulsante

var Button = require('./components/Button') 

così quando richiedo il Checkout dalla index.jsx, gestisce l'richiedono del Pulsante senza alcun problema.

Tuttavia, dalle app/test/test.js, faccio

var Checkout = require('../components/Checkout') 

e webpack non riesco a trovare il componente di Checkout. Quando visualizzo i test nel server di sviluppo webpack, non viene mostrato che l'estensione del file .jsx è stata cercata. Si cercato

app/components/Checkout 
app/components/Checkout.webpack.js 
app/components/Checkout.web.js 
app/components/Checkout.js 
app/components/Checkout.json 

Pertanto, ho cercato di usare il jsx-loader inline come questo

var Checkout = require(jsx-loader!'../components/Checkout') 

dalla directory di prova, e webpack può ora trovare il file, ma genera un errore dicendo che non può risolvere il pulsante che controlla requires. In altre parole, quando utilizzo lo require dalla cartella app/test, l'intera catena di dipendenze viene espulsa dalla sincronizzazione.

Come posso modificare il mio webpack.config.js per poter richiedere i file dell'applicazione nei miei test con questa struttura di directory o, più in generale, come configurare il webpack per richiedere un file dell'applicazione in un test?

Aggiornamento

Struttura del progetto

/app 
    /test/test.js 
    /index.jsx 
    /components/checkout.jsx (and button.jsx) 
/dist 
/node_modules 
package.json 
webpack.config.js 

tutta webpack config

var webpack = require('webpack'); 
module.exports = { 
    context: __dirname + "/app", 
    entry: { 
     vendors: ["d3", "jquery"], 
     app: "index" 
     // app: "./app/index" 

     }, 
    output: { 
     path: './dist', 
     filename: 'bundle.js', //this is the default name, so you can skip it 
     //at this directory our bundle file will be available 
     //make sure port 8090 is used when launching webpack-dev-server 
     publicPath: 'http://localhost:8090/assets/' 
    }, 

    externals: { 
     //don't bundle the 'react' npm package with our bundle.js 
     //but get it from a global 'React' variable 

     'react': 'React' 
     // 'd3': 'd3' 
    }, 
    resolve: { 
     modulesDirectories: ['app', 'node_modules'], 
     extensions: ['', '.js', '.jsx'], 
     resolveLoader: { fallback: __dirname + "/node_modules" }, 
     root: ['/app', '/test'] 
    }, 
    module: { 
     loaders: [ 
      { 
       test: /\.jsx$/, 
       loader: 'jsx-loader?insertPragma=React.DOM&harmony', 
      } 
     ] 
    }, 

    plugins: [ 
    // definePlugin, 
    new webpack.optimize.CommonsChunkPlugin('vendors', 'vendors.js') 

    ] 
} 
+0

come è stata configurata la configurazione di webpack per eseguire i test, è la stessa o separata dalla principale? nel mio setup sto usando 2 diverse configurazioni per eseguire build di sviluppatori e test di reazione. La soluzione per il problema simile era di aggiungere la risoluzione: {extensions: ['', '.js', '.jsx']} nel webpack per eseguire test. –

+0

@EugeneSafronov in questo momento ho solo una configurazione webpack al livello più alto del progetto. Ne ho messo una copia nella sezione di aggiornamento dell'OP, oltre a maggiori dettagli sulla struttura del progetto. Ho pensato di usare una seconda configurazione per i test, ma non sapevo dove metterla o come configurarla. Puoi fornire alcune informazioni a riguardo? – Leahcim

+0

non ti manca 'include: __dirname' nei tuoi caricatori? prova anche: '/ \. jsx? $ /' – knowbody

risposta

3

Una possibile soluzione potrebbe essere quella di sempre richiedere con estensione file:

var Checkout = require('./components/Checkout.jsx') 
+0

che mi permette di richiedere quel componente in particolare, ma quando eseguo il test dice che quei token JSX, (cioè il '<') sono ' inaspettato '. l'app funziona ancora correttamente, solo il problema con il test. Come dichiaro nell'OP ', quando uso il fabbisogno dall'interno della cartella app/test, l'intera catena di dipendenze non viene sincronizzata. Nell'OP', quindi penso che il problema sia in qualche modo correlato al mio webpack.config file .js, bit rilevanti dei quali mostro nell'OP – Leahcim

3

Immagino che potrebbe essere l'impostazione di "test" come directory principale. Ma non è chiaro fino a quando non condividi il tuo codice. Puoi darmi un link al repository GitHub o qualcosa del genere?

+0

il punto di ingresso del test è stato rimosso (vedi l'aggiornamento all'OP). Il progetto non è in github. – Leahcim

+0

Sto parlando di questo: root: ['/ app', '/ test'], è ancora presente nella configurazione del webpack – gyzerok

3

vedo che stai usando il parametro harmony, posso presumere che stai usando, es6?

Se ho avuto questo problema in precedenza, il problema per me era che i file venivano aggiunti, come es6 senza essere trasformati, in es5 da jsx-loader/babel-loader.

quindi avevo bisogno di aggiungere:

preLoaders: [{ 
    test: [/\.jsx$/, /\.js$/], 
    include: // modules here 
    loaders: ['babel-loader?optional[]=runtime'] 
}] 

ma poi non spiegherebbe il motivo per cui questo viene a mancare solo per i test. forse puoi approfondire ciò che viene eseguito quando esegui i tuoi test ma per ora sono ancora sotto l'assunzione di te usando es6,

se la situazione di cui sopra non è il tuo caso, prova ad installare una versione locale di webpack, e cercarlo nella vostra dir locali, anche per la cartella app

(resolveLoader: { root: path.join(__dirname, "node_modules") }) 

speranza che questo aiuta

edit: ps guardando la vostra configurazione, resolveLoader non dovrebbe essere una parte della vostra volontà, in un altro di impostazione webpack Io uso, ho il seguente setup per la risoluzione:

resolve: { 
    extensions: ['', '.js', '.jsx', '.json'], 
    modulesDirectories: ['node_modules', 'node_modules/vl_tooling/node_modules'] 
}, 
resolveLoader: { 
    modulesDirectories: ['node_modules', 'node_modules/vl_tooling/node_modules'] 
}, 
+0

Sto usando jsx ma non es6. Alla fine della tua risposta, metti 'modulesDirectories 'in' resolve 'e' resolveLoader '. Dovrebbe essere in entrambi? – Leahcim

1

ho configurato compito sorso separata per eseguire test Reagire, forse si potrebbe riutilizzare l'idea:

karma.js file di

var karma = require('gulp-karma'), 
    _ = require('lodash'), 
    Promise = require('bluebird'), 
    plumber = require('gulp-plumber'), 
    path = require('path'), 
    webpack = require('gulp-webpack'), 
    named = require('vinyl-named'); 

module.exports = function (gulp, options) { 
    var root = path.join(options.cwd, 'app'), 
    extensions = ['', '.js', '.jsx'], 
    modulesDirectories = ['node_modules']; 

    gulp.task('karma', ['karma:build'], function() { 
    return runAllTests(gulp, options); 
    }); 

    gulp.task('karma:build', function() { 
    var optionsForTests = _.merge({ 
     ignore: ['**/node_modules/**'] 
    }, options); 

    return gulp.src(['**/__tests__/*.js'], optionsForTests). 
     pipe(named(function(file){ 
     // name file bundle.js 
     return 'bundle'; 
     })). 
     pipe(webpack({ 
     module: { 
      loaders: [ 
       // runtime option adds Object.assign support 
       { test: /\.(js|jsx)$/, loader: 'babel-loader?optional[]=runtime', exclude: /node_modules/}, 
       { test: /\.(sass|scss)$/, loader: 'css-loader!sass-loader'}, 
       { test: /\.(png|jpg|jpeg|gif|svg|woff|woff2)$/, loader: 'url-loader'}, 
       { test: /\.(ttf|eot)$/, loader: 'file-loader'}, 
       { test: /sinon.*\.js$/, loader: 'imports?define=>false' } // hack due to https://github.com/webpack/webpack/issues/304 
      ] 
     }, 
     resolve: { 
      root: root, 
      extensions: extensions, 
      modulesDirectories: modulesDirectories 
     } 
     })). 
     pipe(gulp.dest('test-build')); 
    }) 

} 

function runAllTests(gulp, options) { 
    var optionsForTests = _.merge({ 
    ignore: ['**/node_modules/**'] 
    }, options); 

    return new Promise(function (resolve, reject) { 
    var karmaConfig = path.join(path.resolve(__dirname, '..'), 'karma.conf.js'); 

    // shim Prototype.function.bind in PhantomJS 1.x 
    var testFiles = [ 
     'node_modules/es5-shim/es5-shim.min.js', 
     'node_modules/es5-shim/es5-sham.min.js', 
     'test-build/bundle.js']; 

    gulp.src(testFiles). 
     pipe(plumber({ 
     errorHandler: function (error) { 
      console.log(error); 
      this.emit('end'); 
     } 
     })). 
     pipe(karma({ 
     configFile: karmaConfig, 
     action: 'run' 
     })). 
     on('end', function() { resolve(); }); 
    }); 
} 

Gulp:

var gulp = require('gulp'); 
var auctionataBuild = require('auctionata-build'); 
var path = require('path'); 

auctionataBuild.tasks.karma(gulp, { 
    cwd: path.resolve(__dirname) 
}); 

Run dal terminale :

gulp karma 
Problemi correlati