Skip to content

Replace clean-webpack-plugin with the core output cleaning feature #1313

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

Merged
merged 1 commit into from
Sep 2, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,10 @@ This is a new major version that contains several backwards-compatibility breaks

* #1308 Drop Vue 2 support (End-Of-Life), only Vue 3 is supported (@Kocal)

* #1309 Drop ESLint integration (@Kocal)
* #1309 Drop ESLint integration (@Kocal)

* #1313 Drop `clean-webpack-plugin` in favor of webpack's `output.clean` configuration. The
configuration settings supported by `Encore.cleanupOutputBeforeBuild` have changed (@stof)

* #1317 Drop support of sass-loader ^13 and ^14, add support for sass-loader ^16 (@Kocal)

Expand Down Expand Up @@ -1014,4 +1017,3 @@ for a full description of all of the valid browser descriptions.

* `Encore.cleanupOutputBeforeBuild()` now empties the directory
instead or removing it.

11 changes: 5 additions & 6 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -1491,22 +1491,21 @@ class Encore {
/**
* If enabled, the output directory is emptied between each build (to remove old files).
*
* A list of available options can be found at https://github.com/johnagan/clean-webpack-plugin
* A list of available options can be found at https://webpack.js.org/configuration/output/#outputclean
*
* For example:
*
* ```
* Encore.cleanupOutputBeforeBuild(['*.js'], (options) => {
* Encore.cleanupOutputBeforeBuild((options) => {
* options.dry = true;
* })
* ```
*
* @param {Array} paths Paths that should be cleaned, relative to the "root" option
* @param {Function} cleanWebpackPluginOptionsCallback
* @param {Function} cleanOptionsCallback
* @returns {Encore}
*/
cleanupOutputBeforeBuild(paths = ['**/*'], cleanWebpackPluginOptionsCallback = () => {}) {
webpackConfig.cleanupOutputBeforeBuild(paths, cleanWebpackPluginOptionsCallback);
cleanupOutputBeforeBuild(cleanOptionsCallback = () => {}) {
webpackConfig.cleanupOutputBeforeBuild(cleanOptionsCallback);

return this;
}
Expand Down
18 changes: 5 additions & 13 deletions lib/WebpackConfig.js
Original file line number Diff line number Diff line change
Expand Up @@ -154,11 +154,8 @@ class WebpackConfig {
svelte: () => {},
};

// Plugins options
this.cleanWebpackPluginPaths = ['**/*'];

// Plugins callbacks
this.cleanWebpackPluginOptionsCallback = () => {};
this.cleanOptionsCallback = () => {};
this.definePluginOptionsCallback = () => {};
this.forkedTypeScriptTypesCheckOptionsCallback = () => {};
this.friendlyErrorsPluginOptionsCallback = () => {};
Expand Down Expand Up @@ -844,18 +841,13 @@ class WebpackConfig {
this.fontRuleCallback = ruleCallback;
}

cleanupOutputBeforeBuild(paths = ['**/*'], cleanWebpackPluginOptionsCallback = () => {}) {
if (!Array.isArray(paths)) {
throw new Error('Argument 1 to cleanupOutputBeforeBuild() must be an Array of paths - e.g. [\'**/*\']');
}

if (typeof cleanWebpackPluginOptionsCallback !== 'function') {
throw new Error('Argument 2 to cleanupOutputBeforeBuild() must be a callback function');
cleanupOutputBeforeBuild(cleanOptionsCallback = () => {}) {
if (typeof cleanOptionsCallback !== 'function') {
throw new Error('Argument 1 to cleanupOutputBeforeBuild() must be a callback function');
}

this.cleanupOutput = true;
this.cleanWebpackPluginPaths = paths;
this.cleanWebpackPluginOptionsCallback = cleanWebpackPluginOptionsCallback;
this.cleanOptionsCallback = cleanOptionsCallback;
}

autoProvideVariables(variables) {
Expand Down
15 changes: 12 additions & 3 deletions lib/config-generator.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ const deleteUnusedEntriesPluginUtil = require('./plugins/delete-unused-entries')
const entryFilesManifestPlugin = require('./plugins/entry-files-manifest');
const manifestPluginUtil = require('./plugins/manifest');
const variableProviderPluginUtil = require('./plugins/variable-provider');
const cleanPluginUtil = require('./plugins/clean');
const definePluginUtil = require('./plugins/define');
const terserPluginUtil = require('./plugins/terser');
const optimizeCssAssetsUtil = require('./plugins/optimize-css-assets');
Expand Down Expand Up @@ -247,6 +246,7 @@ class ConfigGenerator {
}

return {
clean: this.buildCleanConfig(),
path: this.webpackConfig.outputPath,
filename: filename,
// default "asset module" filename
Expand All @@ -259,6 +259,17 @@ class ConfigGenerator {
};
}

/**
* @returns {import('webpack').CleanOptions|boolean}
*/
buildCleanConfig() {
if (!this.webpackConfig.cleanupOutput) {
return false;
}

return applyOptionsCallback(this.webpackConfig.cleanOptionsCallback, {});
}

buildRulesConfig() {
const applyRuleConfigurationCallback = (name, defaultRules) => {
return applyOptionsCallback(this.webpackConfig.loaderConfigurationCallbacks[name], defaultRules);
Expand Down Expand Up @@ -460,8 +471,6 @@ class ConfigGenerator {

variableProviderPluginUtil(plugins, this.webpackConfig);

cleanPluginUtil(plugins, this.webpackConfig);

definePluginUtil(plugins, this.webpackConfig);

notifierPluginUtil(plugins, this.webpackConfig);
Expand Down
51 changes: 0 additions & 51 deletions lib/plugins/clean.js

This file was deleted.

1 change: 0 additions & 1 deletion lib/plugins/plugin-priorities.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ module.exports = {
WebpackManifestPlugin: 120,
LoaderOptionsPlugin: 110,
ProvidePlugin: 90,
CleanWebpackPlugin: 80,
DefinePlugin: 70,
WebpackNotifier: 60,
VueLoaderPlugin: 50,
Expand Down
1 change: 0 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@
"assets-webpack-plugin": "7.0.*",
"babel-loader": "^9.1.3",
"chalk": "^4.0.0",
"clean-webpack-plugin": "^4.0.0",
"css-loader": "^6.7.0",
"css-minimizer-webpack-plugin": "^5.0.0",
"fastest-levenshtein": "^1.0.16",
Expand Down
18 changes: 4 additions & 14 deletions test/WebpackConfig.js
Original file line number Diff line number Diff line change
Expand Up @@ -225,33 +225,23 @@ describe('WebpackConfig object', () => {
config.cleanupOutputBeforeBuild();

expect(config.cleanupOutput).to.be.true;
expect(config.cleanWebpackPluginPaths).to.deep.equal(['**/*']);
});

it('Setting paths and callback', () => {
const config = createConfig();
const callback = () => {};
config.cleanupOutputBeforeBuild(['**/*.js', '**/*.css'], callback);
config.cleanupOutputBeforeBuild(callback);

expect(config.cleanupOutput).to.be.true;
expect(config.cleanWebpackPluginPaths).to.deep.equal(['**/*.js', '**/*.css']);
expect(config.cleanWebpackPluginOptionsCallback).to.equal(callback);
});

it('Setting invalid paths argument', () => {
const config = createConfig();

expect(() => {
config.cleanupOutputBeforeBuild('foo', () => {});
}).to.throw('Argument 1 to cleanupOutputBeforeBuild() must be an Array of paths');
expect(config.cleanOptionsCallback).to.equal(callback);
});

it('Setting invalid callback argument', () => {
const config = createConfig();

expect(() => {
config.cleanupOutputBeforeBuild(['**/*'], 'foo');
}).to.throw('Argument 2 to cleanupOutputBeforeBuild() must be a callback function');
config.cleanupOutputBeforeBuild('foo');
}).to.throw('Argument 1 to cleanupOutputBeforeBuild() must be a callback function');
});
});

Expand Down
9 changes: 3 additions & 6 deletions test/config-generator.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ const RuntimeConfig = require('../lib/config/RuntimeConfig');
const configGenerator = require('../lib/config-generator');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const { WebpackManifestPlugin } = require('../lib/webpack-manifest-plugin');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
const webpack = require('webpack');
const path = require('path');
const logger = require('../lib/logger');
Expand Down Expand Up @@ -534,7 +533,7 @@ describe('The config-generator function', () => {
});
});

describe('cleanupOutputBeforeBuild() adds CleanWebpackPlugin', () => {
describe('cleanupOutputBeforeBuild() configures output cleaning', () => {
it('without cleanupOutputBeforeBuild()', () => {
const config = createConfig();
config.outputPath = '/tmp/output/public-path';
Expand All @@ -543,8 +542,7 @@ describe('The config-generator function', () => {

const actualConfig = configGenerator(config);

const cleanPlugin = findPlugin(CleanWebpackPlugin, actualConfig.plugins);
expect(cleanPlugin).to.be.undefined;
expect(actualConfig.output.clean).to.be.false;
});

it('with cleanupOutputBeforeBuild()', () => {
Expand All @@ -556,8 +554,7 @@ describe('The config-generator function', () => {

const actualConfig = configGenerator(config);

const cleanPlugin = findPlugin(CleanWebpackPlugin, actualConfig.plugins);
expect(cleanPlugin).to.not.be.undefined;
expect(actualConfig.output.clean).to.deep.equals({});
});
});

Expand Down
80 changes: 0 additions & 80 deletions test/plugins/clean.js

This file was deleted.

Loading