Skip to content

Commit

Permalink
add protectWebpackAssets option
Browse files Browse the repository at this point in the history
  • Loading branch information
chrisblossom committed Mar 4, 2019
1 parent f506dc6 commit 03d12ac
Show file tree
Hide file tree
Showing 3 changed files with 168 additions and 7 deletions.
7 changes: 7 additions & 0 deletions README.md
Expand Up @@ -70,6 +70,13 @@ new CleanWebpackPlugin({
*/
cleanStaleWebpackAssets: false,

/**
* Do not allow removal of current webpack assets
*
* default: true
*/
protectWebpackAssets: false,

/**
* **WARNING**
*
Expand Down
143 changes: 143 additions & 0 deletions src/clean-webpack-plugin.test.ts
Expand Up @@ -380,6 +380,149 @@ describe('cleanStaleWebpackAssets option', () => {
});
});

describe('protectWebpackAssets option', () => {
test('protectWebpackAssets true will not remove webpack assets', async () => {
createSrcBundle(2);
createStaticFiles();

const cleanWebpackPlugin = new CleanWebpackPlugin({
cleanAfterEveryBuildPatterns: ['bundle.js'],
protectWebpackAssets: true,
});

const compiler = webpack({
entry: entryFileFull,
output: {
path: outputPathFull,
filename: 'bundle.js',
chunkFilename: '[name].bundle.js',
},
plugins: [cleanWebpackPlugin],
});

expect(cleanWebpackPlugin.currentAssets).toEqual([]);

await compiler.run();

expect(cleanWebpackPlugin.currentAssets).toEqual([
'1.bundle.js',
'bundle.js',
]);

expect(sandbox.getFileListSync(outputPathFull)).toEqual([
'1.bundle.js',
'bundle.js',
]);

createSrcBundle(1);
createStaticFiles();

await compiler.run();

expect(cleanWebpackPlugin.currentAssets).toEqual(['bundle.js']);

expect(sandbox.getFileListSync(outputPathFull)).toEqual([
'.hidden.file',
'bundle.js',
'static1.js',
'static2.txt',
]);
});

test('protectWebpackAssets undefined will not remove webpack assets', async () => {
createSrcBundle(2);
createStaticFiles();

const cleanWebpackPlugin = new CleanWebpackPlugin({
cleanAfterEveryBuildPatterns: ['bundle.js'],
});

const compiler = webpack({
entry: entryFileFull,
output: {
path: outputPathFull,
filename: 'bundle.js',
chunkFilename: '[name].bundle.js',
},
plugins: [cleanWebpackPlugin],
});

expect(cleanWebpackPlugin.currentAssets).toEqual([]);

await compiler.run();

expect(cleanWebpackPlugin.currentAssets).toEqual([
'1.bundle.js',
'bundle.js',
]);

expect(sandbox.getFileListSync(outputPathFull)).toEqual([
'1.bundle.js',
'bundle.js',
]);

createSrcBundle(1);
createStaticFiles();

await compiler.run();

expect(cleanWebpackPlugin.currentAssets).toEqual(['bundle.js']);

expect(sandbox.getFileListSync(outputPathFull)).toEqual([
'.hidden.file',
'bundle.js',
'static1.js',
'static2.txt',
]);
});

test('protectWebpackAssets false will remove webpack assets', async () => {
createSrcBundle(2);
createStaticFiles();

const cleanWebpackPlugin = new CleanWebpackPlugin({
cleanAfterEveryBuildPatterns: ['bundle.js'],
protectWebpackAssets: false,
});

const compiler = webpack({
entry: entryFileFull,
output: {
path: outputPathFull,
filename: 'bundle.js',
chunkFilename: '[name].bundle.js',
},
plugins: [cleanWebpackPlugin],
});

expect(cleanWebpackPlugin.currentAssets).toEqual([]);

await compiler.run();

expect(cleanWebpackPlugin.currentAssets).toEqual([
'1.bundle.js',
'bundle.js',
]);

expect(sandbox.getFileListSync(outputPathFull)).toEqual([
'1.bundle.js',
]);

createSrcBundle(1);
createStaticFiles();

await compiler.run();

expect(cleanWebpackPlugin.currentAssets).toEqual(['bundle.js']);

expect(sandbox.getFileListSync(outputPathFull)).toEqual([
'.hidden.file',
'static1.js',
'static2.txt',
]);
});
});

describe('cleanOnceBeforeBuildPatterns option', () => {
test('does nothing when nothing changes or files added but not removed', async () => {
createSrcBundle(1);
Expand Down
25 changes: 18 additions & 7 deletions src/clean-webpack-plugin.ts
@@ -1,6 +1,6 @@
import { Compiler, Stats } from 'webpack';
import path from 'path';
import del, { Options as DelOptions } from 'del';
import del from 'del';

interface Options {
/**
Expand All @@ -25,6 +25,13 @@ interface Options {
*/
cleanStaleWebpackAssets: boolean;

/**
* Do not allow removal of current webpack assets
*
* default: true
*/
protectWebpackAssets: boolean;

/**
* Removes files after every build (including watch mode) that match this pattern.
* Used for files that are not created directly by Webpack.
Expand Down Expand Up @@ -59,6 +66,7 @@ class CleanWebpackPlugin {
private readonly dry: boolean;
private readonly verbose: boolean;
private readonly cleanStaleWebpackAssets: boolean;
private readonly protectWebpackAssets: boolean;
private readonly cleanAfterEveryBuildPatterns: string[];
private readonly cleanOnceBeforeBuildPatterns: string[];
private readonly dangerouslyAllowCleanPatternsOutsideProject: boolean;
Expand Down Expand Up @@ -108,6 +116,12 @@ class CleanWebpackPlugin {
? options.cleanStaleWebpackAssets
: true;

this.protectWebpackAssets =
options.protectWebpackAssets === true ||
options.protectWebpackAssets === false
? options.protectWebpackAssets
: true;

this.cleanAfterEveryBuildPatterns = Array.isArray(
options.cleanAfterEveryBuildPatterns,
)
Expand Down Expand Up @@ -246,22 +260,19 @@ class CleanWebpackPlugin {
* Run cleanAfterEveryBuildPatterns
*/
if (this.cleanAfterEveryBuildPatterns.length !== 0) {
this.removeFiles(this.cleanAfterEveryBuildPatterns, {
// Never remove current webpack assets
ignore: this.currentAssets,
});
this.removeFiles(this.cleanAfterEveryBuildPatterns);
}
}

removeFiles(patterns: string[], delOptions: DelOptions = {}) {
removeFiles(patterns: string[]) {
try {
const deleted = del.sync(patterns, {
force: this.dangerouslyAllowCleanPatternsOutsideProject,
// Change context to build directory
cwd: this.outputPath,
dryRun: this.dry,
dot: true,
...delOptions,
ignore: this.protectWebpackAssets ? this.currentAssets : [],
});

/**
Expand Down

0 comments on commit 03d12ac

Please sign in to comment.