2016-07-26 9 views
1

Ich habe ein Problem, dass jedes Mal, wenn ich meinen Code js ändern, ich meinen Browser drei oder vier Mal neu laden muss, um den Cache zu löschen. Es ist also schmerzhaft.Versionierung Bundle-Datei

Ich bin auf der Suche nach einer Lösung wie Versionierung der Bundle.js, die von Schluck erzeugt wird. Jedes Mal, wenn mein Code geändert wird, muss ich eine Bundle-Datei mit einer Zufallszahl wie bundle-1287138.js erstellen und das Skript-Tag in meinem index.html muss automatisch aktualisiert werden.

<script src = "/dist/bundle-1287138.js"></script> 

Wie könnte ich tun?

Der folgende Code ist mein gulpfile.js jetzt:

var gulp  = require('gulp'); 
var fs   = require("fs"); 
var browserify = require("browserify"); 
var babelify = require("babelify"); 
var source  = require('vinyl-source-stream'); 
var gutil  = require('gulp-util'); 

gulp.task('es6', function() { 
    browserify({ debug: true }) 
     .transform(babelify) 
     .require("./main.js", { entry: true }) 
     .bundle() 
     .on('error',gutil.log) 
     .pipe(source('./dist/bundle.js')) 
     .pipe(gulp.dest('./')); 
}); 

gulp.task('watch',function() { 
    gulp.watch(['app.jsx', 'main.js', './components/**/*.jsx'], ['es6']) 
}); 

gulp.task('default', ['es6','watch']); 

Thank you!

UPDATE

Wie MadScone sagen, ich benutze BrowserSync und es funktioniert super. Nur ein Problem, es hat eine Verzögerung (8 - 9 Sekunden) nach dem Speichern.

Dies ist meine Ordnerstruktur:

- api 
- frontend 
    - gulpfile.js 
- index.js 

In index.js, ich benutze BrowserSync:

var express  = require('express'); 
var app   = express(); 
var browserSync = require('browser-sync'); 

var bs   = browserSync({ logSnippet: false }); 
bs.watch("frontend/dist/bundle.js", function() { 
    var curr = new Date(); 
    console.log("changed " + curr.getHours() + ":" + curr.getMinutes() + ":" + curr.getSeconds()); 
    bs.reload(); 
}); 

app.use(require('connect-browser-sync')(bs)); 
app.use('/', express.static(path.join(__dirname, 'frontend'))); 

var server = app.listen(3000, function() { 
    console.log('Server running at http://127.0.0.1:3000/'); 
}); 

Und in gulpfile.js, ich schluck bin mit bauen mein bundle.js:

var gulp  = require('gulp'); 
var fs   = require("fs"); 
var browserify = require("browserify"); 
var babelify = require("babelify"); 
var source  = require('vinyl-source-stream'); 
var gutil  = require('gulp-util'); 

gulp.task('es6', function() { 
    browserify({ debug: true }) 
     .transform(babelify) 
     .require("./main.js", { entry: true }) 
     .bundle() 
     .on('error',gutil.log) 
     .pipe(source('./dist/bundle.js')) 
     .pipe(gulp.dest('./')); 
}); 

gulp.task('watch',function() { 
    gulp.watch(['app.jsx', 'main.js', './components/**/*.jsx'], ['es6']) 
}); 

gulp.task('default', ['es6', 'watch']); 

Wenn ich meinen Code ändern und speichern, regeneriert die schluck es6 Aufgabe die bundle.js und die folgende Protokoll machen:

[23:49:54] Starting 'es6'... 
[23:49:54] Finished 'es6' after 6 ms 

Da die bundle.js Datei geändert wird, so BrowserSync macht seinen arbeiten, aber 5 Sekunden später ...

changed 23:49:59 
[BS] Reloading Browsers... 

Könnten Sie bitte erklären, warum es richtig nachladen nicht nach der es6 Aufgabe.

Vielen Dank!

Antwort

2

Wenn Sie Ihren Browser jedes Mal neu laden möchten, wenn sich Ihr Bundle ändert, sollten Sie wirklich in Browsersync schauen, was eine viel bessere Möglichkeit ist, dies zu tun. Es gibt jedoch eine Lösung, wenn Sie aus irgendeinem Grund Browsersync nicht verwenden möchten.

Sie können etwas wie node-randomstring verwenden, um den Dateinamen zu generieren (oder es gibt viele andere Möglichkeiten, dies zu tun) und dann gulp-inject verwenden, um das Bundle in Ihr HTML zu injizieren.

Führen Sie die Aufgabe inject aus, um die gewünschte Ausgabe zu erstellen.

var gulp   = require('gulp'); 
var fs   = require('fs'); 
var browserify = require('browserify'); 
var babelify  = require('babelify'); 
var source  = require('vinyl-source-stream'); 
var gutil  = require('gulp-util'); 
var path   = require('path'); 
var inject  = require('gulp-inject'); 
var del   = require('del'); 
var randomString = require('randomstring'); 

var BUILD_DIRECTORY = 'dist'; 

gulp.task('es6', function() { 

    // Create random file name. 
    var hash = randomString.generate(8); 
    var name = path.join(BUILD_DIRECTORY, 'bundle-' + hash + '.js'); 

    return browserify({ debug: true }) 
     .transform(babelify) 
     .require('./main.js', { entry: true }) 
     .bundle() 
     .on('error',gutil.log) 
     .pipe(source(name)) 
     .pipe(gulp.dest('./')); 

}); 

// Inject bundle into HTML. 
gulp.task('inject', ['clean', 'es6'], function() { 

    const target = gulp.src('index.html'); 
    const sources = gulp.src(path.join(BUILD_DIRECTORY, '*.js'), {read: false}); 
    return target.pipe(inject(sources)) 
     .pipe(gulp.dest(BUILD_DIRECTORY)); 

}); 

// Delete the old bundle. 
gulp.task('clean', function() { 
    return del(path.join(BUILD_DIRECTORY, 'bundle*.js')); 
}); 

Eine neue Bundle-Datei wird jedes Mal, wenn Sie inject laufen erstellt. Die Task clean löscht alle alten Bundle-Dateien, sonst werden Sie viele davon erhalten.

Beachten Sie, dass Ihre index.html und main.js im Stammverzeichnis Ihres Verzeichnisses sind.

bearbeiten

Leider vergaßen die HTML:

<!DOCTYPE html> 
<html lang="en"> 
<head> 
    <meta charset="UTF-8"> 
    <title>Title</title> 
</head> 
<body> 

    <!-- inject:js --> 
    <!-- endinject --> 
</body> 
</html> 

Edit 2

Sie Browsersync in Ihrer schluck Datei einrichten sollte. Auf diese Weise können Sie Browsersync genau mitteilen, wenn sich etwas geändert hat, anstatt es dort warten zu lassen.

gulp.task('serve', ['inject'], function() { 

    // Start browser sync after "inject" has finished. 
    browserSync.init({ 
     server: { 
      baseDir: './dist' 
     } 
    }); 

    // When the watch is triggered, call "reload". That will call "inject" and then let 
    // Browsersync know a change has occurred. 
    gulp.watch('*.js', ['reload']); 

}); 

gulp.task('reload', ['inject'], function() { 
    browserSync.reload(); 
}); 

Die serve Aufgabe jetzt alle Ihre JavaScript kompiliert, beginnt Browsersync und beginnt für JavaScript-Datei Änderungen zu beobachten (Beispiel oben nur das Root-Verzeichnis Uhren, müssen Sie wahrscheinlich, dass ändern Sie Ihr Projekt entsprechen). Sobald gulp.watch() eine Änderung sieht, ruft es die reload Aufgabe auf, die die inject Aufgabe aufruft und dann Browsersync neu lädt.

reload tut nicht viel selbst, aber beachten Sie, dass es zuerst inject ruft. Daher wird gewartet, bis diese Aufgabe abgeschlossen ist, bevor Browsersync erneut geladen wird.

+0

Ich benutze BrowserSync, du hast Recht, es ist besser. Aber es hat ein Problem und ich weiß nicht warum. Könnten Sie sich bitte mein Update ansehen? Danke –

+0

@TrongLamPhan Ich habe meine Antwort bearbeitet. Ich bin mir nicht ganz sicher, ob Sie die 'inject' Aufgabe noch brauchen, also möchten Sie vielleicht Ihre' es6' Aufgabe jetzt anstelle von 'inject' aufrufen, nachdem' gulp.watch() 'ausgelöst wurde. Aber hoffentlich bekommst du die Idee von meiner Antwort trotzdem. – MadScone