语境
我有一个gulpfile.js
. 它基本上将两个带有 js 文件的文件夹连接到两个文件以导出到 dist 文件夹。它还添加了一个缓存破坏器和一个用于生产的丑陋版本。
//gulpfile.js
const gulp = require('gulp');
const sass = require('gulp-sass');
const concat = require('gulp-concat');
const rename = require('gulp-rename');
const maps = require('gulp-sourcemaps');
const uglify = require('gulp-uglify');
const gulpif = require('gulp-if');
const inlineCss = require('gulp-inline-css');
const jsValidate = require('gulp-jsvalidate');
const notify = require('gulp-notify');
const rev = require('gulp-rev');
const fs = require("fs");
const del = require('del');
const distFolder = './myapp/dist/';
/* Concat all scripts and add cache buster */
gulp.task('app_concatScripts', (done) => {
/*first remove old app.js files */
return del([distFolder + "app-*.{js,map}"])
.then(paths => {
/*Concat files with sourcemaps, hash them and write to manifest*/
return gulp.src("./myapp/js/source-app/*.js")
.pipe(maps.init())
.pipe(concat({
path: "app.js",
cwd: '',
newLine: '; \n'
}))
.pipe(gulp.dest(distFolder))
.pipe(rev())
.pipe(maps.write('./'))
.pipe(gulp.dest(distFolder))
.pipe(rev.manifest(distFolder + 'rev-manifest.json', {
base: distFolder,
merge: true
}))
.pipe(gulp.dest(distFolder));
});
});
/* Minify scripts and add cache buster */
gulp.task('app_minifyScripts', (done) => {
return gulp.src(distFolder + "app.js", {
allowEmpty: true
})
.pipe(uglify())
.on('error', notify.onError((error) => {
console.log(error);
return error.message + ' in ' + error.fileName;
}))
.pipe(rename("app.min.js"))
.pipe(rev())
.pipe(gulp.dest(distFolder))
.pipe(rev.manifest(distFolder + 'rev-manifest.json', {
base: distFolder,
merge: true
}))
.pipe(gulp.dest(distFolder));
});
/* Concat all scripts and add cache buster, this function is exactly the same as app_concatScripts */
gulp.task('main_concatScripts', (done) => {
/*Concat files with sourcemaps, hash them and write to manifest*/
return del(["./myapp/dist/main-*.{js,map}"])
.then(paths => {
return gulp.src("./myapp/js/source-main/*.js")
.pipe(maps.init())
.pipe(concat({
path: "main.js",
cwd: '',
newLine: '; \n'
}))
.pipe(gulp.dest(distFolder))
.pipe(rev())
.pipe(maps.write('./'))
.pipe(gulp.dest(distFolder))
.pipe(rev.manifest(distFolder + 'rev-manifest.json', {
base: distFolder,
merge: true
}))
.pipe(gulp.dest(distFolder));
});
});
/* Minify scripts and add cache buster, this function is the same as app_minifyScripts */
gulp.task('main_minifyScripts', (done) => {
return gulp.src("./myapp/dist/main.js")
.pipe(uglify())
.on('error', notify.onError((error) => {
console.log(error);
return error.message + ' in ' + error.fileName;
}))
.pipe(rename("main.min.js"))
.pipe(rev())
.pipe(gulp.dest(distFolder))
.pipe(rev.manifest(distFolder + 'rev-manifest.json', {
base: distFolder,
merge: true
}))
.pipe(gulp.dest(distFolder));
});
/* watch task */
gulp.task('watch', (done) => {
gulp.watch('./myapp/js/source-app/*.js', gulp.series('app_concatScripts', 'app_minifyScripts'));
gulp.watch('./myapp/js/source-main/*.js', gulp.series('main_concatScripts', 'main_minifyScripts'));
done();
});
gulp.task('default', gulp.series('main_concatScripts', 'main_minifyScripts', 'app_concatScripts', 'app_minifyScripts', 'watch'));
输出
gulpfile.js
作品。它构建了一个rev-manifest.json
这样的:
{
"app.js": "app-234318a58d.js",
"app.min.js": "app-7788fee7f3.min.js",
"main.js": "main-60788c863c.js",
"main.min.js": "main-1e92517890.min.js",
"style.css": "style-296f22c598.css",
"admin.css": "admin-a3742ed2f6.css",
}
问题
为了让它工作,我为每个 js 文件复制了_concatScripts
and任务:和. 使 gulpfile 不必要的大且难以维护。_minifyScripts
app.js
main.js
我试过的
我尝试使用数组来定义脚本源文件和输出名称。这不起作用,因为循环块中的代码不会等待前一个块准备好。因此,缩小任务有时会失败,因为原始 js 文件尚不存在,有时rev-manifest.json
会被先前的代码块覆盖。所以它不再是一个真正的 gulp 系列了。做这样的事情的最佳做法是什么?
const scripts = [{
name: 'app',
source: './myapp/js/source-app/*.js'
}, {
name: 'main',
source: './myapp/js/source-main/*.js'
}];
/* Concat all scripts and add cache buster */
gulp.task('concatScripts', (done) => {
for (var i = 0; i < scripts.length; i++) {
var script = scripts[i];
del([distFolder + script.name + "-*.{js,map}"])
.then(paths => {
/*Concat files with sourcemaps, hash them and write to manifest*/
gulp.src(script.source)
.pipe(maps.init())
.pipe(concat({
path: script.name + ".js",
cwd: '',
newLine: '; \n'
}))
.pipe(gulp.dest(distFolder))
.pipe(rev())
.pipe(maps.write('./'))
.pipe(gulp.dest(distFolder))
.pipe(rev.manifest(distFolder + 'rev-manifest.json', {
base: distFolder,
merge: true
}))
.pipe(gulp.dest(distFolder));
});
}
});
/* Minify scripts and add cache buster */
gulp.task('minifyScripts', (done) => {
for (var i = 0; i < scripts.length; i++) {
var script = scripts[i];
gulp.src(distFolder + script.name + ".js", {
allowEmpty: true
})
.pipe(uglify())
.on('error', notify.onError((error) => {
console.log(error);
return error.message + ' in ' + error.fileName;
}))
.pipe(rename(script.name + ".min.js"))
.pipe(rev())
.pipe(gulp.dest(distFolder))
.pipe(rev.manifest(distFolder + 'rev-manifest.json', {
base: distFolder,
merge: true
}))
.pipe(gulp.dest(distFolder));
}
});
/* watch task */
gulp.task('watch', (done) => {
gulp.watch(['./myapp/js/source-app/*.js', './myapp/js/source-main/*.js'], gulp.series('concatScripts', 'minifyScripts'));
done();
});
gulp.task('default', gulp.series('concatScripts', 'minifyScripts', 'watch'));
更新
我的 gulp 文件现在看起来像这样:
//gulpfile.js
const gulp = require('gulp');
const sass = require('gulp-sass');
const concat = require('gulp-concat');
const rename = require('gulp-rename');
const maps = require('gulp-sourcemaps');
const uglify = require('gulp-uglify');
const gulpif = require('gulp-if');
const inlineCss = require('gulp-inline-css');
const jsValidate = require('gulp-jsvalidate');
const notify = require('gulp-notify');
const rev = require('gulp-rev');
const fs = require("fs");
const del = require('del');
/* Concat all scripts and add cache buster */
const distFolder = './myapp/dist/';
function concatTask(opts) {
const taskName = opts.name + '_concatScripts';
gulp.task(taskName, (done) => {
/*Concat files with sourcemaps, hash them and write to manifest*/
return del(opts.del)
.then(paths => {
return gulp.src(opts.source)
.pipe(maps.init())
.pipe(concat({
'path': opts.name + '.js',
'cwd': '',
'newLine': '; \n'
}))
.pipe(gulp.dest(distFolder))
.pipe(rev())
.pipe(maps.write('./'))
.pipe(gulp.dest(distFolder))
.pipe(rev.manifest(distFolder + 'rev-manifest.json', {
'base': distFolder,
'merge': true
}))
.pipe(gulp.dest(distFolder));
});
});
return taskName;
}
function minifyTask(opts) {
const taskName = opts.name + '_minifyScripts';
gulp.task(taskName, (done) => {
return gulp.src(distFolder + opts.name + '.js', opts.sourceParams)
.pipe(uglify())
.on('error', notify.onError((error) => {
console.log(error);
return error.message + ' in ' + error.fileName;
}))
.pipe(rename(opts.name + '.min.js'))
.pipe(rev())
.pipe(gulp.dest(distFolder))
.pipe(rev.manifest(distFolder + 'rev-manifest.json', {
'base': distFolder,
'merge': true
}))
.pipe(gulp.dest(distFolder));
});
return taskName;
}
const taskOptions = [{
'name': 'main',
'source': './myapp/js/source-main/*.js',
'sourceParams': {
'allowEmpty': false
},
'del': ['./myapp/dist/main-*.{js,map}']
}, {
'name': 'app',
'source': './myapp/js/source-app/*.js',
'sourceParams': {
'allowEmpty': false
},
'del': ['./myapp/dist/app-*.{js,map}']
},
];
const taskNames = taskOptions.map(opts => {
return [concatTask(opts), minifyTask(opts)];
});
/* equivalent to defining tasks and assigning:
* var taskNames = [
* ['main_concatScripts', 'main_minifyScripts'],
* ['app_concatScripts', 'app_minifyScripts']
* ];
*/
gulp.task('watch', (done) => {
taskOptions.forEach((opts, i) => {
gulp.watch(opts.source, gulp.series.apply(gulp, taskNames[i]));
});
done();
});
/* equivalent to:
* gulp.task('watch', (done) => {
* gulp.watch('./myapp/js/source-main/*.js', gulp.series('main_concatScripts', 'main_minifyScripts'));
* gulp.watch('./myapp/js/source-app/*.js', gulp.series('app_concatScripts', 'app_minifyScripts'));
* done();
* });
*/
const allTaskNames = taskNames.reduce((arr, names) => arr.concat(names), []); // flatmap the task names into a single array
// console.log(allTaskNames.concat(['watch']));
/* equivalent to:
* let allTaskNames = ['main_concatScripts', 'main_minifyScripts', 'app_concatScripts', 'app_minifyScripts'];
*/
gulp.task('default', gulp.series.apply(gulp, allTaskNames.concat(['styles', 'watch'])));
/* equivalent to:
* gulp.task('default', gulp.series('main_concatScripts', 'main_minifyScripts', 'app_concatScripts', 'app_minifyScripts', 'watch'));
*/
动态任务创建者工作。不幸的是,缩小任务在连接任务完成之前就开始了。我收到以下错误,添加 allowEmpty 选项确实有效,但随后错误的连接文件被缩小:
[12:57:19] Using gulpfile /repo/myapp/gulpfile.js
[12:57:19] Starting 'default'...
[12:57:19] Starting 'main_concatScripts'...
[12:57:19] Finished 'main_concatScripts' after 47 ms
[12:57:19] Starting 'main_minifyScripts'...
[12:57:19] 'main_minifyScripts' errored after 11 ms
[12:57:19] Error: File not found with singular glob: /repo/myapp/dist/main.js (if this was purposeful, use `allowEmpty` option)