Saltar al contenido

¿Es posible utilizar imagemin-cli y mantener la misma estructura de carpetas de los archivos comprimidos?

Solución:

¿Es una forma de comprimir imágenes manteniendo la estructura de carpetas?

La respuesta corta es no, no con imagemin-cli

imagemin, (la API imagemin-cli se basa en), no proporciona un mecanismo para preservar la estructura de la carpeta. Ver abierto Issue / feature-request # 191 en el repositorio de github de proyectos.


Solución

Una forma multiplataforma de lograr sus requisitos es escribir un node.js script de utilidad que utiliza la API imagemin directamente. Tan eficazmente … cree su propia herramienta CLI que se puede ejecutar a través de npm-scripts.

Las siguientes esencias muestran cómo se puede lograr esto …


imagemin.js

La utilidad nodo El guión es el siguiente:

#!/usr/bin/env node

'use strict';

var path = require('path');
var readline = require('readline');
var Imagemin = require('imagemin');

var outdir = process.env.PWD; // Default output folder.
var verbose = false; // Default no logging.

// The folder name specified MUST exist in the `glob` pattern of the npm-script.
var DEST_SUBROOT_FOLDER = 'images';

// Nice ticks for logging aren't supported via cmd.exe
var ticksymbol = process.env.npm_config_shell.indexOf('bash') !== -1 ? '✔' : '√';

var rl = readline.createInterface({
    input: process.stdin,
    output: null,
    terminal: false
});

// Handle the optional `-o` argument for the destination folder.
if (process.argv.indexOf('-o') !== -1) {
    outdir = process.argv[process.argv.indexOf('-o') + 1];
}

// Handle the optional `-v` argument for verbose logging.
if (process.argv.indexOf('-v') !== -1) {
    verbose = true;
}

/**
 * Utilizes the Imagemin API to create a new instance for optimizing each image.
 * @param {String} srcpath - The filepath of the source image to optimize.
 * @param {String} destpath - The destination path to save the resultant file.
 * @param {Function} - The relevent `use` plugin (jpegtran|optipng|gifsicle).
 */
function imagemin(srcpath, destpath, plugin) {
    var im = new Imagemin()
        .src(srcpath)
        .dest(destpath)
        .use(plugin);

    im.optimize(function (err, file) {
        if (err) {
            console.error('Error: ' + err);
            process.exit(1);
        }
        if (file && verbose) {
            console.log('x1b[32m%sx1b[0m', ticksymbol, destpath);
        }
    });
}

/**
 * Obtains the destination path and file suffix from the original source path.
 * @param {String} srcpath - The filepath for the image to optimize.
 * @return {{dest: String, type: String}} dest path and ext (.jpg|.png|.gif).
 */
function getPathInfo(srcpath) {
    var ext = path.extname(srcpath),
        parts = srcpath.split(path.sep),
        subpath = parts.slice(parts.indexOf(DEST_SUBROOT_FOLDER), parts.length);

    subpath.unshift(outdir);

    return {
        dest: path.normalize(subpath.join(path.sep)),
        ext: ext
    };
}

/**
 * Triggers the relevent imagemin process according to file suffix (jpg|png|gif).
 * @param {String} srcpath - The filepath of the image to optimize.
 */
function optimizeImage(srcpath) {
    var p = getPathInfo(srcpath);

    switch (p.ext) {
    case '.jpg':
        imagemin(srcpath, p.dest, Imagemin.jpegtran({ progressive: true }));
        break;
    case '.png':
        imagemin(srcpath, p.dest, Imagemin.optipng({ optimizationLevel: 5 }));
        break;
    case '.gif':
        imagemin(srcpath, p.dest, Imagemin.gifsicle({ interlaced: true }));
        break;
    }
}

// Read each line from process.stdin (i.e. the filepath)
rl.on('line', function(srcpath) {
    optimizeImage(srcpath);
});

Nota: El código anterior usa la versión 1.0.5 de El imagemin API y no la última versión – ¿Por qué? Consulte el punto 1 en la sección Notas adicionales a continuación).


Desinstalar e instalar nuevos paquetes

  1. Primero desinstalar imagemin-cli ya que ya no es necesario:

$ npm un -D imagemin-cli

  1. Siguiente instalar la versión de imagemin 1.0.5 (Este es un paquete más antiguo, por lo que puede tardar npm más de instalar de lo habitual)

$ npm i -D [email protected]

  1. Luego instale cli-glob. Esto se utilizará para especificar el patrón global para que coincida con las imágenes para optimizar.

$ npm i -D cli-glob


npm-scripts

Actualiza tu npm-scripts como sigue:

...
"scripts": {
    "imagemin:prod": "glob "app/src/images/**/*.{png,jpg,gif}" | node bin/imagemin -v -o dist",
    "imagemin:dev": "glob "app/src/images/**/*.{png,jpg,gif}" | node bin/imagemin -v -o .tmp",
    ...
},
...

Nota: Para optimizar las imágenes usando los gists que se muestran arriba, no es necesario usar los dos scripts llamados copy:prod y copy:dev mostrado en su publicación / pregunta original)

  1. los glob "app/src/... parte del script anterior usa cli-glob para hacer coincidir los archivos fuente de imagen necesarios.

  2. Luego, los caminos se canalizan al imagemin.js secuencia de comandos del nodo de utilidad.

  3. Cuando el -v (detallado) argumento / bandera se incluye, luego cada imagen procesada se registra en la consola. Para omitir el registro, simplemente elimine el -v bandera.

  4. los -o El argumento / bandera (de salida) se utiliza para especificar el nombre de la carpeta de destino. P.ej dist o .tmp. Cuando el valor de -o Si se omite, las imágenes resultantes se envían al directorio raíz del proyecto.


Notas adicionales:

  1. La razón para usar imagemin la versión 1.0.5 se debe a que esta API permite src valor que se especificará como una única ruta de archivo. En versiones superiores a 2.0.0 la API espera el src value para ser un patrón glob como se muestra en la última versión 5.2.2.

  2. Las esencias anteriores asumen imagemin.js se guarda en una carpeta llamada bin que existe en la misma carpeta que package.json. Se puede cambiar a un nombre preferido, o una carpeta invisible prefijándolo con un punto [.] p.ej .scripts o .bin. Elija lo que elija, deberá actualizar la ruta al script en npm-scripts respectivamente.

Actualización 2020

Hay una solicitud de extracción no fusionada (a mediados de junio de 2020) de Gijs Rogé que permite preservar la estructura del directorio en el directorio de salida.

Puede instalar módulos npm que aún no figuran en el registro instalando directamente desde Github, haciendo referencia a un repositorio e incluso un compromiso específico:
npm install https://github.com/<username>/<repository>#<commit> --save-dev

Para instalar imagemin con la corrección de Gijs Rogé, ejecute …
npm install https://github.com/imagemin/imagemin#bfd7c547045f68ed92243c6a772f6265a08a687f --save-dev

… y habilite la nueva opción en su script configurando preserveDirectories: true:

// Note: imports and plugin configs have been omitted for brevity

const imagemin = require('imagemin');
const imageminMozjpeg = require('imagemin-mozjpeg');
...

(async () => {
    const files = await imagemin(['input_dir/**/*.{jpg,jpeg,png,svg}'], {
    destination: 'output_dir/',
    ✨preserveDirectories: true,
        plugins: [
            imageminMozjpeg( ... ),
            imageminPngquant( ... ),
            imageminSvgo( ... )
        ]
});

A .jpg encontrado en input_dir/some/sub/dir/image.jpg ahora será procesado y escrito a output_dir/input_dir/some/sub/dir/image.jpg.

Usar destination: '.' para sobrescribir los archivos originales en su lugar.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *