Skip to content
This repository was archived by the owner on Dec 5, 2019. It is now read-only.

Commit beaf1ad

Browse files
authoredDec 18, 2018
fix: dedupe extracted comments (#383)
1 parent 1e58c99 commit beaf1ad

File tree

6 files changed

+801
-1333
lines changed

6 files changed

+801
-1333
lines changed
 

‎src/index.js

+46-33
Original file line numberDiff line numberDiff line change
@@ -267,7 +267,8 @@ class UglifyJsPlugin {
267267

268268
results.forEach((data, index) => {
269269
const { file, input, inputSourceMap, commentsFile } = tasks[index];
270-
const { error, map, code, warnings, extractedComments } = data;
270+
const { error, map, code, warnings } = data;
271+
let { extractedComments } = data;
271272

272273
let sourceMap = null;
273274

@@ -306,44 +307,56 @@ class UglifyJsPlugin {
306307

307308
// Write extracted comments to commentsFile
308309
if (commentsFile && extractedComments.length > 0) {
309-
// Add a banner to the original file
310-
if (this.options.extractComments.banner !== false) {
311-
let banner =
312-
this.options.extractComments.banner ||
313-
`For license information please see ${path.posix.basename(
314-
commentsFile
315-
)}`;
316-
317-
if (typeof banner === 'function') {
318-
banner = banner(commentsFile);
319-
}
310+
if (commentsFile in compilation.assets) {
311+
const commentsFileSource = compilation.assets[
312+
commentsFile
313+
].source();
320314

321-
if (banner) {
322-
outputSource = new ConcatSource(
323-
`/*! ${banner} */\n`,
324-
outputSource
325-
);
326-
}
315+
extractedComments = extractedComments.filter(
316+
(comment) => !commentsFileSource.includes(comment)
317+
);
327318
}
328319

329-
const commentsSource = new RawSource(
330-
`${extractedComments.join('\n\n')}\n`
331-
);
320+
if (extractedComments.length > 0) {
321+
// Add a banner to the original file
322+
if (this.options.extractComments.banner !== false) {
323+
let banner =
324+
this.options.extractComments.banner ||
325+
`For license information please see ${path.posix.basename(
326+
commentsFile
327+
)}`;
328+
329+
if (typeof banner === 'function') {
330+
banner = banner(commentsFile);
331+
}
332+
333+
if (banner) {
334+
outputSource = new ConcatSource(
335+
`/*! ${banner} */\n`,
336+
outputSource
337+
);
338+
}
339+
}
332340

333-
if (commentsFile in compilation.assets) {
334-
// commentsFile already exists, append new comments...
335-
if (compilation.assets[commentsFile] instanceof ConcatSource) {
336-
compilation.assets[commentsFile].add('\n');
337-
compilation.assets[commentsFile].add(commentsSource);
341+
const commentsSource = new RawSource(
342+
`${extractedComments.join('\n\n')}\n`
343+
);
344+
345+
if (commentsFile in compilation.assets) {
346+
// commentsFile already exists, append new comments...
347+
if (compilation.assets[commentsFile] instanceof ConcatSource) {
348+
compilation.assets[commentsFile].add('\n');
349+
compilation.assets[commentsFile].add(commentsSource);
350+
} else {
351+
compilation.assets[commentsFile] = new ConcatSource(
352+
compilation.assets[commentsFile],
353+
'\n',
354+
commentsSource
355+
);
356+
}
338357
} else {
339-
compilation.assets[commentsFile] = new ConcatSource(
340-
compilation.assets[commentsFile],
341-
'\n',
342-
commentsSource
343-
);
358+
compilation.assets[commentsFile] = commentsSource;
344359
}
345-
} else {
346-
compilation.assets[commentsFile] = commentsSource;
347360
}
348361
}
349362

‎src/minify.js

+9-3
Original file line numberDiff line numberDiff line change
@@ -115,15 +115,21 @@ const buildComments = (options, uglifyOptions, extractedComments) => {
115115
}
116116
});
117117

118+
// Redefine the comments function to extract and preserve
119+
// comments according to the two conditions
118120
// Redefine the comments function to extract and preserve
119121
// comments according to the two conditions
120122
return (astNode, comment) => {
121123
if (condition.extract(astNode, comment)) {
122-
extractedComments.push(
124+
const commentText =
123125
comment.type === 'comment2'
124126
? `/*${comment.value}*/`
125-
: `//${comment.value}`
126-
);
127+
: `//${comment.value}`;
128+
129+
// Don't include duplicate comments
130+
if (!extractedComments.includes(commentText)) {
131+
extractedComments.push(commentText);
132+
}
127133
}
128134

129135
return condition.preserve(astNode, comment);

‎test/__snapshots__/extractComments-option.test.js.snap

+674-1,297
Large diffs are not rendered by default.

‎test/extractComments-option.test.js

+50
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ describe('when applied with `extractComments` option', () => {
1010
entry: {
1111
one: `${__dirname}/fixtures/comments.js`,
1212
two: `${__dirname}/fixtures/comments-2.js`,
13+
three: `${__dirname}/fixtures/comments-3.js`,
14+
four: `${__dirname}/fixtures/comments-4.js`,
1315
},
1416
output: {
1517
filename: 'filename/[name].[chunkhash].js',
@@ -296,4 +298,52 @@ describe('when applied with `extractComments` option', () => {
296298
}
297299
});
298300
});
301+
302+
it('matches snapshot for a `true` value and dedupe duplicate comments', () => {
303+
new UglifyJsPlugin({ extractComments: true }).apply(compiler);
304+
305+
return compile(compiler).then((stats) => {
306+
const errors = stats.compilation.errors.map(cleanErrorStack);
307+
const warnings = stats.compilation.warnings.map(cleanErrorStack);
308+
309+
expect(errors).toMatchSnapshot('errors');
310+
expect(warnings).toMatchSnapshot('warnings');
311+
312+
for (const file in stats.compilation.assets) {
313+
if (
314+
Object.prototype.hasOwnProperty.call(stats.compilation.assets, file)
315+
) {
316+
expect(stats.compilation.assets[file].source()).toMatchSnapshot(file);
317+
}
318+
}
319+
});
320+
});
321+
322+
it('matches snapshot for a object value (extracts comments to a single file) and dedupe duplicate comments', () => {
323+
new UglifyJsPlugin({
324+
extractComments: {
325+
condition: true,
326+
filename: 'extracted-comments.js',
327+
banner(licenseFile) {
328+
return `License information can be found in ${licenseFile}`;
329+
},
330+
},
331+
}).apply(compiler);
332+
333+
return compile(compiler).then((stats) => {
334+
const errors = stats.compilation.errors.map(cleanErrorStack);
335+
const warnings = stats.compilation.warnings.map(cleanErrorStack);
336+
337+
expect(errors).toMatchSnapshot('errors');
338+
expect(warnings).toMatchSnapshot('warnings');
339+
340+
for (const file in stats.compilation.assets) {
341+
if (
342+
Object.prototype.hasOwnProperty.call(stats.compilation.assets, file)
343+
) {
344+
expect(stats.compilation.assets[file].source()).toMatchSnapshot(file);
345+
}
346+
}
347+
});
348+
});
299349
});

‎test/fixtures/comments-3.js

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
/**
2+
* Duplicate comment in same file.
3+
* @license MIT
4+
*/
5+
6+
/**
7+
* Duplicate comment in same file.
8+
* @license MIT
9+
*/
10+
11+
/**
12+
* Duplicate comment in difference files.
13+
* @license MIT
14+
*/
15+
16+
module.exports = Math.random();

‎test/fixtures/comments-4.js

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
/**
2+
* Duplicate comment in difference files.
3+
* @license MIT
4+
*/
5+
6+
module.exports = Math.random();

0 commit comments

Comments
 (0)
This repository has been archived.