2016-07-26 472 views
1

我有一個問題,每次我修改我的代碼js時,我必須重新加載我的瀏覽器三次或四次以清除緩存。所以這很痛苦。版本控制軟件包文件

我正在尋找一個解決方案,如版本控制由吞噬生成的bundle.js。每次我的代碼被修改時,我需要創建一個包含bundle-1287138.js的隨機數的包文件,並且我的index.html中的腳本標記需要自動更新。

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

我該怎麼辦?

下面的代碼是我現在gulpfile.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']); 

謝謝!

UPDATE

由於MadScone說,我用BrowserSync和它的偉大工程。只有一個問題,它在保存後有延遲(8 - 9秒)。

這是我的文件夾結構:

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

index.js,我使用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/'); 
}); 

而且在gulpfile.js,我使用一飲而盡建設我的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']); 

當我修改並保存我的代碼,吞氣ES6任務再生bundle.js並進行以下日誌:

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

因爲bundle.js文件被修改,所以BrowserSync使得其工作但在5秒鐘後...

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

能否請您解釋爲什麼它的ES6任務之後沒有重新加載。

謝謝!

回答

2

如果你想在每次你的軟件包改變時重新載入你的瀏覽器,你應該看看Browsersync,這是一個更好的方法。但是,如果您出於某種原因不想使用Browsersync,以下有一個解決方案。

您可以使用類似於node-randomstring的東西來生成文件名(或者有很多其他方法可以做到這一點),然後使用gulp-inject將該包注入到HTML中。

運行任務inject以產生所需的輸出。

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')); 
}); 

一個新的軟件包文件被創建每次運行inject時間。 clean任務刪除任何舊的捆綁包文件,否則最終會加載它們。

請注意,我假定您的index.htmlmain.js位於您的目錄的根目錄。

編輯

對不起忘了HTML:

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

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

編輯2

您應該建立Browsersync在你一飲而盡文件。這樣,當事情發生變化時,你可以準確地告訴Browsersync,而不是讓它在那裏等待。

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(); 
}); 

serve現在的任務編譯所有你的JavaScript,開始Browsersync並開始留意JavaScript文件的更改(例如上面只是手錶的根目錄下,你可能將不得不改變,以適應您的項目)。一旦gulp.watch()看到更改,它將調用reload任務,該任務調用inject任務,然後重新加載Browsersync。

reload自己做的不多,但是請注意,它首先調用inject。因此,它會在重新加載Browsersync之前等待該任務完成。

+0

我使用BrowserSync,你是對的,它更好。但它有一個問題,我不知道爲什麼。你能看看我的更新嗎?謝謝 –

+0

@TrongLamPhan我編輯了我的答案。我不完全確定你是否仍然需要'inject'任務,所以你可能想在'gulp.watch()'被觸發之後立即調用你的'es6'任務而不是'inject'。但希望你能從我的答案中得到想法。 – MadScone