Coder Social home page Coder Social logo

gulp-order's Introduction

gulp-order

The gulp plugin gulp-order allows you to reorder a stream of files using the same syntax as of gulp.src.

Motivation

Assume you want to concatenate the following files in the given order (with gulp-concat):

  • vendor/js1.js
  • vendor/**/*.{coffee,js}
  • app/coffee1.coffee
  • app/**/*.{coffee,js}

You'll need two streams:

  • A stream that emits the JavaScript files, and
  • a stream that emits the compiled CoffeeScript files.

To combine the streams you can pipe into another gulp.src or use es.merge (from event-stream). But you'll notice that in both cases the files are emitted in the same order as they come in - and this can seem very random. With gulp-order you can reorder the files.

Usage

require("gulp-order") returns a function that takes an array of patterns (as gulp.src would take).

var order = require("gulp-order");
var coffee = require("gulp-coffee");
var concat = require("gulp-concat");

gulp
  .src("**/*.coffee")
  .pipe(coffee())
  .pipe(gulp.src("**/*.js")) // gulp.src passes through input
  .pipe(order([
    "vendor/js1.js",
    "vendor/**/*.js",
    "app/coffee1.js",
    "app/**/*.js"
  ]))
  .pipe(concat("all.js"))
  .pipe(gulp.dest("dist"));

  // When passing gulp.src stream directly to order, don't include path source/scripts in the order paths.
  // They should be relative to the /**/*.js.
  gulp
  .src("source/scripts/**/*.js")
  .pipe(order([
    "vendor/js1.js",
    "vendor/**/*.js",
    "app/coffee1.js",
    "app/**/*.js"
  ]))
  .pipe(concat("all.js"))
  .pipe(gulp.dest("dist"));

Options

gulp
  .src("**/*.coffee")
  // ...
  .pipe(order([...], options))

base

Some plugins might provide a wrong base on the Vinyl file objects. base allows you to set a base directory (for example: your application root directory) for all files.

Features

Uses minimatch for matching.

Tips

  • Try to move your ordering out of your gulp.src(...) calls into order(...) instead.
  • You can see the order of the outputted files with gulp-print

Troubleshooting

If your files aren't being ordered in the manner that you expect, try adding the base option.

Alternative Approaches

Contributors

License

MIT - Copyright © 2014 Marcel Jackwerth

gulp-order's People

Contributors

andrewleedham avatar danielcompton avatar dependabot[bot] avatar mrcljx avatar rejas avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

gulp-order's Issues

Can't get order to work

I'm getting a bunch of files, what I want with the order is to have app.css at the bottom, but whatever I do it's always at the top.

var lessTask = function(event) {
    var response = gulp.src('./public/assets/css/builds/**/*.css')
        .pipe(order([
            "**/*.css",
            "**/app.css"
        ]))
        .pipe(concat('app.css'))
        .pipe(gulp.dest('./public/assets/css/'))
        .pipe(minifycss())
        .pipe(gulp.dest('./public/assets/css'))
        .pipe(buster('css.json'))
        .pipe(gulp.dest('./public/assets'));

    return response;
}

How do you order it so that app.css is at the bottom of new file?

Sort is unstable

Array.prototype.sort() is an unstable sort

This causes non-deterministic sorting when dealing with files that have the same name (e.g. index.js). In other words one may sort several unique files with the same name and end up with different sortings each time.

This is not ideal for me as I have checked-in source files that are generated from a gulp task. This is not ideal in general because non-determinism should be avoided.

Support certain files to be "last"

I'm trying to express the following order, but it's not working as I had hoped:

[
  "app.js",
  "**/*.js",
  "debug.js"
]

I want debug.js to always be at the end, but since it matches the **/*.js, it get placed too early. How can I express that a certain file (certain files) should come later?

Try

rank = function(s) {
  var index, matcher, _i, _len;
  for (index = _i = 0, _len = matchers.length; _i < _len; index = ++_i) {
    matcher = matchers[index];

    //This line fixed my problem to order in any folder
    if(matcher.pattern.replace(/\//g,'\\').indexOf(s.replace('..\\', '', 'g')) > -1) return index;

    if (matcher.match(s)) {
      return index;
    }
  }
  return matchers.length;
};

seems like globs starting with './' throws the ranking off

Hi,

I'm trying this:

bower()
.pipe(order(['./**/angular.js']))
.pipe(concat('all.js'))

but I still get angular-route.js before angular.js.
If I change to:

bower()
.pipe(order(['**/angular.js']))
.pipe(concat('all.js'))

it works however, and I get angular.js first in the resulting file.
Any ideas how it could be so?
Not a big problem for me to drop the ./ prefix, but thought I should let you know.

Not doing anything

I am using gulp-remember which clearly states to use gulp-order if order is to be maintained, I am trying but gulp-order is not doing anything. I created the exact repo to outline the problem available here.

https://github.com/newtonianb/gulp-order-problem
npm install && bower install && gulp js and see output in public/scripts.js. The coffeescript file (a.coffee) is being concatenated after the js file (b.js) eventhough the order states a should come first.

'use strict';
var gulp = require('gulp');
var $ = require('gulp-load-plugins')();

gulp.task('js', function (callback) {

    var coffeeFilter = $.filter(['**/*.coffee']);

    var src = [
        'resources/assets/bower/jquery/dist/jquery.min.js',
        'resources/assets/bower/jquery-migrate/jquery-migrate.min.js',
        'resources/assets/scripts/util/a.coffee',
        'resources/assets/scripts/b.js'
    ];

    var destName = 'scripts.js';
    var dest = 'public/assets';

    return gulp.src(src)

    .pipe(coffeeFilter)
    .pipe($.cached('coffee'))
    .pipe($.coffee())
    .pipe($.remember('coffee'))
    .pipe($.order(src, { base: process.cwd() }))
    .pipe(coffeeFilter.restore())

    .pipe($.concat(destName))
    .pipe(gulp.dest(dest));
});

Support for ordering files in any folder

gulp.src() supports jumping over to another directory, such as "../app". I usually structure my apps with my build tools in a separate directory than my app, so this is typically how most of my globs start out.

When I realized that gulp-order() was not matching any of my files, I cracked open the source. I think the issue is that since path.relative() is used for ranking, it will never produce a path which matches since it's not accessible in a relative path from gulp (no matter what I pass in to options.base).

I'm on Windows, so ignoring options.base and letting it use file.path isn't an option either as it contains backslashes which are stripped out by path.relative().

Way to specify 'the rest'?

Trying to get jQuery to load first so the rest of its dependencies will work. The issue is I'm using this in conjunction with main-bower-files. Is there a way to say: load jQuery first and then put everything else after that?

Thank you!
Matt

Allow to provide a custom rank function

The actual rank function isn't working for me.

We map every glob to a absolute path (this is an internal need ), and that makes the rank matcher not match on the rank function.

Say we have the following patterns:

[
"C:\folder\src\app\modules\analytics\**\*.config.js"
"C:\folder\src\app\modules\analytics\**\*.run.js"
"C:\folder\src\app\modules\analytics\**\*.filter.js"
"C:\folder\src\app\modules\analytics\**\*.controller.js"
"C:\folder\src\app\modules\analytics\**\*.directive.js"
"C:\folder\src\app\modules\analytics\**\*.service.js"
"C:\folder\src\app\modules\analytics\**\*.model.js"
"C:\folder\src\app\modules\analytics\**\*.factory.js"
]

With that, the rank function fails at the matcher.match(s),
for example, with an given s = "test.config.js" the matcher of the first item of the array will not match (at least it's not matching for me).

I don't know if it's a bug with minimatch or a real bug, but allowing to provide a custom rank function would solve this problem for me.

Making it work with gulp-watch

Is this known to break with gulp-watch? It seems my changed file is not being picked up when I have the gulp-order hooked up. I'm also using it with gulp-cache and gulp-remember.

return gulp.src(conf.src)
        .pipe(coffeeFilter)
        .pipe($.cached('coffee'))
        .pipe($.coffee())
        .pipe($.remember('coffee'))
        .pipe(coffeeFilter.restore())
        .pipe($.order(castExtension(conf.src, ['coffee'], 'js'), { base: process.cwd() }))
        .pipe($.concat(conf.outputName))
        .pipe(gulp.dest(conf.dest))

Relative File Names

Hey,

Not sure if this is the case on OSX/Linux, but on Windows the <file>.relative variable you use for ranking just resolves to the file name. This makes folder matching useless. I was able to fix this locally by changing the variable to <file>.path in the sorting function.

Again, not sure if this is an issue on other platforms, so I didn't make a PR - let me know if you would like me to do so.

Subdirectory ordering?

Really love this library, but something I've been wondering about is ordering files within a sub directory of the given source.

My use case is probably fairly common, Bootstrap installed via Bower. Bootstrap annoyingly has a requirement for tooltip.js inside its popover.js, and of course by default tooltip would get loaded after popover in any build process.

To solve this I tried doing the following

var paths = {
    'concat':'js/concat/',
    'bootstrap':'boostrap-sass/vendor/assets/javascripts/bootstrap/*.js',
    'bowerJs':
    [
        'bower_components/**/*.js',
        '!bower_components/**/*.min.js',
        '!bower_components/jquery/src/**/*.js'
    ],
};

gulp.task('vendor', function() {
    return gulp.src(paths.bowerJs)
    .pipe(order(
        [
            'lodash/lodash.js',
            'jquery/dist/jquery.js',
            paths.bootstrap + 'bootstrap/affix.js',
            paths.bootstrap + 'bootstrap/alert.js',
            paths.bootstrap + 'bootstrap/button.js',
            paths.bootstrap + 'bootstrap/carousel.js',
            paths.bootstrap + 'bootstrap/collapse.js',
            paths.bootstrap + 'bootstrap/dropdown.js',
            paths.bootstrap + 'bootstrap/tab.js',
            paths.bootstrap + 'bootstrap/transition.js',
            paths.bootstrap + 'bootstrap/scrollspy.js',
            paths.bootstrap + 'bootstrap/modal.js',
            paths.bootstrap + 'bootstrap/tooltip.js',
            paths.bootstrap + 'bootstrap/popover.js',
        ]
    ))
    .pipe(print())
    .pipe(concat('vendor.concat.js'))
    .pipe(gulp.dest(paths.concat));
});

The overall order is correct (ie., lodash, jquery then bootstrap) but bootstrap's ordering is just sticking to alphabetical ordering of the files. I think I could probably achieve this by building bootstrap first and then calling another function to build them all together, but was wondering if there was a way to do it in a single function.

option add case sensitive

filename case sensitive

.pipe(order([
     'person.js',
     'Woman.js'
], options))


options:{
caseSensitive:true or false
}

Ordering doesnt work

I have task:

gulp.task('js:min', function () {
  return gulp.src(['public/js/*.min.js'])
    .pipe(order([
      'public/js/jquery-1.11.1.min.js',
      'public/js/bootstrap.min.js'
    ]))
    .pipe(print())
    .pipe(concat('main.min.js'))
    .pipe(gulp.dest('tmp'));
});

Running gulp js:min will print:

[16:28:19] Using gulpfile ~/devster/gulpfile.js
[16:28:19] Starting 'js:min'...
[16:28:19] public/js/bootstrap.min.js
[16:28:19] public/js/jquery-1.11.1.min.js
[16:28:19] public/js/jquery.magnific-popup.min.js
[16:28:19] public/js/jquery.stellar.min.js
[16:28:19] public/js/jquery.touchSwipe.min.js
[16:28:19] public/js/owl.carousel.min.js
[16:28:19] public/js/retina-1.1.0.min.js
[16:28:19] public/js/wow.min.js
[16:28:19] Finished 'js:min' after 46 ms

TypeError, cannot read property 'on' of undefined.

Hi Guys,

I am executing this simple task:

gulp.task('js', function() {
    return gulp.src([
        path.join(config.dest, 'vendor/**/*.js')
    ])
    .pipe(order[
        'Content/vendor/jquery/dist/jquery.js'
    ])
    .pipe(concat('all.js'))
    .pipe(gulp.dest(config.scripts));
});

Without the .pipe(order[... it works just fine, concatenating the files.
Initially I tried order['vendor/jquery/**'] which is what I actually wanted. I tried a few path combinations.
What could i possibly be missing?

Support for undeclared file order read from header

At the moment we have to declare the order of fileprocessing in the gulp file.
What if the order plugin could read the header of an html document, look for requested links (files) and process them in a task in that certain order.

Lets say the HTML has this:

<!-- build:css -->
    <link rel="stylesheet" type="text/css" href="css/reset.css">
    <link rel="stylesheet" type="text/css" href="css/style.css">
    <link rel="stylesheet" type="text/css" href="css/typography.css">
    <link rel="stylesheet" type="text/css" href="css/sizes.css">
    <link rel="stylesheet" type="text/css" href="css/custom.css">
    <!-- endbuild -->

And the guild task would be like this:

gulp task:
  - get filepaths and order from htmldocument(s)
  - concat
  - minify
  - dest

Multiple html documents: only add new links, dont add existing links.
That would be awesome. But possible?

globs is not defined

Just installed gulp-order using 'npm install gulp-order --save-dev' and attempted to use, but received the error:

node_modules/gulp-order/lib/index.js:26
  return globs.length;
         ^
ReferenceError: globs is not defined

Compared with your coffee source code and changed line 26 in the index.js file to read return patterns.length instead of globs.length, all works fine.

Appears to be some issue with the current npm package.

Hope this helps.

Thanks for gulp-order, very helpful.

David

gulp-order v1.2.0 causes (gulp build) to throw ReferenceError: Invalid left-hand side in assignment

The Problem:
At least for my set up, when I try to build my application gulp-order v1.2.0 throws an error as follows:
... ... ... ... .../node_modules/gulp-order/lib/index.js:7
build 10-Oct-2018 17:36:02 [ERROR] ({Minimatch} = require("minimatch"));
build 10-Oct-2018 17:36:02 [ERROR] ^
build 10-Oct-2018 17:36:02 [ERROR]
build 10-Oct-2018 17:36:02 [ERROR] ReferenceError: Invalid left-hand side in assignment

This version of gulp-order ships with a file src/index.coffee with the following lines:
through = require "through"
{ Minimatch } = require "minimatch"

The second line is the one that ends up causing an issue when it is used to generate the following file:
... ... ... ... .../node_modules/gulp-order/lib/index.js which contains the following lines:
// Generated by CoffeeScript 2.3.1
(function() {
var Minimatch, path, sort, through;

through = require("through");

({Minimatch} = require("minimatch"));

Note the last line (line 7) retains the format from the index.coffee file where we have extra brackets. In order to build, it should look like the following line:
Minimatch = require("minimatch").Minimatch;

The cause in my case is the following:
This just occurred yesterday (10/10/18) when I build my code base because:

  1. Issue "#31 Publish v1.2.0 to npm" made version 1.2.0 automatically available to many projects
    "sirlantis commented a day ago"
    "I've been under a rock for the last few months. I published 1.2.0 to npm."
    and
  2. My top level package.json had the following in it, which also allowed the project to automatically upgrade to v1.2.0
    ...
    "devDependencies": { ....
    "gulp-order": "^1.1.1", ....

The solution:
A) Modify the above line as follows:
"gulp-order": "1.1.1", OR
B) Figure out why the following line causes a build exception...
{ Minimatch } = require "minimatch"

I am definitely not an expert, so I may be missing something that will make V1.2.0 work fine. That is part of the reason I tried to give you as much info as I could, and info about my work around.
However, my guess is that I am not going to be the only one who is going to rebuild from scratch and hit this issue.
I could be wrong.... :)
Thank you in advance for your help....
Jeff

Wrong order

Let's assume we have the following file structure:

tmptmp
    tmp1
        a.txt
        b.txt
    tmp2
        aa.txt
        bb.txt

And my pattern looks like:

var pattern = [
    'tmptmp/tmp1/a.txt',
    'tmptmp/tmp2/aa.txt',
    'tmptmp/tmp2/bb.txt',
    'tmptmp/tmp1/b.txt'
];

I call gulp.src(pattern).pipe(order(pattern)) and the result is:

tmptmp/tmp1/a.txt
tmptmp/tmp2/aa.txt
tmptmp/tmp1/b.txt
tmptmp/tmp2/bb.txt

Which is wrong.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.