Gulp - 如何使用gulp-concat控制处理顺序

时间:2014-09-16 19:29:58

标签: angularjs gulp

我正在尝试使用gulp-concat将组合的JavaScript和CSS资源生成到单个文件中,使用类似这样的内容:

var concatjs = gulp
    .src(['app/js/app.js','app/js/*Controller.js', 'app/js/*Service.js'])
    .pipe(concat('app.js'))
    .pipe(gulp.dest('build'));

我得到了一个带有这个的连接文件,但是组合输出文件中嵌入的javascript文件的顺序是随机的 - 在这种情况下,控制器在初始app.js文件之前出现,这在尝试加载时会导致问题Angular应用程序在加载任何相关资源之前需要app.js。同样地,对于最终以随机顺序组合的CSS资源,并且顺序再次有点重要 - 即。 bootstrap需要在主题和任何自定义样式表之前加载。

如何设置连接过程以使订单保持不变?

更新 事实证明, DOES 上面的排序实际上是通过在文件规范数组中明确指定文件顺序来实现的。因此,在这种情况下,关键是首先列出app / js / app.js,然后让订单的其余部分以任何顺序排列。

我没有看到这种行为(Duh!)的原因是Gulp Watch正在运行并且gulpfile.js更新实际上没有反映在输出中。重新启动gulp确实更新了脚本。新手错误......

其他想法: 仍然想知道 - 这是指定构建顺序的正确位置吗?现在看来你现在正在将应用程序逻辑(加载顺序)填充到构建脚本中,这感觉不对。还有其他方法可以解决这个问题吗?

2 个答案:

答案 0 :(得分:5)

对于像示例中的角度应用程序(以及它的依赖关系管理),我通常使用这种语法:gulp.src(['app\js\app.js', 'app\js\**\*.js'])

如果你的app.js文件是第一个按字母顺序排列的文件,你也可以只使用gulp.src('app\js\**\*.js')

我看到了关于将加载文件顺序移动到构建脚本中的观点:直到我开始使用gulp-inject在开发时注入index.html中的未分析文件引用并注入捆绑包时,我有同样的感觉生产索引文件中的缩小版和版本版。在我的所有开发周期中使用该glob排序解决方案对我来说非常有意义,我不再考虑它了。

最后,这种“排序气味”的可能解决方案可能是使用browserify,但对我而言,这只会使角度应用程序的架构变得复杂:最后,正如您所说,您只需要一个特定的在所有其他文件之前调用file。

答案 1 :(得分:3)

对于我的js,我使用特定的结构/命名约定,这有助于。我按功能将其拆分为目录,其中每个功能都有'然后将其视为单独的封装模块。

所以对于我的项目,

app/js/

    - app.js
    - app.routes.js
    - app.config.js

    /core/

        - core.js
        - core.controllers.js
        - core.services.js

        /test/

           - .spec.js test files for module here

    /feature1/

        - feature1.js
        - feature1.controllers.js

    /feature2/

        - feature2.js
        - feature2.controllers.js

    ...

因此每个目录都有一个同名文件,其中只包含初始模块定义,这是整个应用程序中app.js所拥有的全部内容。所以feature1.js

angular.module('feature1', [])

然后模块中的后续文件检索模块并向其添加内容(控制器/服务/工厂等)。

angular.module('feature1')
       .controller(....)


无论如何,我已经明白了......

由于我有一个预定义的结构,并且知道每个模块必须首先使用特定文件,因此我可以使用下面的函数将所有内容按顺序排序,然后再通过gulp处理。

此功能取决于npm install filenpm install path

function getModules(src, app, ignore) {

    var modules = [];

    file.walkSync(src, function(dirPath, dirs, files) {

        if(files.length < 1)
            return;

        var dir = path.basename(dirPath)
            module;

        if(ignore.indexOf(dir) === -1) {
            module = dirPath === src ? app : dir;

            files = files.sort(function(a, b) {
                return path.basename(a, '.js') === module ? -1 : 1;
            })
            .filter(function(value) {
                return value.indexOf('.') !== 0;
            })
            .map(function(value) {
                return path.join(dirPath, value);
            })

            modules = modules.concat(files);
        }
    })

    return modules;
}

它遍历传递给它的目录结构,从每个目录(或模块)获取文件并将它们排序到正确的顺序,确保模块定义文件始终是第一个。它还会忽略出现在&#39; ignore&#39;中的任何目录。数组并删除任何以&#39;。&#39;

开头的隐藏文件

用法是,

getModules(src, appName, ignoreDirs);
  • src是你要从
  • 递减的目录
  • appName是app.js文件的名称 - 所以&#39; app&#39;
  • ignoreDirs是一组您想忽略的目录名称

所以

getModules('app/js', 'app', ['test']);

它会以正确的顺序返回应用中所有文件的数组,然后您可以使用它们:

gulp.task('scripts', function() {
    var modules = getModules('app/js', 'app', ['test']);

    return gulp.src(modules)
               .pipe(concat('app.js'))
               .pipe(gulp.dest('build'));
});