阿里云主机折上折
  • 微信号
Current Site:Index > CleanWebpackPlugin cleans the build directory

CleanWebpackPlugin cleans the build directory

Author:Chuan Chen 阅读数:31973人阅读 分类: 构建工具

CleanWebpackPlugin Cleans the Build Directory

CleanWebpackPlugin is a commonly used plugin in the webpack ecosystem, primarily designed to clean the output directory before each build. It automatically deletes files generated by previous builds, ensuring the output directory always remains up-to-date and avoiding issues caused by residual old files.

Why Clean the Build Directory?

During the webpack build process, the output directory may accumulate a large number of unnecessary files. For example:

  • Modified output filename configurations
  • Removed certain entry points
  • Use of hash/chunkhash/contenthash
  • Switching between different build environments

If old files are not cleaned, it may lead to:

  1. The development server loading incorrect old resources
  2. Production environments deploying redundant files
  3. Build analysis tools displaying inaccurate data
  4. Disk space being occupied by useless files

Basic Usage

First, install the plugin:

npm install clean-webpack-plugin --save-dev

Then import and use it in the webpack configuration:

const { CleanWebpackPlugin } = require('clean-webpack-plugin');

module.exports = {
  // ...other configurations
  plugins: [
    new CleanWebpackPlugin()
  ]
};

Detailed Configuration Options

CleanWebpackPlugin provides multiple configuration options to meet various needs:

dry

Simulates deletion without actually deleting files:

new CleanWebpackPlugin({
  dry: true  // Default: false
})

verbose

Outputs deletion logs:

new CleanWebpackPlugin({
  verbose: true  // Default: false
})

cleanStaleWebpackAssets

Automatically deletes resources no longer used by webpack:

new CleanWebpackPlugin({
  cleanStaleWebpackAssets: false  // Default: true
})

protectWebpackAssets

Protects resources currently in use by webpack from deletion:

new CleanWebpackPlugin({
  protectWebpackAssets: false  // Default: true
})

cleanOnceBeforeBuildPatterns

Specifies file patterns to delete before building:

new CleanWebpackPlugin({
  cleanOnceBeforeBuildPatterns: [
    '**/*',
    '!static-files*',
    '!directoryToPreserve/**'
  ]
})

dangerouslyAllowCleanPatternsOutsideProject

Allows cleaning files outside the project directory (use with caution):

new CleanWebpackPlugin({
  dangerouslyAllowCleanPatternsOutsideProject: true  // Default: false
})

Advanced Usage Scenarios

Usage in Multi-Configuration Projects

In multi-configuration webpack projects, different cleanup strategies can be applied to different configurations:

module.exports = [{
  name: 'client',
  output: {
    path: path.resolve(__dirname, 'dist/client')
  },
  plugins: [
    new CleanWebpackPlugin({
      cleanOnceBeforeBuildPatterns: ['**/*', '!shared/**']
    })
  ]
}, {
  name: 'server',
  output: {
    path: path.resolve(__dirname, 'dist/server')
  },
  plugins: [
    new CleanWebpackPlugin()
  ]
}];

Preserving Specific Files

Sometimes it's necessary to preserve special files (e.g., README.md):

new CleanWebpackPlugin({
  cleanOnceBeforeBuildPatterns: [
    '**/*',
    '!README.md',
    '!*.json'
  ]
})

Custom Deletion Function

More complex cleanup logic can be implemented using custom functions:

new CleanWebpackPlugin({
  cleanAfterEveryBuildPatterns: ['static/**/*'],
  dangerouslyAllowCleanPatternsOutsideProject: true,
  beforeEmit: (compilation, patterns) => {
    console.log('About to clean the following files:', patterns);
    return Promise.resolve();
  }
})

Integration with Other Plugins

Integration with html-webpack-plugin

Ensures HTML files are correctly cleaned and regenerated:

plugins: [
  new CleanWebpackPlugin(),
  new HtmlWebpackPlugin({
    template: './src/index.html'
  })
]

Integration with copy-webpack-plugin

Handles cleanup issues when copying static resources:

plugins: [
  new CleanWebpackPlugin(),
  new CopyWebpackPlugin({
    patterns: [
      { from: 'public', to: 'assets' }
    ]
  })
]

Common Issue Resolution

File Deletion Permission Issues

On Windows systems, permission errors may occur. Try:

new CleanWebpackPlugin({
  cleanOnceBeforeBuildPatterns: ['**/*'],
  dangerouslyAllowCleanPatternsOutsideProject: true,
  dry: false,
  beforeEmit: async () => {
    await new Promise(resolve => setTimeout(resolve, 500));
  }
})

Excluding node_modules

Avoid accidentally deleting dependencies:

new CleanWebpackPlugin({
  cleanOnceBeforeBuildPatterns: [
    '**/*',
    '!node_modules/**'
  ]
})

Handling Symbolic Links

Handling symbolic links in the project:

new CleanWebpackPlugin({
  handleSymlinks: true  // Default: false
})

Performance Optimization Recommendations

  1. Disable the plugin in development mode to speed up builds:
plugins: [
  process.env.NODE_ENV === 'production' && new CleanWebpackPlugin()
].filter(Boolean)
  1. For large projects, limit the cleanup scope:
new CleanWebpackPlugin({
  cleanOnceBeforeBuildPatterns: ['js/**', 'css/**']
})
  1. Use caching to avoid repeated cleanup:
new CleanWebpackPlugin({
  cleanOnceBeforeBuildPatterns: [],
  cleanAfterEveryBuildPatterns: ['tmp/**']
})

Version Compatibility Notes

Different versions of CleanWebpackPlugin have significant differences:

  • v1.x: Basic functionality
  • v2.x: Introduces more configuration options
  • v3.x: Supports webpack 5
  • v4.x: Complete refactor, major API changes

It's recommended to check the documentation for the corresponding version:

// Import method for v3.x and below
const CleanWebpackPlugin = require('clean-webpack-plugin');

// Import method for v4.x+
const { CleanWebpackPlugin } = require('clean-webpack-plugin');

Alternative Solutions Comparison

Besides CleanWebpackPlugin, other cleanup solutions include:

  1. Using rimraf for manual cleanup:
// package.json
{
  "scripts": {
    "clean": "rimraf dist",
    "build": "npm run clean && webpack"
  }
}
  1. Using the shelljs plugin:
const shell = require('shelljs');

class CleanPlugin {
  apply(compiler) {
    compiler.hooks.beforeRun.tap('CleanPlugin', () => {
      shell.rm('-rf', 'dist/*');
    });
  }
}

In comparison, CleanWebpackPlugin offers:

  • More precise file pattern control
  • Deeper integration with the webpack build process
  • Better cross-platform compatibility
  • Safer default behavior

Best Practices in Real Projects

  1. Differentiate environment configurations:
const cleanOptions = {
  verbose: process.env.NODE_ENV !== 'production',
  dry: process.env.DRY_RUN === 'true',
  cleanOnceBeforeBuildPatterns: [
    '**/*',
    '!config.json',
    ...(process.env.NODE_ENV === 'development' ? ['!test-coverage/**'] : [])
  ]
};

plugins: [
  new CleanWebpackPlugin(cleanOptions)
]
  1. Shared configuration for multiple projects:
// shared-webpack-config.js
module.exports.cleanPlugin = (options = {}) => new CleanWebpackPlugin({
  cleanOnceBeforeBuildPatterns: ['**/*'],
  ...options
});

// webpack.config.js
const { cleanPlugin } = require('./shared-webpack-config');

module.exports = {
  plugins: [
    cleanPlugin({
      verbose: true
    })
  ]
};
  1. Integration with CI/CD:
new CleanWebpackPlugin({
  cleanOnceBeforeBuildPatterns: [
    '**/*',
    process.env.CI ? '!ci-lockfile.json' : '!.env.local'
  ]
})

Plugin Internal Mechanism Analysis

The workflow of CleanWebpackPlugin is roughly as follows:

  1. Registers cleanup tasks in webpack's beforeRun hook
  2. Analyzes configured file patterns
  3. Uses globby to match files
  4. Uses the del library to perform deletions
  5. Handles potential errors and warnings
  6. Executes subsequent cleanup in the afterEmit hook (if configured)

Key source code snippet:

apply(compiler) {
  compiler.hooks.beforeRun.tapPromise(pluginName, () => this.handleInitial());
  compiler.hooks.watchRun.tapPromise(pluginName, () => this.handleInitial());
  compiler.hooks.afterEmit.tapPromise(pluginName, (compilation) => 
    this.handleAfterEmit(compilation));
}

async handleInitial() {
  const { remove, paths } = await this.getPaths();
  if (remove.length > 0) {
    await this.removeFiles(remove);
  }
  return { remove, paths };
}

Custom Cleanup Plugin Development

For more specialized functionality, you can extend CleanWebpackPlugin:

class CustomCleanPlugin extends CleanWebpackPlugin {
  async handleAfterEmit(compilation) {
    await super.handleAfterEmit(compilation);
    // Custom logic
    await this.removeFiles(['temp/*.log']);
  }
  
  async getPaths() {
    const result = await super.getPaths();
    return {
      ...result,
      remove: [...result.remove, 'extra-file.txt']
    };
  }
}

Testing Strategy Recommendations

To ensure cleanup functionality works correctly, it's recommended to:

  1. Write unit tests to verify file pattern matching
  2. Conduct integration tests to check actual filesystem changes
  3. Use dry mode for pre-checks
  4. Test behavior across different operating systems

Example test code:

describe('CleanWebpackPlugin', () => {
  it('should match correct files', async () => {
    const plugin = new CleanWebpackPlugin({
      cleanOnceBeforeBuildPatterns: ['**/*.js', '!vendor.js']
    });
    const { remove } = await plugin.getPaths();
    expect(remove).toContain('app.js');
    expect(remove).not.toContain('vendor.js');
  });
});

Security Considerations

  1. Never configure dangerouslyAllowCleanPatternsOutsideProject: true unless absolutely necessary
  2. Avoid using relative paths like ../../
  3. Verify cleanup rules in a test environment before production deployment
  4. Keep backups of important files

Example of a dangerous configuration:

// Dangerous configuration! May delete system files
new CleanWebpackPlugin({
  cleanOnceBeforeBuildPatterns: ['**/*'],
  dangerouslyAllowCleanPatternsOutsideProject: true
})

Debugging Tips

When cleanup behavior doesn't meet expectations:

  1. Enable verbose mode to view detailed logs
  2. Use dry runs to simulate deletions
  3. Check if file patterns correctly target the intended files
  4. Verify the current working directory is correct
new CleanWebpackPlugin({
  verbose: true,
  dry: true,
  cleanOnceBeforeBuildPatterns: ['**/*.js']
})

本站部分内容来自互联网,一切版权均归源网站或源作者所有。

如果侵犯了你的权益请来信告知我们删除。邮箱:cc@cccx.cn

Front End Chuan

Front End Chuan, Chen Chuan's Code Teahouse 🍵, specializing in exorcising all kinds of stubborn bugs 💻. Daily serving baldness-warning-level development insights 🛠️, with a bonus of one-liners that'll make you laugh for ten years 🐟. Occasionally drops pixel-perfect romance brewed in a coffee cup ☕.