2015-06-18 4 views
10

sono riuscito a realizzare il mio compito utilizzando un plugin chiamato sorso gulp-insert come questo:Come posso inserire il contenuto in un file durante una generazione di gulp?

gulp.task('compile-js', function() { 
    // Minify and bundle client scripts. 
    var scripts = gulp.src([ 
    srcDir + '/routes/**/*.js', 
    srcDir + '/shared/js/**/*.js' 
    ]) 
    // Sort angular files so the module definition appears 
    // first in the bundle. 
    .pipe(gulpAngularFilesort()) 
    // Add angular dependency injection annotations before 
    // minifying the bundle. 
    .pipe(gulpNgAnnotate()) 
    // Begin building source maps for easy debugging of the 
    // bundled code. 
    .pipe(gulpSourcemaps.init()) 
    .pipe(gulpConcat('bundle.js')) 
    // Buffer the bundle.js file and replace the appConfig 
    // placeholder string with a stringified config object. 
    .pipe(gulpInsert.transform(function (contents) { 
     return contents.replace("'{{{appConfigObj}}}'", JSON.stringify(config)); 
    })) 
    .pipe(gulpUglify()) 
    // Finish off sourcemap tracking and write the map to the 
    // bottom of the bundle file. 
    .pipe(gulpSourcemaps.write()) 
    .pipe(gulp.dest(buildDir + '/shared/js')); 

    return scripts.pipe(gulpLivereload()); 
}); 

Quello che sto facendo è la lettura del file di configurazione della nostra applicazione che è gestito dal modulo config su NPM. Ottenere il nostro file di configurazione dal codice lato server è un gioco da ragazzi usando var config = require('config');, ma siamo un'app a pagina singola e spesso è necessario accedere alle impostazioni di configurazione sul lato client. Per fare ciò infilo l'oggetto config in un servizio angolare.

Ecco il servizio Angolare prima di gulp build.

angular.module('app') 
    .factory('appConfig', function() { 
    return '{{{appConfigObj}}}'; 
    }); 

Il segnaposto è in una stringa in modo che sia valida JavaScript per alcuni degli altri plug-gulp che elaborano prima il file. L'utilità gulpInsert mi consente di inserire la configurazione come questa.

.pipe(gulpInsert.transform(function (contents) { 
    return contents.replace("'{{{appConfigObj}}}'", JSON.stringify(config)); 
})) 

Questo funziona ma sembra un po 'hacky. Per non parlare del fatto che deve bufferizzare l'intero file in bundle solo così posso eseguire l'operazione. C'è un modo più elegante per realizzare la stessa cosa? Preferibilmente uno che consente al flusso di fluire senza intoppi senza dover tamponare l'intero fascio alla fine? Grazie!

+0

ho preso un po 'diverso approccio a questo. Ho creato un file json per env. dev.config.js, prod.config.js e durante gulp dev/prod build sostituisco my env.config.js con il file config.js appropriato e il mio index.html include env.config.js. Questo sembra un po 'più pulito di cercare e sostituire i file – harishr

+0

Ci scusiamo, ma qual è il problema dell'utilizzo dei buffer? Lo streaming è anche una sorta di buffering, ma con dimensioni più ridotte. Tuttavia, dubito fortemente che l'intero bundle.js superi anche 1 Mb, che oggi non è quasi nulla. Forse, non sei soddisfatto del tempo di esecuzione complessivo della tua build. In tal caso dovresti considerare l'uso della funzionalità di 'watch'. –

+0

È una grande app aziendale Dimitry. Non è ancora troppo grande, ma lo sarà sicuramente. Siamo andati con il gulp per i guadagni in termini di prestazioni che rendono i tempi di costruzione potenzialmente molto più brevi della stessa configurazione con grunt. Mi sto adoperando per fare le cose in modo corretto nelle prime fasi, al fine di radere ogni possibile secondo nel futuro. – Chev

risposta

5

Avete controllato gulp-replace-task?

Qualcosa di simile

[...] 
.pipe(gulpSourcemaps.init()) 
.pipe(replace({ 
    patterns: [{ 
    match: '{{{appConfigObj}}}', 
    replacement: config 
    }], 
    usePrefix: false 
}) 
.pipe(gulpUglify()) 
[...] 
+1

Bello! Sembra che [sostituisca mid-stream] (https://github.com/outaTiME/gulp-replace-task/blob/master/index.js#L26-L54) come desiderato invece di aspettare che tutto buffer alla fine. Bella scoperta: D – Chev

+0

questo modulo funziona alla grande! Molto potente con espressioni regolari + funzioni di sostituzione. – plong0

2

Certo, anche questo sembra un po 'hacky, ma forse leggermente migliore ... Sto usando envify e gulp-env in un progetto React. Potresti fare qualcosa di simile.

gulpfile.js:

var config = require('config'); 
var envify = require('envify'); 

gulp.task('env', function() { 
    env({ 
     vars: { 
      APP_CONFIG: JSON.stringify(config) 
     } 
    }); 
}); 

gulp.task('compile-js', ['env'], function() { 
    // ... replace `gulp-insert` with `envify` 
}); 

fabbrica:

angular.module('app') 
    .factory('appConfig', function() { 
    return process.env.APP_CONFIG; 
    }); 
+0

Envify conserva ancora l'intero file prima di eseguire la sostituzione? – Chev

+0

Onestamente, non lo so per certo. Direi "no" perché l'invidia sembra veloce nel mio progetto, ma sarebbe solo un'ipotesi. –

+0

Si finisce con una variabile che contiene tutto il contenuto del file come una stringa su cui si esegue il lavoro di sostituzione? Se lo fai, memorizza tutto il file in memoria.Anche il modo in cui lo sto facendo è veloce, è solo che voglio attenermi al paradigma del gulp streaming e sbarazzarmi di ogni nanosecondo che posso. Questo file diventerà sempre più grande col passare del tempo. – Chev