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



我正在尝试使用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'));

我得到了一个带有此属性的concatted文件,但组合输出文件中嵌入的javascript文件的顺序是随机的-在这种情况下,控制器显示在初始的app.js文件之前,这会导致在尝试加载Angular应用程序时出现问题,该应用程序在加载任何相关资源之前需要app.js。同样,对于组合后的CSS资源,最终以随机顺序结束,而且顺序也有些重要——即引导程序需要在主题和任何自定义样式表之前加载。

如何设置串联过程以使订单保持不变?

更新因此,通过在文件规范数组中显式指定文件顺序,上面的排序确实有效。因此,在这种情况下,关键是首先列出app/js/app.js,然后让顺序无关紧要的其余脚本按任何顺序排列。

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

其他想法:尽管如此,仍然想知道这里是指定构建顺序的合适地方吗?您现在似乎正在将应用程序逻辑(加载顺序)填充到构建脚本中,这感觉不太对劲。是否有其他方法来解决这一问题?

对于像您的示例中这样的角度应用程序(它是依赖项管理),我通常使用这种语法:gulp.src(['appjsapp.js', 'appjs***.js'])

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

我理解你关于将加载文件顺序移动到构建脚本中的观点:我也有同样的感觉,直到我开始使用gulp-injection在开发时在我的index.html中注入未合并的文件引用,并在生产索引文件中注入捆绑的、缩小的和版本化的文件引用。在我的整个开发周期中使用glob排序解决方案对我来说意义重大,以至于我不再考虑它了。

最后,这种"排序气味"的一个可能解决方案可以是使用browserfy,但对我来说,这只是使角度应用程序的架构复杂化:最终,正如你所说,你只需要在调用所有其他文件之前先调用一个特定文件。

对于我的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(....)


不管怎样,我会开门见山的

由于我有一个预定义的结构,并且知道每个模块都必须先有一个特定的文件,所以我可以使用下面的函数在gump处理之前将所有内容按顺序排序。

此功能取决于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;
}

它遍历传递给它的目录结构,从每个目录(或模块)中获取文件,并将它们按正确的顺序排序,确保模块定义文件始终位于第一位。它还会忽略"忽略"数组中出现的任何目录,并删除任何以"开头的隐藏文件

用途是,

getModules(src, appName, ignoreDirs);
  • src是要从中递归的目录
  • appName是您的app.js文件的名称,因此为"app"
  • 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'));
});

最新更新