javascript - Concatenar scripts en orden con Gulp
Digamos, por ejemplo, que estás construyendo un proyecto en Backbone o lo que sea y necesitas cargar los scripts en un cierto orden, por ejemplo, underscore.js necesita cargarse antes que backbone.js.
¿Cómo hago para que concatene los scripts de manera que estén en orden?
// 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/'));
});
Tengo el orden correcto de los scripts en mi source/index.html, pero como los archivos están organizados por orden alfabético, gulp concatenará underscore.js después de backbone.js, y el orden de los scripts en mi source/index.html no importa, mira los archivos en el directorio.
¿Entonces alguien tiene alguna idea sobre esto?
La mejor idea que tengo es renombrar los scripts del proveedor con 1, 2, 3 para darles el orden adecuado, pero no estoy seguro de si me gusta esto.
A medida que aprendía más, descubrí que Browserify es una gran solución, puede ser un problema al principio, pero es excelente.
Respuesta #1
Recientemente tuve un problema similar con Grunt al construir mi aplicación AngularJS. Aquí hay una pregunta que publiqué.
Lo que terminé haciendo fue listar explícitamente los archivos en orden en la configuración de grunt. El archivo de configuración entonces se verá así:
[
'/path/to/app.js',
'/path/to/mymodule/mymodule.js',
'/path/to/mymodule/mymodule/*.js'
]
Grunt puede averiguar qué archivos son duplicados y no incluirlos. La misma técnica funcionará también con Gulp.
Respuesta #2
Otra cosa que ayuda si necesitas que algunos archivos vengan después de un grupo de archivos, es excluir archivos específicos de tu patrón glob, así:
[
'/src/**/!(foobar)*.js', // all files that end in .js EXCEPT foobar*.js
'/src/js/foobar.js',
]
Puedes combinar esto con la especificación de archivos que deben ir primero como se explica en la respuesta de Chad Johnson.
Respuesta #3
He usado el plugin gulp-order pero no siempre tiene éxito como se puede ver en mi publicación de Stack Overflow gulp-order módulo node con streams combinados. Al navegar por la documentación de Gulp me encontré con el módulo streamque, que ha funcionado bastante bien para especificar el orden, en mi caso para la concatenación. https://github.com/gulpjs/gulp/blob/master/docs/recipes/using-multiple-sources-in-one-task.md
A continuación se muestra un ejemplo de cómo lo usé
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);
});
Respuesta #4
Con gulp-useref puedes concatenar cada script declarado en tu archivo index, en el orden en que lo declares.
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'}));
});
Y en el HTML tienes que declarar el nombre del archivo de compilación que deseas generar, así:
<!-- 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>
En tu directorio de compilación tendrás la referencia a main.min.js que contendrá vendor.js, test.js y main.js
