Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Custom plugin settings: TypeError: imagemin.<plugin name> is not a function #365

Open
replete opened this issue Oct 7, 2021 · 2 comments

Comments

@replete
Copy link

replete commented Oct 7, 2021

Error

[18:25:48] TypeError: imagemin.optipng is not a function

Doesn't seem to detect any of the plugins and fails on whatever it hits first, in the above error imagemin.optipng. I've tried adding imagemin and imagemin-* packages to my repository, but this does not help.

My implementation appears to match the package expectations. Am I missing something here?

Environment

node v16.10.0
npm 7.24.0
macOS Catalina 10.15.7

gulpfile.js

// gulpfile.js
import gulp from 'gulp';
import gulpSass from 'gulp-sass';
import dartSass from 'sass';
import del from 'del';
import browserSync from 'browser-sync';
import imagemin from 'gulp-imagemin';
import fancyLog from 'fancy-log';

const sass = gulpSass(dartSass);
const browserSyncServer = browserSync.create('LocalDevServer');

const paths = {
    distributables: 'dist',
    documents: {
        source: 'src/**/*.html',
        destination: 'dist'
    },
    styles: {
        source: 'src/styles/**/*.scss',
        destination: 'dist/styles/'
    },
    scripts: {
        source: 'src/scripts/**/*.js',
        destination: 'dist/scripts'
    },
    images: {
        source: 'src/images/**/*.{png,jpg,jpeg,webp,gif}',
        destination: 'dist/images'
    }
}

fancyLog(typeof imagemin);

function clean() { 
    return del([paths.distributables]);
}

function documents() {
    return gulp.src(paths.documents.source,{since: gulp.lastRun(documents)})
        .pipe(gulp.dest(paths.documents.destination));
}

function styles() {
    return gulp.src(paths.styles.source)
        .pipe(sass.sync().on('error', sass.logError))
        // sass.sync() is faster than sass(): https://github.com/dlmanning/gulp-sass
        .pipe(gulp.dest(paths.styles.destination))
        .pipe(browserSyncServer.stream());
}

function scripts() {
    return gulp.src(paths.scripts.source)
        .pipe(gulp.dest(paths.scripts.destination));
}

function images() {
    return gulp.src(paths.images.source, {since: gulp.lastRun(images)})
        .pipe(imagemin([
            imagemin.optipng({ optimizationLevel: 5 }), 
            imagemin.svgo({
                plugins: [
                    { removeViewBox: true },
                    { cleanupIDs: false }
                ]
            }),
            imagemin.mozjpeg({ quality: 75, progressive: false })
        ]))
        .pipe(gulp.dest(paths.images.destination));
}

function watchFiles(done) {
    gulp.watch(paths.documents.source, gulp.series(documents, browserSyncReload));
    gulp.watch(paths.styles.source, styles);
    gulp.watch(paths.scripts.source, gulp.series(scripts, browserSyncReload));
    gulp.watch(paths.images.source, images);
    done();
}

function serve(done) {
    browserSyncServer.init({
        server: {
            baseDir: `${paths.distributables}`,
        },
        open: false
    });
    done();
}

function browserSyncReload(done) {
    browserSyncServer.reload();
    done();
}

const build = gulp.series(
    clean, 
    gulp.parallel(
        documents,
        styles, 
        scripts, 
        images
    )
);

const dev = gulp.series(
    clean, 
    build, 
    gulp.parallel(
        watchFiles, 
        serve
    )
);

export { 
    clean, 
    documents,
    styles, 
    scripts,
    images,
    watchFiles as watch,
    serve,
    build,
    dev
}
export default build;

package.json

// package.json
{
  "name": "frontend-boilerplate",
  "version": "1.0.0",
  "description": "Frontend boilerplate 2021",
  "main": "gulpfile.js",
  "type": "module",
  "scripts": {
    "start": "gulp dev"
  },
  "keywords": [
    "frontend",
    "javascript",
    "gulp"
  ],
  "author": "Phil Ricketts",
  "license": "UNLICENSED",
  "homepage": "https://github.com/replete/frontend-boilerplate#readme",
  "devDependencies": {
    "browser-sync": "^2.27.5",
    "del": "^6.0.0",
    "fancy-log": "^1.3.3",
    "gulp": "^4.0.2",
    "gulp-imagemin": "^8.0.0",
    "gulp-sass": "^5.0.0",
    "sass": "^1.42.1"
  }
}
@replete
Copy link
Author

replete commented Oct 8, 2021

Workaround solution

The problem is resolved by importing the imagemin modules directly after adding the packages to the local project.

I guess the fix is to either update the docs, or move the imagemin from optionalDependencies into devDependencies?

package.json

  "devDependencies": {
    "browser-sync": "^2.27.5",
    "del": "^6.0.0",
    "fancy-log": "^1.3.3",
    "gulp": "^4.0.2",
    "gulp-imagemin": "^8.0.0",
    "gulp-sass": "^5.0.0",
+  "imagemin": "^8.0.1",
+  "imagemin-mozjpeg": "^9.0.0",
+  "imagemin-optipng": "^8.0.0",
+  "imagemin-svgo": "^10.0.0",
    "sass": "^1.42.1"
  }

gulpfile.js diff

 import gulpSass from 'gulp-sass';
 import dartSass from 'sass';
 import del from 'del';
 import browserSync from 'browser-sync';
 import imagemin from 'gulp-imagemin';
+import imageminOptipng from 'imagemin-optipng';
+import imageminSvgo from 'imagemin-svgo';
+import imageminMozjpeg from 'imagemin-svgo';
 import fancyLog from 'fancy-log';


 function images() {
     return gulp.src(paths.images.source, {since: gulp.lastRun(images)})
+        .pipe(imagemin([
+            imageminOptipng({ optimizationLevel: 5 }),
+            imageminSvgo({
+                plugins: [
+                    { removeViewBox: true },
+                    { cleanupIDs: false }
+                ]
+            }),
+            imageminMozjpeg({ quality: 75, progressive: false })
+        ]))
         .pipe(gulp.dest(paths.images.destination));
 }

@replete
Copy link
Author

replete commented Oct 8, 2021

Although this workaround introduces this deprecation warning from imagemin-svgo. I will raise an issue there and link to this issue.

(node:28326) [DEP0151] DeprecationWarning: No "main" or "exports" field defined in the package.json for /Users/user/dev/frontend-boilerplate/node_modules/imagemin-svgo/ resolving the main entry point "index.js", imported from /Users/user/dev/frontend-boilerplate/gulpfile.js.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant