Pasar parámetro a la tarea Gulp

Respuestas:

269

Es una característica que no puede quedarse sin los programas. Puedes probar hilos .

npm install --save-dev yargs

Puedes usarlo así:

gulp mytask --production --test 1234

En el código, por ejemplo:

var argv = require('yargs').argv;
var isProduction = (argv.production === undefined) ? false : true;

Para su entendimiento:

> gulp watch
console.log(argv.production === undefined);  <-- true
console.log(argv.test === undefined);        <-- true

> gulp watch --production
console.log(argv.production === undefined);  <-- false
console.log(argv.production);                <-- true
console.log(argv.test === undefined);        <-- true
console.log(argv.test);                      <-- undefined

> gulp watch --production --test 1234
console.log(argv.production === undefined);  <-- false
console.log(argv.production);                <-- true
console.log(argv.test === undefined);        <-- false
console.log(argv.test);                      <-- 1234

Espero que puedas tomarlo desde aquí.

Hay otro complemento que puedes usar, minimist. Hay otra publicación donde hay buenos ejemplos tanto para yargs como para minimist: ( ¿Es posible pasar una bandera a Gulp para que ejecute tareas de diferentes maneras? )

Ethan
fuente
13
Respuesta muy bien escrita, ¡gracias por los ejemplos!
Allen Rice
¿Cómo se accede a esto en JavaScript?
vini
Si usa trago con hilos, tenga en cuenta lo siguiente: Si tiene una tarea 'cliente' y no quiere usar la construcción de hilos en la comprobación de parámetros para los comandos requeridos: comando ("cliente", "Crear un directorio de clientes")
suther
Vea mi comentario a continuación, si desea utilizar los hilos integrados en la verificación de parámetros para los 'comandos' requeridos junto con trago: stackoverflow.com/a/41412558/1256697
suther
55
(argv.production === undefined) ? false : true;es equivalente a argv.production !== undefined.
CJStuart
136

Si desea evitar agregar dependencias adicionales, encontré que los nodos process.argvson útiles:

gulp.task('mytask', function() {
    console.log(process.argv);
});

Entonces lo siguiente:

gulp mytask --option 123

debería mostrar:

[ 'node', 'path/to/gulp.js', 'mytask', '--option', '123']

Si está seguro de que el parámetro deseado está en la posición correcta, entonces los indicadores no son necesarios. ** Solo use (en este caso):

var option = process.argv[4]; //set to '123'

PERO: como la opción puede no estar configurada, o puede estar en una posición diferente, creo que una mejor idea sería algo como:

var option, i = process.argv.indexOf("--option");
if(i>-1) {
    option = process.argv[i+1];
}

De esa manera, puede manejar variaciones en múltiples opciones, como:

//task should still find 'option' variable in all cases
gulp mytask --newoption somestuff --option 123
gulp mytask --option 123 --newoption somestuff
gulp mytask --flag --option 123

** Editar: verdadero para los scripts de nodo, pero gulp interpreta cualquier cosa sin un "-" inicial como otro nombre de tarea. Por lo tanto, el uso gulp mytask 123fallará porque gulp no puede encontrar una tarea llamada '123'.

Trevedhek
fuente
1
Hay un error tipográfico en "var option, i = process, argv.indexOf (" - option ");". Creo que debería ser proccess.argv.
Luis Paulo Lohmann
Ah, así debería ser. Corregido Gracias @luis
Trevedhek
Solo quería verificar la bandera --dev, para poder distinguir entre producción y entornos inferiores. Esto hace el truco sin agregar dependencias adicionales. ¡Gracias!
b01
1
Para mí, los gulp myTask --productionresultados son process.argviguales a[pathToNode, pathToGulp, 'myTask', '--production']
Sung Cho
2
Probablemente ha cambiado, he visto algunos ejemplos antiguos con la misma diferencia. De todos modos, puede depurarlo y ver su caso. Esta debe ser la respuesta aceptada, ya que tiene cero dependencias ..
Juan
19

Pasar un parámetro a tragar puede significar algunas cosas:

  • Desde la línea de comando hasta el archivo de trago (ya ejemplificado aquí).
  • Desde el cuerpo principal de la secuencia de comandos gulpfile.js hasta tragar tareas.
  • De una tarea de trago a otra tarea de trago.

Aquí hay un enfoque para pasar parámetros desde el archivo principal de gulpfile a una tarea de trago. Al mover la tarea que necesita el parámetro a su propio módulo y envolverlo en una función (para que se pueda pasar un parámetro):

// ./gulp-tasks/my-neat-task.js file
module.exports = function(opts){

  opts.gulp.task('my-neat-task', function(){
      console.log( 'the value is ' + opts.value );
  });

};
//main gulpfile.js file

//...do some work to figure out a value called val...
var val = 'some value';

//pass that value as a parameter to the 'my-neat-task' gulp task
require('./gulp-tasks/my-neat-task.js')({ gulp: gulp, value: val});

Esto puede ser útil si tiene muchas tareas y desea pasarles algunas configuraciones ambientales útiles. No estoy seguro de si puede funcionar entre una tarea y otra.

yuvilio
fuente
16

Hay una receta oficial para esto usando minimist .

https://github.com/gulpjs/gulp/blob/master/docs/recipes/pass-arguments-from-cli.md

Lo básico es usar minimist para separar los argumentos de cli y combinarlos con opciones conocidas:

var options = minimist(process.argv.slice(2), knownOptions);

Que analizaría algo como

$ gulp scripts --env development

Más información completa en la receta.

RobW
fuente
1
¿Por qué la basura en la parte superior de la lista y la solución adecuada en la parte inferior no se votan? suspiro
DDD
14

Si desea usar parámetros de entorno y otras utilidades, como log, puede usar gulp-util

/* 
  $npm install gulp-util --save-dev
  $gulp --varName 123
*/
var util = require('gulp-util');
util.log(util.env.varName);

Actualizar

gulp-util ahora está en desuso. Puedes usar minimist en su lugar.

var argv = require('minimist')(process.argv.slice(2));
console.dir(argv);
Quy Tang
fuente
1
trago-util está obsoleta desde 2016
valdeci
5

La respuesta de @ Ethan funcionaría por completo. Desde mi experiencia, la forma más nodal es usar variables de entorno. Es una forma estándar de configurar programas implementados en plataformas de alojamiento (por ejemplo, Heroku o Dokku).

Para pasar el parámetro desde la línea de comando, hágalo así:

Desarrollo: gulp dev

Producción: NODE_ENV=production gulp dev

La sintaxis es diferente, pero muy Unix, y es compatible con Heroku, Dokku, etc.

Puede acceder a la variable en su código en process.env.NODE_ENV

MYAPP=something_else gulp dev

establecería

process.env.MYAPP === 'something_else'

Esta respuesta puede darte algunas otras ideas.

Michael Cole
fuente
4

Aquí está mi ejemplo de cómo lo uso. Para la tarea css / less. Se puede aplicar para todos.

var cssTask = function (options) {
  var minifyCSS = require('gulp-minify-css'),
    less = require('gulp-less'),
    src = cssDependencies;

  src.push(codePath + '**/*.less');

  var run = function () {
    var start = Date.now();

    console.log('Start building CSS/LESS bundle');

    gulp.src(src)
      .pipe(gulpif(options.devBuild, plumber({
        errorHandler: onError
      })))
      .pipe(concat('main.css'))
      .pipe(less())
      .pipe(gulpif(options.minify, minifyCSS()))
      .pipe(gulp.dest(buildPath + 'css'))
      .pipe(gulpif(options.devBuild, browserSync.reload({stream:true})))
      .pipe(notify(function () {
        console.log('END CSS/LESS built in ' + (Date.now() - start) + 'ms');
      }));
  };

  run();

  if (options.watch) {
    gulp.watch(src, run);
  }
};

gulp.task('dev', function () {
  var options = {
    devBuild: true,
    minify: false,
    watch: false
  };

  cssTask (options);
});
Lince
fuente
3

Aquí hay otra forma sin módulos adicionales:

Necesitaba adivinar el entorno a partir del nombre de la tarea, tengo una tarea 'dev' y una tarea 'prod'.

Cuando lo ejecuto gulp prod, debería estar configurado en entorno de producción. Cuando ejecuto gulp devo cualquier otra cosa, debe establecerse en el entorno de desarrollo.

Para eso solo verifico el nombre de la tarea en ejecución:

devEnv = process.argv[process.argv.length-1] !== 'prod';
antoni
fuente
2

Si usa trago con hilos, observe lo siguiente:

Si tiene una tarea 'cliente' y no quiere usar la construcción de hilos en la verificación de parámetros para los comandos requeridos:

.command("customer <place> [language]","Create a customer directory") llámalo con:

gulp customer --customer Bob --place Chicago --language english

¡yargs siempre arrojará un error, que no hay suficientes comandos asignados a la llamada, incluso si tiene! -

Pruébelo y agregue solo un dígito al comando (para que no sea igual al nombre de la tarea gulp) ... y funcionará:

.command("customer1 <place> [language]","Create a customer directory")

Esto es causa de que el trago parezca desencadenar la tarea, antes de que los hilos puedan verificar este parámetro requerido. Me costó horas de vigilancia resolver esto.

Espero que esto te ayude..

suther
fuente
0

Sé que llego tarde para responder esta pregunta, pero me gustaría agregar algo para responder de @Ethan, la respuesta más votada y aceptada.

Podemos usar yargspara obtener el parámetro de línea de comando y con eso también podemos agregar nuestro propio alias para algunos parámetros como el siguiente.

var args = require('yargs')
    .alias('r', 'release')
    .alias('d', 'develop')
    .default('release', false)
    .argv;

Favor de referirse a este enlace para más detalles. https://github.com/yargs/yargs/blob/HEAD/docs/api.md

El siguiente es el uso de alias según lo dado en la documentación de yargs. También podemos encontrar más yargsfunciones allí y podemos mejorar aún más la experiencia de pasar la línea de comandos.

.alias (clave, alias)

Establezca los nombres de clave como equivalentes, de modo que las actualizaciones de una clave se propaguen a alias y viceversa.

Opcionalmente .alias () puede tomar un objeto que asigna claves a alias. Cada clave de este objeto debe ser la versión canónica de la opción, y cada valor debe ser una cadena o una matriz de cadenas.

Code Spark
fuente
-2

Simplemente cárguelo en un nuevo objeto en proceso ... process.gulp = {}y haga que la tarea mire allí.

Kirk Strobeck
fuente