与Gulp一起订购Concat脚本

时间:2014-02-22 21:57:49

标签: javascript gulp

例如,假设您正在Backbone上构建一个项目,或者您需要按特定顺序加载脚本,例如需要在underscore.js之前加载backbone.js

如何让脚本连接以便它们按顺序排列?

// JS concat, strip debugging and minify
gulp.task('scripts', function() {
    gulp.src(['./source/js/*.js', './source/js/**/*.js'])
    .pipe(concat('script.js'))
    .pipe(stripDebug())
    .pipe(uglify())
    .pipe(gulp.dest('./build/js/'));
});

我在source/index.html中有正确的脚本顺序,但由于文件是按字母顺序排列的,因此gulp会在underscore.js之后连续backbone.js,以及我的脚本顺序source/index.html并不重要,它会查看目录中的文件。

那么有人对此有所了解吗?

我最好的想法是使用123重命名供应商脚本,以便为他们提供正确的订单,但我不确定我是否喜欢这个。

随着我的了解,我发现Browserify是一个很好的解决方案,起初可能会很痛苦,但它很棒。

17 个答案:

答案 0 :(得分:193)

在构建我的AngularJS应用程序时,我最近遇到了与Grunt类似的问题。这是我发布的a question

我最终做的是在grunt配置中按顺序显式列出文件。所以它看起来像:

[
  '/path/to/app.js',
  '/path/to/mymodule/mymodule.js',
  '/path/to/mymodule/mymodule/*.js'
]

事情有效。 Grunt显然很聪明,不能两次包含同一个文件。

这与Gulp一样。

答案 1 :(得分:132)

如果你需要一些文件来一小撮文件之后,另一件事就是从你的glob中排除特定文件,如下所示:

[
  '/src/**/!(foobar)*.js', // all files that end in .js EXCEPT foobar*.js
  '/src/js/foobar.js',
]

您可以将其与指定需要首先出现的文件结合起来,如Chad Johnson的回答中所述。

答案 2 :(得分:17)

我使用了gulp-order插件,但它并不总是成功,因为我可以通过我的堆栈溢出帖gulp-order node module with merged streams看到。浏览Gulp文档时,我遇到了streamque模块,该模块在我的案例连接中指定了顺序。 https://github.com/gulpjs/gulp/blob/master/docs/recipes/using-multiple-sources-in-one-task.md

我如何使用它的示例在

之下
var gulp         = require('gulp');
var concat       = require('gulp-concat');
var handleErrors = require('../util/handleErrors');
var streamqueue  = require('streamqueue');

gulp.task('scripts', function() {
    return streamqueue({ objectMode: true },
        gulp.src('./public/angular/config/*.js'),
        gulp.src('./public/angular/services/**/*.js'),
        gulp.src('./public/angular/modules/**/*.js'),
        gulp.src('./public/angular/primitives/**/*.js'),
        gulp.src('./public/js/**/*.js')
    )
        .pipe(concat('app.js'))
        .pipe(gulp.dest('./public/build/js'))
        .on('error', handleErrors);
});

答案 3 :(得分:12)

使用gulp-useref,您可以按照声明的顺序连接索引文件中声明的每个脚本。

https://www.npmjs.com/package/gulp-useref

var $ = require('gulp-load-plugins')();
gulp.task('jsbuild', function () {
  var assets = $.useref.assets({searchPath: '{.tmp,app}'});
  return gulp.src('app/**/*.html')
    .pipe(assets)
    .pipe($.if('*.js', $.uglify({preserveComments: 'some'})))
    .pipe(gulp.dest('dist'))
    .pipe($.size({title: 'html'}));
});

在HTML中,您必须声明要生成的构建文件的名称,如下所示:

<!-- build:js js/main.min.js -->
    <script src="js/vendor/vendor.js"></script>
    <script src="js/modules/test.js"></script>
    <script src="js/main.js"></script>

在您的构建目录中,您将获得对main.min.js的引用,其中包含vendor.js,test.js和main.js

答案 4 :(得分:6)

sort-stream也可用于确保gulp.src文件的特定顺序。将backbone.js始终作为要处理的最后一个文件的示例代码:

var gulp = require('gulp');
var sort = require('sort-stream');
gulp.task('scripts', function() {
gulp.src(['./source/js/*.js', './source/js/**/*.js'])
  .pipe(sort(function(a, b){
    aScore = a.path.match(/backbone.js$/) ? 1 : 0;
    bScore = b.path.match(/backbone.js$/) ? 1 : 0;
    return aScore - bScore;
  }))
  .pipe(concat('script.js'))
  .pipe(stripDebug())
  .pipe(uglify())
  .pipe(gulp.dest('./build/js/'));
});

答案 5 :(得分:5)

我将我的脚本组织在不同的文件夹中,用于从bower中提取的每个包,以及我自己的应用程序脚本。由于您要在某处列出这些脚本的顺序,为什么不将它们列在您的gulp文件中?对于项目中的新开发人员,很高兴您在此处列出了所有脚本端点。您可以使用gulp-add-src执行此操作:

gulpfile.js

var gulp = require('gulp'),
    less = require('gulp-less'),
    minifyCSS = require('gulp-minify-css'),
    uglify = require('gulp-uglify'),
    concat = require('gulp-concat'),
    addsrc = require('gulp-add-src'),
    sourcemaps = require('gulp-sourcemaps');

// CSS & Less
gulp.task('css', function(){
    gulp.src('less/all.less')
        .pipe(sourcemaps.init())
        .pipe(less())
        .pipe(minifyCSS())
        .pipe(sourcemaps.write('source-maps'))
        .pipe(gulp.dest('public/css'));
});

// JS
gulp.task('js', function() {
    gulp.src('resources/assets/bower/jquery/dist/jquery.js')
    .pipe(addsrc.append('resources/assets/bower/bootstrap/dist/js/bootstrap.js'))
    .pipe(addsrc.append('resources/assets/bower/blahblah/dist/js/blah.js'))
    .pipe(addsrc.append('resources/assets/js/my-script.js'))
    .pipe(sourcemaps.init())
    .pipe(concat('all.js'))
    .pipe(uglify())
    .pipe(sourcemaps.write('source-maps'))
    .pipe(gulp.dest('public/js'));
});

gulp.task('default',['css','js']);

注意:添加了jQuery和Bootstrap以用于演示目的。可能更好地使用CDN,因为它们被广泛使用,浏览器可以将它们从其他站点缓存。

答案 6 :(得分:3)

我只是在文件名的开头添加数字:

0_normalize.scss
1_tikitaka.scss
main.scss

它在没有任何问题的情况下工作。

答案 7 :(得分:2)

试试stream-series。它的工作方式类似于merge-stream / event-stream.merge(),除了它不是交错,而是追加到最后。它并不要求您指定像streamqueue这样的对象模式,因此您的代码更清晰。

var series = require('stream-series');

gulp.task('minifyInOrder', function() {
    return series(gulp.src('vendor/*'),gulp.src('extra'),gulp.src('house/*'))
        .pipe(concat('a.js'))
        .pipe(uglify())
        .pipe(gulp.dest('dest'))
});

答案 8 :(得分:1)

另一种方法是使用专门为此问题创建的Gulp插件。 https://www.npmjs.com/package/gulp-ng-module-sort

它允许您通过添加.pipe(ngModuleSort())来对脚本进行排序:

var ngModuleSort = require('gulp-ng-module-sort');
var concat = require('gulp-concat');

gulp.task('angular-scripts', function() {
    return gulp.src('./src/app/**/*.js')
        .pipe(ngModuleSort())
        .pipe(concat('angularAppScripts.js))
        .pipe(gulp.dest('./dist/));
});

假设目录约定为:

|——— src/
|   |——— app/
|       |——— module1/
|           |——— sub-module1/
|               |——— sub-module1.js
|           |——— module1.js
|       |——— module2/
|           |——— sub-module2/
|               |——— sub-module2.js
|           |——— sub-module3/
|               |——— sub-module3.js
|           |——— module2.js
|   |——— app.js

希望这有帮助!

答案 9 :(得分:1)

对我来说,我在管道中有natualSort()和angularFileSort(),它正在重新排序文件。我删除了它,现在它对我来说很好用

$.inject( // app/**/*.js files
    gulp.src(paths.jsFiles)
      .pipe($.plumber()), // use plumber so watch can start despite js errors
      //.pipe($.naturalSort())
      //.pipe($.angularFilesort()),
    {relative: true}))

答案 10 :(得分:1)

我只是使用gulp-angular-filesort

function concatOrder() {

    return gulp.src('./build/src/app/**/*.js')
        .pipe(sort())
        .pipe(plug.concat('concat.js'))
        .pipe(gulp.dest('./output/'));
}

答案 11 :(得分:1)

merge2看起来像是目前唯一可以工作和维护的有序流合并工具。

答案 12 :(得分:0)

我在一个模块环境中,所有人都是使用gulp的核心依赖者。 因此,core模块需要先添加到其他模块之前。

我做了什么:

  1. 将所有脚本移至src文件夹
  2. 只需gulp-rename您的core目录_core
  3. gulp保持gulp.src的顺序,我的concat src看起来像这样:

    concat: ['./client/src/js/*.js', './client/src/js/**/*.js', './client/src/js/**/**/*.js']
    
  4. 它显然会将_作为列表中的第一个目录(自然排序?)。

    注意(angularjs): 然后我使用gulp-angular-extender将模块动态添加到core模块。 编译它看起来像这样:

    angular.module('Core', ["ui.router","mm.foundation",(...),"Admin","Products"])
    

    管理员和产品是两个模块。

答案 13 :(得分:0)

如果您想订购第三方库依赖项,请尝试wiredep。这个包基本上检查bower.json中的每个包依赖,然后为你连接它们。

答案 14 :(得分:0)

我尝试了此页面上的几种解决方案,但均无效果。我有一系列带编号的文件,我只是希望按字母顺序的文件夹名进行排序,因此当通过管道传输到print时,它们将具有相同的顺序。即,保留全局输入的顺序。容易吧?

这是我特定的概念验证代码(var order = require('gulp-order'); var gulp = require('gulp'); var print = require('gulp-print').default; var options = {}; options.rootPath = { inputDir: process.env.INIT_CWD + '/Draft', inputGlob: '/**/*.md', }; gulp.task('default', function(){ gulp.src(options.rootPath.inputDir + options.rootPath.inputGlob, {base: '.'}) .pipe(order([options.rootPath.inputDir + options.rootPath.inputGlob])) .pipe(print()); }); 只是为了查看打印到cli的顺序):

gulp.src

gulp.src疯狂的原因?当我能够使用sleep()函数(使用.map,睡眠时间按索引递增)来确定流输出正确时,我确定src正在异步运行。

{{1}}异步的结果是,其中包含更多文件的目录仅次于目录较少的目录,因为它们需要更长的处理时间。

答案 15 :(得分:0)

在gulp设置中,我先指定供应商文件,然后再指定(更一般的)所有内容。并且成功将供应商js放在其他自定义内容之前。

class JobForm(forms.ModelForm):
    start = forms.TimeField(widget=forms.TimeInput(format='%H:%M'))
    end = forms.TimeField()
    class Meta:
        model = Job
        fields = ('start', 'end')

答案 16 :(得分:0)

显然,您可以将“ nosort”选项传递给gulp.src gulp.src