Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/382.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用Gulp编译JavaScripts并解析依赖项(单独的文件)_Javascript_Compilation_Assets_Gulp - Fatal编程技术网

使用Gulp编译JavaScripts并解析依赖项(单独的文件)

使用Gulp编译JavaScripts并解析依赖项(单独的文件),javascript,compilation,assets,gulp,Javascript,Compilation,Assets,Gulp,我想用Gulp编译JavaScript文件 我有一个src目录,其中所有脚本都有.js扩展名。我希望所有脚本都单独编译,并放入目标目录(dist),其文件名与原始脚本相同 考虑这个例子: src/jquery.js: /** * @require ../../vendor/jquery/dist/jquery.js */ /** * @require ../../vendor/angular/angular.js * @require ../../vendor/ngprogress-l

我想用Gulp编译JavaScript文件

我有一个
src
目录,其中所有脚本都有
.js
扩展名。我希望所有脚本都单独编译,并放入目标目录(
dist
),其文件名与原始脚本相同

考虑这个例子:

src/jquery.js

/**
 * @require ../../vendor/jquery/dist/jquery.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);
src/application.js

/**
 * @require ../../vendor/jquery/dist/jquery.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);
我使用解析每个源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
需要一个文件名,并且不仅合并原始文件和为其解析的依赖项,还合并通过glob模式指定的所有JavaScript文件

那么,如何获取单个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;
}
但它看起来很粗糙,我找不到一个好方法让它工作

有没有更好更简单的方法来解决这个问题并达到预期的效果

如何获取单个JavaScript文件作为输出

在这里检查我对类似问题的回答:

使用此gulp插件:

您可以访问单个文件

这就是(假设使用此插件):


下面是使用指定的解决方案重写任务的结果。这是一个完整的、经过测试的、可运行的代码

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

嘿,谢谢!这看起来是一个可行的解决方案,我会尝试一下,然后再回来找你。顺便问一下,
concat
需要文件名才能操作,您能否更新代码段以反映这一点?也许我们可以从
compileScript
函数的参数中提取文件名?compileScript将文件名作为参数接收,这就是我们使用globToViny的原因,所以我想只是将文件添加到:.pipe(concat(file)),但我无法(没有时间)真正测试代码,所以,您必须这样做。请检查并让我知道。我认为
file
是文件的完整路径名,
concat
只需要文件名的一部分。不是吗?啊,明白了,我没有完全理解你。我不知道我们必须发送文件名。是我的错。为此,只需从路径字符串中提取文件名,如下所示:.pipe(concat(file.replace(/^..[\\/]/,''))如果有帮助,请告诉我。谢谢您的回答!我已经设法用你的建议重写了我的任务。我已经发布了完整的工作代码,作为将来参考的另一个答案。