Skip to content

UglifyJsPlugin: extract comments to separate file - #4134

Merged
sokra merged 2 commits into
webpack:masterfrom
SebastianS90:uglifyjs-extract-comments
Feb 15, 2017
Merged

sokra merged 2 commits into
webpack:masterfrom
SebastianS90:uglifyjs-extract-comments

Conversation

@SebastianS90

@SebastianS90 SebastianS90 commented Jan 30, 2017 •

Copy link
Copy Markdown
Contributor

What kind of change does this PR introduce?

feature in UglifyJsPlugin

Did you add tests for your changes?

yes

If relevant, link to documentation update:

Not yet, I will create a documentation PR if you agree with this feature

Summary

License comments use up a lot of space, especially when using many small libraries with large license blocks. With this addition, you can extract all license comments to a separate file and remove them from the bundle files. A small banner points to the file containing all license information such that the user can find it if needed.

Does this PR introduce a breaking change?

No

Other information

This PR adds a new option extractComments to the UglifyJsPlugin.
It can be omitted, then the behavior does not change, or it can be:

  • true: All comments that normally would be preserved by the comments option will be moved to a separate file. If the original file is named foo.js, then the comments will be stored to foo.js.LICENSE
  • regular expression (given as RegExp or string) or a function (astNode, comment) -> boolean:
    All comments that match the given expression (resp. are evaluated to true by the function) will be extracted to the separate file. The comments option specifies whether the comment will be preserved, i.e. it is possible to preserve some comments (e.g. annotations) while extracting others or even preserving comments that have been extracted.
  • an object consisting of the following keys, all optional:
    • condition: regular expression or function (see previous point)
    • filename: The file where the extracted comments will be stored. Can be either a string or function (string) -> string which will be given the original filename. Default is to append the suffix .LICENSE to the original filename.
    • banner: The banner text that points to the extracted file and will be added on top of the original file. will be added to the original file. Can be false (no banner), a string, or a function (string) -> string that will be called with the filename where extracted comments have been stored. Will be wrapped into comment.
      Default: /*! For license information please see foo.js.LICENSE */

@SebastianS90

Copy link
Copy Markdown
Contributor Author

@sokra I added more tests and the coverage checks now succeed.
Let me know whether you plan to merge it. If so, then I'll open a PR to webpack-contrib/uglifyjs-webpack-plugin to document my addition. Should I also create a PR with code changes to that repo (it contains the standalone version of this plugin)?

@SebastianS90

Copy link
Copy Markdown
Contributor Author

@sokra I've just rebased this PR onto master to resolve conflicts. Anything else I need to do in order to get it merged?

License comments use up a lot of space, especially when using many small
libraries with large license blocks. With this addition, you can extract
all license comments to a separate file and remove them from the bundle
files. A small banner points to the file containing all license
information such that the user can find it if needed.

We add a new option extractComments to the UglifyJsPlugin.
It can be omitted, then the behavior does not change, or it can be:
- true: All comments that normally would be preserved by the comments
    option will be moved to a separate file. If the original file is
    named foo.js, then the comments will be stored to foo.js.LICENSE
- regular expression (given as RegExp or string) or a function
  (astNode, comment) -> boolean: All comments that match the given
    expression (resp. are evaluated to true by the function) will be
    extracted to the separate file. The comments option specifies
    whether the comment will be preserved, i.e. it is possible to
    preserve some comments (e.g. annotations) while extracting others or
    even preserving comments that have been extracted.
- an object consisting of the following keys, all optional:
  - condition: regular expression or function (see previous point)
  - file: The file where the extracted comments will be stored. Can be
      either a string (filename) or function (string) -> string which
      will be given the original filename. Default is to append the
      suffix .LICENSE to the original filename.
  - banner: The banner text that points to the extracted file and will
      be added on top of the original file. will be added to the
      original file. Can be false (no banner), a string, or a function
      (string) -> string that will be called with the filename where
      extracted comments have been stored. Will be wrapped into comment.
      Default: /*! For license information please see foo.js.LICENSE */
Comment thread lib/optimize/UglifyJsPlugin.js Outdated
case "boolean":
var b = condition[key];
condition[key] = () => b;
case "function": // eslint-disable-line no-fallthrough

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There should be a break before this line and the eslint comment removed.

Comment thread lib/optimize/UglifyJsPlugin.js Outdated
break;
}
condition[key] = new RegExp(condition[key]);
default: // eslint-disable-line no-fallthrough

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe solve this without fallthrough. It requires an additional line but is more readable..

Comment thread lib/optimize/UglifyJsPlugin.js Outdated
new SourceMapSource(stringifiedStream, file, JSON.parse(map), input, inputSourceMap) :
new RawSource(stringifiedStream));
if(extractedComments.length > 0) {
let commentsFile = options.extractComments.file || file + ".LICENSE";

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

extractComments.file -> extractComments.filename to be consistent with other webpack options.

Comment thread lib/optimize/UglifyJsPlugin.js Outdated
banner = banner(commentsFile);
}
if(banner) {
asset.__UglifyJsPlugin = compilation.assets[file] = new ConcatSource(

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

only write to asset.__UglifyJsPlugin = compilation.assets[file] = once in the UglifyJsPlugin. Use a local variable to keep the uglify result source and reassign this. Add asset.__UglifyJsPlugin = compilation.assets[file] = source to the end of the plugin.

@SebastianS90

Copy link
Copy Markdown
Contributor Author

@sokra thanks for your review, I added a commit to resolve all comments.

@sokra
sokra merged commit d0f1f6e into webpack:master Feb 15, 2017
@sokra

sokra commented Feb 15, 2017

Copy link
Copy Markdown
Member

Thanks. Also make sure to add a PR to the documentation

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants