我想用Gulp编译JavaScript文件。
我有一个src
目录,其中所有脚本都带有.js
扩展名。我希望所有脚本都能单独编译并放入目标目录(dist
),文件名与原始目录相同。
考虑这个例子:
的src /的jquery.js :
/**
* @require ../../vendor/jquery/dist/jquery.js
*/
的src / application.js中:
/**
* @require ../../vendor/angular/angular.js
* @require ../../vendor/ngprogress-lite/ngprogress-lite.js
* @require ../../vendor/restangular/dist/restangular.js
* @require ../../vendor/lodash/dist/lodash.underscore.js
* @require ../../vendor/angular-input-locker/dist/angular-input-locker.js
* @require ../../vendor/angular-route/angular-route.js
*/
(function(document, angular) {
'use strict';
var moduleName = 'waApp';
angular.module(moduleName, [
// Some more code here.
;
// Bootstrapping application when DOM is ready.
angular.element(document).ready(function() {
angular.bootstrap(document, [moduleName]);
});
})(document, angular);
我正在使用gulp-resolve-dependencies来解析每个源JavaScript文件的标头中指定的依赖关系。
我的 gulpfile.js 看起来像这样:
//==============//
// Dependencies //
//==============//
var gulp = require('gulp');
var pathModule = require('path');
var resolveDependencies = require('gulp-resolve-dependencies');
var concat = require('gulp-concat');
var uglify = require('gulp-uglify');
//=======//
// TASKS //
//=======//
gulp.task('build:scripts', function(callback) {
return gulp.src('scripts/*.js')
.pipe(resolveDependencies({
pattern: /\* @require [\s-]*(.*?\.js)/g,
log: true
}))
.pipe(concat('all.js'))
.pipe(uglify())
.pipe(gulp.dest('js/'))
;
});
为了合并由resolveDependencies
解析的脚本,我必须使用concat
,但concat
需要一个文件名并且不仅合并原始文件和为其解析的依赖项,而且还合并所有JavaScript文件通过glob模式指定。
那么,如何将单个JavaScript文件作为输出?像这样:
dist/jquery.js:
src/jquery.js
vendor/jquery.js
dist/application.js:
src/application.js
vendor/angular.js
vendor/ngprogress-lite.js
...
我现在有这个解决方法:
gulp.task('build:scripts', function(callback) {
var compileScript = function(stream, filename) {
return stream
.pipe(resolveDependencies({
pattern: /\* @require [\s-]*(.*?\.js)/g,
log: true
}))
.pipe(concat(filename))
.pipe(uglify())
.pipe(gulp.dest('dist/'))
;
};
var scripts = getListOfFiles('src/', 'js');
for (key in scripts) {
var filename = scripts[key];
var stream = gulp.src(pathModule.join('src/', filename));
compileScript(stream, filename);
}
callback(null);
});
//===================//
// FUNCTIONS & UTILS //
//===================//
/**
* Returns list of files in the specified directory
* with the specified extension.
*
* @param {string} path
* @param {string} extension
* @returns {string[]}
*/
function getListOfFiles(path, extension) {
var list = [];
var files = fs.readdirSync(path);
var pattern = new RegExp('.' + extension + '$');
for (var key in files) {
var filename = files[key];
if (filename.match(pattern)) {
list.push(filename);
}
}
return list;
}
但它看起来很乱,我找不到一个好方法让它与gulp-watch一起使用。
有没有更好更简单的方法来解决这个问题并取得理想的结果?
答案 0 :(得分:1)
如何将单个JavaScript文件作为输出?
在此处查看我给类似问题的答案:Pass random value to gulp pipe template
使用这个gulp插件:https://github.com/adam-lynch/glob-to-vinyl
您可以访问单个文件。
这是(假设使用此插件):
function compileScript(file) {
gulp
.src('file')
.pipe(resolveDependencies({
pattern: /\* @require [\s-]*(.*?\.js)/g,
log: true
}))
.pipe(concat())
.pipe(uglify())
.pipe(gulp.dest('dist/'))
;
};
gulp.task('build:scripts', function() {
globToVinyl('src/**/*.js', function(err, files){
for (var file in files) {
compileScript(files[file].path);
}
});
});
答案 1 :(得分:1)
以下是使用@avcajaraville指定的解决方案重写我的任务的结果。它是一个完整的,经过测试和运行的代码。
var targetDir = 'web';
var sourceDir = 'assets';
var gulp = require('gulp');
var pathModule = require('path');
var resolveDependencies = require('gulp-resolve-dependencies');
var concat = require('gulp-concat');
var uglify = require('gulp-uglify');
var globToVinyl = require('glob-to-vinyl');
gulp.task('build:scripts', function(callback) {
var compileScript = function(filePath, destinationDirectory) {
// Extracting filename from absolute path (required by concat).
var filename = pathModule.basename(filePath);
return gulp
.src(filePath)
.pipe(resolveDependencies({
pattern: /\* @require [\s-]*(.*?\.js)/g,
log: true
}))
.pipe(concat(filename))
.pipe(uglify())
.pipe(gulp.dest(destinationDirectory))
;
};
var sourceGlob = pathModule.join(sourceDir, '/scripts/*.js');
var destinationDirectory = pathModule.join(targetDir, '/js/');
globToVinyl(sourceGlob, function(errors, files) {
for (var file in files) {
compileScript(files[file].path, destinationDirectory);
}
});
callback(null);
});