2016-07-26 3 views
1

У меня проблема: каждый раз, когда я изменяю свой код js, я должен перезагрузить мой браузер три или четыре раза, чтобы очистить кеш. Так что это больно.Файл с пакетом версий

Я ищу решение, такое как versioning bundle.js, которое генерируется gulp. Каждый раз, когда мой код изменяется, мне нужно создать файл пакета со случайным числом, например 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.html и main.js находятся в вашем каталоге.

Редактировать

К сожалению забыл HTML:

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

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

Edit 2

Вы должны установить 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, а затем перезагружает браузер.

reload не очень много, но обратите внимание, что он сначала называет inject. Поэтому он будет ждать завершения этой задачи, прежде чем перезагрузит Browsersync.

+0

Я использую BrowserSync, вы правы, это лучше. Но это проблема, и я не знаю, почему. Не могли бы вы посмотреть мое обновление? Спасибо –

+0

@TrongLamPhan Я отредактировал свой ответ. Я не совсем уверен, что вам все еще нужно задание 'inject', поэтому вы можете вместо этого выполнить вызов' es6' вместо 'inject' после запуска' gulp.watch() '. Но, надеюсь, вы получите идею от моего ответа в любом случае. – MadScone

Смежные вопросы