del is now only used for ESM

Issues about del and gulp

Variables

fs-extra better than fs for supressing useless errors

const { rmSync, rmdirSync, existsSync } = require('fs')
const { join } = require('path')
const gulp = require('gulp')
// folder to scan and delete files
const destDir = join(__dirname, 'folder/to/scan')

Using standard gulp.src with ! as ignore

gulp.task('clean', function () {
  return gulp
    // this will delete all files, except .git*,/bin/*
    .src(['**/*', '!^.git*', '!**/bin/*'], { cwd: destDir })
    .pipe(
      through2.obj((file, _enc, next) => {
        if (existsSync(file.path)){
          if (statSync(file.path).isFile()) {
            rmSync(file.path)
          } else {
            rmdirSync(file.path)
          }
        } 
        next()
      })
    )
    .pipe(gulp.dest(destDir))
})

OR you can

Using ignore options like below

gulp.task('clean', function () {
  return gulp
    .src(
      [
        // delete all files and folders
        '**/*'
      ],
      {
        ignore: [
          // keep git files
          '^.git*',
          // keep shortcut script
          '**/bin',
          // keep sitemap
          'sitemap.*',
          // keep CNAME
          'CNAME',
          // keep nojekyll builds
          '.nojekyll',
          // skip removing html, for keep old files on remote
          '**/*.html'
        ],
        cwd: destDir
      }
    )
    .pipe(
      through2.obj((file, _enc, next) => {
        try {
          if (existsSync(file.path))
            rm(file.path, { recursive: true, force: true }, next)
        } catch {
          //
        }
      })
    )
})

My Gulp Clean Script

gulp.task('clean', function () {
  return gulp
    .src(
      [
        // delete all files and folders
        '**/*'
      ],
      {
        ignore: [
          // keep git files
          '^.git*',
          // keep shortcut script
          '**/bin',
          // keep sitemap
          'sitemap.*',
          // keep CNAME
          'CNAME',
          // keep nojekyll builds
          '.nojekyll',
          // skip removing html, for keep old files on remote
          '**/*.html'
        ],
        cwd: destDir
      }
    )
    .pipe(
      through2.obj((file, _enc, next) => {
        try {
          if (existsSync(file.path)) {
            const { path } = file
            const stats = statSync(path)
            if (stats.isFile()) {
              rmSync(path)
            } else {
              rmSync(path, { recursive: true })
            }
            next(null)
          }
        } catch {
          //
        }
      })
    )
})