CleanWebpackPlugin cleans the build directory
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:
- The development server loading incorrect old resources
- Production environments deploying redundant files
- Build analysis tools displaying inaccurate data
- 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
- Disable the plugin in development mode to speed up builds:
plugins: [
process.env.NODE_ENV === 'production' && new CleanWebpackPlugin()
].filter(Boolean)
- For large projects, limit the cleanup scope:
new CleanWebpackPlugin({
cleanOnceBeforeBuildPatterns: ['js/**', 'css/**']
})
- 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:
- Using rimraf for manual cleanup:
// package.json
{
"scripts": {
"clean": "rimraf dist",
"build": "npm run clean && webpack"
}
}
- 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
- 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)
]
- 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
})
]
};
- 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:
- Registers cleanup tasks in webpack's
beforeRun
hook - Analyzes configured file patterns
- Uses
globby
to match files - Uses the
del
library to perform deletions - Handles potential errors and warnings
- 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:
- Write unit tests to verify file pattern matching
- Conduct integration tests to check actual filesystem changes
- Use dry mode for pre-checks
- 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
- Never configure
dangerouslyAllowCleanPatternsOutsideProject: true
unless absolutely necessary - Avoid using relative paths like
../../
- Verify cleanup rules in a test environment before production deployment
- 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:
- Enable verbose mode to view detailed logs
- Use dry runs to simulate deletions
- Check if file patterns correctly target the intended files
- Verify the current working directory is correct
new CleanWebpackPlugin({
verbose: true,
dry: true,
cleanOnceBeforeBuildPatterns: ['**/*.js']
})
本站部分内容来自互联网,一切版权均归源网站或源作者所有。
如果侵犯了你的权益请来信告知我们删除。邮箱:cc@cccx.cn