Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: webpack-contrib/terser-webpack-plugin
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: bb902d7d0b8f38a0ed8d1ca5827ff3252e1ec3d1
Choose a base ref
...
head repository: webpack-contrib/terser-webpack-plugin
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: e6798814cd64a74f888e2d241501fc08c8676ed8
Choose a head ref

Commits on Feb 4, 2019

  1. Copy the full SHA
    0593d7c View commit details
  2. Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    83f4f0f View commit details
  3. Copy the full SHA
    ea99cce View commit details

Commits on Feb 25, 2019

  1. Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    6abc66c View commit details
  2. Copy the full SHA
    675edfd View commit details
  3. chore(release): 1.2.3

    alexander-akait committed Feb 25, 2019
    Copy the full SHA
    22352b0 View commit details

Commits on Mar 7, 2019

  1. Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    2388f2a View commit details

Commits on May 14, 2019

  1. Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    3cdd2ed View commit details
  2. Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    449e0fc View commit details
  3. Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    d9533dd View commit details

Commits on May 15, 2019

  1. chore(release): 1.2.4

    alexander-akait committed May 15, 2019
    Copy the full SHA
    6d7aaa7 View commit details

Commits on May 24, 2019

  1. Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    e5de064 View commit details
  2. Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    15d1595 View commit details
  3. chore(release): 1.3.0

    alexander-akait committed May 24, 2019
    Copy the full SHA
    a0d8317 View commit details

Commits on Jul 31, 2019

  1. Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    45ddf2f View commit details
  2. Copy the full SHA
    9d777f0 View commit details
  3. chore(release): 1.4.0

    alexander-akait committed Jul 31, 2019
    Copy the full SHA
    2b2cb8a View commit details
  4. Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    bc19b72 View commit details
  5. chore(release): 1.4.1

    alexander-akait committed Jul 31, 2019
    Copy the full SHA
    aa12914 View commit details

Commits on Sep 2, 2019

  1. Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    ec9450c View commit details
  2. Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    c896de6 View commit details
  3. Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    4f88a97 View commit details
  4. chore(defaults): update (#127)

    BREAKING CHANGE: minimum require Node.js version is `8.9.0`
    evilebottnawi authored Sep 2, 2019

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    edbd3e0 View commit details
  5. fix: make extractComments API more consistent (#129)

    BREAKING CHANGE: using the `extractComments.condition` option with `true` value extract only `some` comments
    evilebottnawi authored Sep 2, 2019

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    37d2df0 View commit details

Commits on Sep 3, 2019

  1. Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    41a9fff View commit details
  2. feat: enable the parallel option by default (#131)

    BREAKING CHANGE: the `parallel` option is `true` by default
    evilebottnawi authored Sep 3, 2019

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    7b342af View commit details

Commits on Sep 4, 2019

  1. feat: enable the cache option by default (#132)

    BREAKING CHANGE: the `cache` option is `true` by default
    evilebottnawi authored Sep 4, 2019

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    960d249 View commit details
  2. feat: enable the extractComments option by default

    BREAKING CHANGE: the `extractComments` option is `true` by default
    alexander-akait committed Sep 4, 2019
    Copy the full SHA
    ad2471c View commit details
  3. Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    84fed6b View commit details
  4. Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    8b88b39 View commit details

Commits on Sep 5, 2019

  1. docs: fix examples (#135)

    gaokun authored and evilebottnawi committed Sep 5, 2019
    Copy the full SHA
    a169061 View commit details
  2. Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    cc1c081 View commit details
  3. Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    527a055 View commit details
  4. Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    0537591 View commit details
  5. Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    080baff View commit details
  6. Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    dd37ca1 View commit details
  7. Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    dcf875b View commit details
  8. Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    ae56c17 View commit details
  9. Copy the full SHA
    42a0f9c View commit details

Commits on Sep 6, 2019

  1. Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    815e533 View commit details
  2. Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    6613a97 View commit details
  3. Copy the full SHA
    0b9681d View commit details

Commits on Sep 9, 2019

  1. Copy the full SHA
    cf91c43 View commit details

Commits on Sep 12, 2019

  1. docs: clarify default value for sourceMap option (#151)

    See more context here:
    #150
    koggdal authored and evilebottnawi committed Sep 12, 2019
    Copy the full SHA
    5821456 View commit details
  2. Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    cea7243 View commit details
  3. Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    5fe3337 View commit details

Commits on Sep 13, 2019

  1. docs: add missing breaking change for 2.0.0 (#155)

    See more in:
    #150
    koggdal authored and evilebottnawi committed Sep 13, 2019
    Copy the full SHA
    efbd383 View commit details
  2. Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    2b4d2a4 View commit details
  3. Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    aba8ba7 View commit details

Commits on Sep 16, 2019

  1. refactor: code (#158)

    evilebottnawi authored Sep 16, 2019

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    9bbe824 View commit details
Showing with 21,018 additions and 17,049 deletions.
  1. +0 −145 .circleci/config.yml
  2. +1 −2 .editorconfig
  3. +3 −5 .eslintignore
  4. +1 −8 .eslintrc.js
  5. +1 −0 .gitattributes
  6. +77 −41 .github/CONTRIBUTING.md
  7. +1 −0 .github/FUNDING.yml
  8. +1 −1 .github/ISSUE_TEMPLATE.md
  9. +9 −10 .github/ISSUE_TEMPLATE/BUG.md
  10. +1 −3 .github/ISSUE_TEMPLATE/DOCS.md
  11. +5 −8 .github/ISSUE_TEMPLATE/FEATURE.md
  12. +5 −11 .github/ISSUE_TEMPLATE/MODIFICATION.md
  13. +0 −1 .github/ISSUE_TEMPLATE/SUPPORT.md
  14. +95 −0 .github/workflows/nodejs.yml
  15. +1 −0 .gitignore
  16. +0 −2 .npmignore
  17. +5 −0 .prettierignore
  18. +0 −5 .prettierrc
  19. +1 −0 .prettierrc.js
  20. +369 −1 CHANGELOG.md
  21. +63 −224 README.md
  22. +0 −45 appveyor.yml
  23. +19 −0 babel.config.js
  24. +3 −0 commitlint.config.js
  25. +6 −0 husky.config.js
  26. +3 −0 jest.config.js
  27. +4 −0 lint-staged.config.js
  28. +7,344 −7,898 package-lock.json
  29. +50 −78 package.json
  30. +0 −106 src/TaskRunner.js
  31. +347 −287 src/index.js
  32. +72 −63 src/minify.js
  33. +40 −62 src/options.json
  34. +0 −21 src/worker.js
  35. +1,158 −105 test/TerserPlugin.test.js
  36. +1,214 −50 test/__snapshots__/TerserPlugin.test.js.snap
  37. +327 −587 test/__snapshots__/cache-option.test.js.snap
  38. +0 −108 test/__snapshots__/chunkFilter-option.test.js.snap
  39. +192 −510 test/__snapshots__/exclude-option.test.js.snap
  40. +5,124 −1,134 test/__snapshots__/extractComments-option.test.js.snap
  41. +195 −521 test/__snapshots__/include-option.test.js.snap
  42. +64 −403 test/__snapshots__/minify-option.test.js.snap
  43. +0 −231 test/__snapshots__/parallel-option-failure.test.js.snap
  44. +102 −35 test/__snapshots__/parallel-option.test.js.snap
  45. +310 −29 test/__snapshots__/sourceMap-option.test.js.snap
  46. +0 −152 test/__snapshots__/supports-multicompiler.test.js.snap
  47. +457 −562 test/__snapshots__/terserOptions-option.test.js.snap
  48. +617 −1,099 test/__snapshots__/test-option.test.js.snap
  49. +178 −0 test/__snapshots__/validate-options.test.js.snap
  50. +0 −209 test/__snapshots__/validation.test.js.snap
  51. +0 −48 test/__snapshots__/warningsFilter-option.test.js.snap
  52. +141 −25 test/__snapshots__/worker.test.js.snap
  53. +395 −279 test/cache-option.test.js
  54. +0 −44 test/chunkFilter-option.test.js
  55. +4 −4 test/cjs.test.js
  56. +34 −66 test/exclude-option.test.js
  57. +499 −221 test/extractComments-option.test.js
  58. +7 −0 test/fixtures/asset-resource.js
  59. +2 −0 test/fixtures/comments.js
  60. +2 −0 test/fixtures/copy.cjs
  61. +2 −0 test/fixtures/copy.js
  62. +2 −0 test/fixtures/copy.mjs
  63. +5 −0 test/fixtures/emit-loader.js
  64. +1 −0 test/fixtures/emitted.js
  65. 0 test/fixtures/empty.js
  66. +7 −4 test/fixtures/entry.mjs
  67. +7 −0 test/fixtures/file-loader.js
  68. +1 −0 test/fixtures/file.js
  69. +7 −0 test/fixtures/file.worker.js
  70. +1 −0 test/fixtures/shebang-1.js
  71. +3 −0 test/fixtures/shebang.js
  72. +10 −0 test/fixtures/worker-loader.js
  73. +0 −96 test/helpers.js
  74. +16 −0 test/helpers/BrokenCodePlugin.js
  75. +16 −0 test/helpers/ExistingCommentsFile.js
  76. +25 −0 test/helpers/ModifyExistingAsset.js
  77. +11 −0 test/helpers/compile.js
  78. +9 −0 test/helpers/countPlugins.js
  79. +22 −0 test/helpers/execute.js
  80. +31 −0 test/helpers/getCompiler.js
  81. +5 −0 test/helpers/getErrors.js
  82. +5 −0 test/helpers/getWarnings.js
  83. +27 −0 test/helpers/index.js
  84. +19 −0 test/helpers/normalizeErrors.js
  85. +23 −0 test/helpers/readAsset.js
  86. +11 −0 test/helpers/readAssets.js
  87. +28 −0 test/helpers/snapshotResolver.js
  88. +34 −66 test/include-option.test.js
  89. +172 −178 test/minify-option.test.js
  90. +0 −105 test/parallel-option-failure.test.js
  91. +201 −83 test/parallel-option.test.js
  92. +230 −121 test/sourceMap-option.test.js
  93. +0 −102 test/supports-multicompiler.test.js
  94. +224 −480 test/terserOptions-option.test.js
  95. +68 −108 test/test-option.test.js
  96. +0 −53 test/{validation.test.js → validate-options.test.js}
  97. +0 −144 test/warningsFilter-option.test.js
  98. +246 −60 test/worker.test.js
145 changes: 0 additions & 145 deletions .circleci/config.yml

This file was deleted.

3 changes: 1 addition & 2 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -9,5 +9,4 @@ insert_final_newline = true
trim_trailing_whitespace = true

[*.md]
insert_final_newline = true
trim_trailing_whitespace = false
trim_trailing_whitespace = false
8 changes: 3 additions & 5 deletions .eslintignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
*.snap
/node_modules
/coverage
/dist
/examples/build
/coverage/
/test/fixtures
/node_modules
/test/fixtures
9 changes: 1 addition & 8 deletions .eslintrc.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,4 @@
module.exports = {
root: true,
plugins: ['prettier'],
extends: ['@webpack-contrib/eslint-config-webpack'],
rules: {
'prettier/prettier': [
'error',
{ singleQuote: true, trailingComma: 'es5', arrowParens: 'always' },
],
},
extends: ['@webpack-contrib/eslint-config-webpack', 'prettier'],
};
1 change: 1 addition & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
package-lock.json -diff
* text=auto
bin/* eol=lf
yarn.lock -diff
118 changes: 77 additions & 41 deletions .github/CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -1,21 +1,21 @@
## Contributing in @webpack-contrib
# Contributing in @webpack-contrib

We'd always love contributions to further improve the webpack / webpack-contrib ecosystem!
We'd always love contributions to further improve the webpack / webpack-contrib ecosystem!
Here are the guidelines we'd like you to follow:

* [Questions and Problems](#question)
* [Issues and Bugs](#issue)
* [Feature Requests](#feature)
* [Pull Request Submission Guidelines](#submit-pr)
* [Commit Message Conventions](#commit)
- [Questions and Problems](#question)
- [Issues and Bugs](#issue)
- [Feature Requests](#feature)
- [Pull Request Submission Guidelines](#submit-pr)
- [Commit Message Conventions](#commit)

### <a name="question"></a> Got a Question or Problem?
## <a name="question"></a> Got a Question or Problem?

Please submit support requests and questions to StackOverflow using the tag [[webpack]](http://stackoverflow.com/tags/webpack).
StackOverflow is better suited for this kind of support though you may also inquire in [Webpack Gitter](https://gitter.im/webpack/webpack).
Please submit support requests and questions to StackOverflow using the tag [[webpack]](http://stackoverflow.com/tags/webpack).
StackOverflow is better suited for this kind of support though you may also inquire in [Webpack Gitter](https://gitter.im/webpack/webpack).
The issue tracker is for bug reports and feature discussions.

### <a name="issue"></a> Found an Issue or Bug?
## <a name="issue"></a> Found an Issue or Bug?

Before you submit an issue, please search the issue tracker, maybe an issue for your problem already exists and the discussion might inform you of workarounds readily available.

@@ -31,13 +31,13 @@ We will be insisting on a minimal reproduce scenario in order to save maintainer

Unfortunately, we are not able to investigate / fix bugs without a minimal reproduction, so if we don't hear back from you we are going to close an issue that doesn't have enough info to be reproduced.

### <a name="feature"></a> Feature Requests?
## <a name="feature"></a> Feature Requests?

You can *request* a new feature by creating an issue on Github.
You can _request_ a new feature by creating an issue on Github.

If you would like to *implement* a new feature, please submit an issue with a proposal for your work `first`, to be sure that particular makes sense for the project.
If you would like to _implement_ a new feature, please submit an issue with a proposal for your work `first`, to be sure that particular makes sense for the project.

### <a name="submit-pr"></a> Pull Request Submission Guidelines
## <a name="submit-pr"></a> Pull Request Submission Guidelines

Before you submit your Pull Request (PR) consider the following guidelines:

@@ -46,9 +46,9 @@ Before you submit your Pull Request (PR) consider the following guidelines:
- Fill out our `Pull Request Template`. Your pull request will not be considered if it is ignored.
- Please sign the `Contributor License Agreement (CLA)` when a pull request is opened. We cannot accept your pull request without this. Make sure you sign with the primary email address associated with your local / github account.

### <a name="commit"></a> Webpack Contrib Commit Conventions
## <a name="commit"></a> Webpack Contrib Commit Conventions

Each commit message consists of a **header**, a **body** and a **footer**. The header has a special
Each commit message consists of a **header**, a **body** and a **footer**. The header has a special
format that includes a **type**, a **scope** and a **subject**:

```
@@ -66,48 +66,56 @@ to read on GitHub as well as in various git tools.

The footer should contain a [closing reference to an issue](https://help.github.com/articles/closing-issues-via-commit-messages/) if any.

Examples:
Examples:

```
docs(readme): update install instructions
```

```
fix: refer to the `entrypoint` instead of the first `module`
```

#### Revert
If the commit reverts a previous commit, it should begin with `revert: `, followed by the header of the reverted commit.
### Revert

If the commit reverts a previous commit, it should begin with `revert:`, followed by the header of the reverted commit.
In the body it should say: `This reverts commit <hash>.`, where the hash is the SHA of the commit being reverted.

#### Type
### Type

Must be one of the following:

* **build**: Changes that affect the build system or external dependencies (example scopes: babel, npm)
* **chore**: Changes that fall outside of build / docs that do not effect source code (example scopes: package, defaults)
* **ci**: Changes to our CI configuration files and scripts (example scopes: circleci, travis)
* **docs**: Documentation only changes (example scopes: readme, changelog)
* **feat**: A new feature
* **fix**: A bug fix
* **perf**: A code change that improves performance
* **refactor**: A code change that neither fixes a bug nor adds a feature
* **revert**: Used when reverting a committed change
* **style**: Changes that do not affect the meaning of the code (white-space, formatting, missing semi-colons)
* **test**: Addition of or updates to Jest tests

#### Scope
- **build**: Changes that affect the build system or external dependencies (example scopes: babel, npm)
- **chore**: Changes that fall outside of build / docs that do not effect source code (example scopes: package, defaults)
- **ci**: Changes to our CI configuration files and scripts (example scopes: circleci, travis)
- **docs**: Documentation only changes (example scopes: readme, changelog)
- **feat**: A new feature
- **fix**: A bug fix
- **perf**: A code change that improves performance
- **refactor**: A code change that neither fixes a bug nor adds a feature
- **revert**: Used when reverting a committed change
- **style**: Changes that do not affect the meaning of the code (white-space, formatting, missing semi-colons)
- **test**: Addition of or updates to Jest tests

### Scope

The scope is subjective & depends on the `type` see above. A good example would be a change to a particular class / module.

#### Subject
### Subject

The subject contains a succinct description of the change:

* use the imperative, present tense: "change" not "changed" nor "changes"
* don't capitalize the first letter
* no dot (.) at the end
- use the imperative, present tense: "change" not "changed" nor "changes"
- don't capitalize the first letter
- no dot (.) at the end

### Body

#### Body
Just as in the **subject**, use the imperative, present tense: "change" not "changed" nor "changes".
The body should include the motivation for the change and contrast this with previous behavior.

#### Footer
### Footer

The footer should contain any information about **Breaking Changes** and is also the place to
reference GitHub issues that this commit **Closes**.

@@ -116,9 +124,37 @@ reference GitHub issues that this commit **Closes**.
Example

```
BREAKING CHANGE: Updates to `Chunk.mapModules`.
BREAKING CHANGE: Updates to `Chunk.mapModules`.
This release is not backwards compatible with `Webpack 2.x` due to breaking changes in webpack/webpack#4764
Migration: see webpack/webpack#5225
```

## Testing Your Pull Request

You may have the need to test your changes in a real-world project or dependent
module. Thankfully, Github provides a means to do this. Add a dependency to the
`package.json` for such a project as follows:

```json
{
"devDependencies": {
"terser-webpack-plugin": "webpack-contrib/terser-webpack-plugin#{id}/head"
}
}
```

Where `{id}` is the # ID of your Pull Request.

## Contributor License Agreement

When submitting your contribution, a CLA (Contributor License Agreement) bot will come by to verify that you signed the [CLA](https://cla.js.foundation/webpack-contrib/terser-webpack-plugin).
If it is your first time, it will link you to the right place to sign it.
However, if you have committed your contributions using an email that is not the same as your email used on GitHub, the CLA bot can't accept your contribution.

Run `git config user.email` to see your Git email, and verify it with [your GitHub email](https://github.com/settings/emails).

## Thanks

For your interest, time, understanding, and for following this simple guide.
1 change: 1 addition & 0 deletions .github/FUNDING.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
open_collective: webpack
2 changes: 1 addition & 1 deletion .github/ISSUE_TEMPLATE.md
Original file line number Diff line number Diff line change
@@ -13,4 +13,4 @@
existing template types, your issue may be closed as invalid. Our issue
templates contain fields that help us help you, and without that important
info, we might as well be ice-skating uphill, carrying a wooly mammoth.
-->
-->
19 changes: 9 additions & 10 deletions .github/ISSUE_TEMPLATE/BUG.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
---
name: 🐛 Bug Report
about: Something went awry and you'd like to tell us about it.

---

<!--
@@ -15,11 +14,11 @@ about: Something went awry and you'd like to tell us about it.
Head to StackOverflow or https://gitter.im/webpack/webpack.
-->

* Operating System:
* Node Version:
* NPM Version:
* webpack Version:
* terser-webpack-plugin Version:
- Operating System:
- Node Version:
- NPM Version:
- webpack Version:
- terser-webpack-plugin Version:

### Expected Behavior

@@ -32,13 +31,13 @@ about: Something went awry and you'd like to tell us about it.
### Code

```js
// webpack.config.js
// If your bitchin' code blocks are over 20 lines, please paste a link to a gist
// (https://gist.github.com).
// webpack.config.js
// If your code blocks are over 20 lines, please paste a link to a gist
// (https://gist.github.com).
```

```js
// additional code, HEY YO remove this block if you don't need it
// additional code, HEY YO remove this block if you don't need it
```

### How Do We Reproduce?
4 changes: 1 addition & 3 deletions .github/ISSUE_TEMPLATE/DOCS.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
---
name: 📚 Documentation
about: Are the docs lacking or missing something? Do they need some new 🔥 hotness? Tell us here.

---

<!--
@@ -26,5 +25,4 @@ Documentation Is:

### Please Explain in Detail...


### Your Proposal for Changes
### Your Proposal for Changes
13 changes: 5 additions & 8 deletions .github/ISSUE_TEMPLATE/FEATURE.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
---
name: ✨ Feature Request
about: Suggest an idea for this project

---

<!--
@@ -15,14 +14,12 @@ about: Suggest an idea for this project
Head to StackOverflow or https://gitter.im/webpack/webpack.
-->

* Operating System:
* Node Version:
* NPM Version:
* webpack Version:
* terser-webpack-plugin Version:
- Operating System:
- Node Version:
- NPM Version:
- webpack Version:
- terser-webpack-plugin Version:

### Feature Proposal



### Feature Use Case
16 changes: 5 additions & 11 deletions .github/ISSUE_TEMPLATE/MODIFICATION.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
---
name: 🔧 Modification Request
about: Would you like something work differently? Have an alternative approach? This is the template for you.

---

<!--
@@ -15,19 +14,14 @@ about: Would you like something work differently? Have an alternative approach?
Head to StackOverflow or https://gitter.im/webpack/webpack.
-->

* Operating System:
* Node Version:
* NPM Version:
* webpack Version:
* terser-webpack-plugin Version:

- Operating System:
- Node Version:
- NPM Version:
- webpack Version:
- terser-webpack-plugin Version:

### Expected Behavior / Situation



### Actual Behavior / Situation



### Modification Proposal
1 change: 0 additions & 1 deletion .github/ISSUE_TEMPLATE/SUPPORT.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
---
name: 🆘 Support, Help, and Advice
about: 👉🏽 Need support, help, or advice? Don't open an issue! Head to StackOverflow or https://gitter.im/webpack/webpack.

---

Hey there! If you need support, help, or advice then this is not the place to ask.
95 changes: 95 additions & 0 deletions .github/workflows/nodejs.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
name: terser-webpack-plugin

on:
push:
branches:
- master
- next
pull_request:
branches:
- master
- next

jobs:
lint:
name: Lint - ${{ matrix.os }} - Node v${{ matrix.node-version }}

env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

strategy:
matrix:
os: [ubuntu-latest]
node-version: [12.x]

runs-on: ${{ matrix.os }}

steps:
- uses: actions/checkout@v2
with:
fetch-depth: 0

- name: Use Node.js ${{ env.node-version }}
uses: actions/setup-node@v1
with:
node-version: ${{ env.node-version }}

- name: Use latest NPM
run: sudo npm i -g npm

- name: Install dependencies
run: npm ci

- name: Lint
run: npm run lint

- name: Security audit
run: npm run security

- name: Check commit message
uses: wagoid/commitlint-github-action@v1

test:
name: Test - ${{ matrix.os }} - Node v${{ matrix.node-version }}, Webpack ${{ matrix.webpack-version }}

strategy:
matrix:
os: [ubuntu-latest, windows-latest, macos-latest]
node-version: [10.x, 12.x, 14.x]
webpack-version: [latest]

runs-on: ${{ matrix.os }}

steps:
- name: Setup Git
if: matrix.os == 'windows-latest'
run: git config --global core.autocrlf input

- uses: actions/checkout@v2

- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v1
with:
node-version: ${{ matrix.node-version }}

- name: Use latest NPM on ubuntu/macos
if: matrix.os == 'ubuntu-latest' || matrix.os == 'macos-latest'
run: sudo npm i -g npm

- name: Use latest NPM on windows
if: matrix.os == 'windows-latest'
run: npm i -g npm

- name: Install dependencies
run: npm ci

- name: Install webpack ${{ matrix.webpack-version }}
run: npm i webpack@${{ matrix.webpack-version }}

- name: Run tests for webpack version ${{ matrix.webpack-version }}
run: npm run test:coverage -- --ci

- name: Submit coverage data to codecov
uses: codecov/codecov-action@v1
with:
token: ${{ secrets.CODECOV_TOKEN }}
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -8,6 +8,7 @@ npm-debug.log*
/local
/reports
/node_modules
/test/outputs

.DS_Store
Thumbs.db
2 changes: 0 additions & 2 deletions .npmignore

This file was deleted.

5 changes: 5 additions & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
/coverage
/dist
/node_modules
/test/fixtures
CHANGELOG.md
5 changes: 0 additions & 5 deletions .prettierrc

This file was deleted.

1 change: 1 addition & 0 deletions .prettierrc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
module.exports = { singleQuote: true };
370 changes: 369 additions & 1 deletion CHANGELOG.md

Large diffs are not rendered by default.

287 changes: 63 additions & 224 deletions README.md

Large diffs are not rendered by default.

45 changes: 0 additions & 45 deletions appveyor.yml

This file was deleted.

19 changes: 19 additions & 0 deletions babel.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
const MIN_BABEL_VERSION = 7;

module.exports = (api) => {
api.assertVersion(MIN_BABEL_VERSION);
api.cache(true);

return {
presets: [
[
'@babel/preset-env',
{
targets: {
node: '10.13.0',
},
},
],
],
};
};
3 changes: 3 additions & 0 deletions commitlint.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
module.exports = {
extends: ['@commitlint/config-conventional'],
};
6 changes: 6 additions & 0 deletions husky.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
module.exports = {
hooks: {
'pre-commit': 'lint-staged',
'commit-msg': 'commitlint -E HUSKY_GIT_PARAMS',
},
};
3 changes: 3 additions & 0 deletions jest.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
module.exports = {
testEnvironment: 'node',
};
4 changes: 4 additions & 0 deletions lint-staged.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
module.exports = {
'*.js': ['eslint --fix', 'prettier --write'],
'*.{json,md,yml,css,ts}': ['prettier --write'],
};
15,242 changes: 7,344 additions & 7,898 deletions package-lock.json

Large diffs are not rendered by default.

128 changes: 50 additions & 78 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,79 +1,80 @@
{
"name": "terser-webpack-plugin",
"version": "1.2.1",
"version": "5.0.0",
"description": "Terser plugin for webpack",
"license": "MIT",
"repository": "webpack-contrib/terser-webpack-plugin",
"author": "webpack Contrib Team",
"homepage": "https://github.com/webpack-contrib/terser-webpack-plugin",
"bugs": "https://github.com/webpack-contrib/terser-webpack-plugin/issues",
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/webpack"
},
"main": "dist/cjs.js",
"engines": {
"node": ">= 6.9.0"
"node": ">= 10.13.0"
},
"scripts": {
"start": "npm run build -- -w",
"build": "cross-env NODE_ENV=production babel src -d dist --ignore 'src/**/*.test.js' --copy-files",
"clean": "del-cli dist",
"commitlint": "commitlint",
"commitmsg": "commitlint -e $GIT_PARAMS",
"lint": "eslint --cache src test",
"prebuild": "npm run clean",
"prepublish": "npm run build",
"release": "standard-version",
"build": "cross-env NODE_ENV=production babel src -d dist --copy-files",
"commitlint": "commitlint --from=master",
"security": "npm audit",
"test": "jest",
"test:watch": "jest --watch",
"test:coverage": "jest --collectCoverageFrom='src/**/*.js' --coverage",
"ci:lint": "npm run lint && npm run security",
"ci:test": "npm run test -- --runInBand",
"ci:coverage": "npm run test:coverage -- --runInBand",
"ci:lint:commits": "commitlint --from=origin/master --to=${CIRCLE_SHA1}",
"lint:prettier": "prettier --list-different .",
"lint:js": "eslint --cache .",
"lint": "npm-run-all -l -p \"lint:**\"",
"test:only": "cross-env NODE_ENV=test jest",
"test:watch": "npm run test:only -- --watch",
"test:coverage": "npm run test:only -- --collectCoverageFrom=\"src/**/*.js\" --coverage",
"pretest": "npm run lint",
"test": "npm run test:coverage",
"prepare": "npm run build",
"release": "standard-version",
"defaults": "webpack-defaults"
},
"files": [
"dist"
],
"peerDependencies": {
"webpack": "^4.0.0"
"webpack": "^5.1.0"
},
"dependencies": {
"cacache": "^11.0.2",
"find-cache-dir": "^2.0.0",
"schema-utils": "^1.0.0",
"serialize-javascript": "^1.4.0",
"jest-worker": "^26.5.0",
"p-limit": "^3.0.2",
"schema-utils": "^3.0.0",
"serialize-javascript": "^5.0.1",
"source-map": "^0.6.1",
"terser": "^3.8.1",
"webpack-sources": "^1.1.0",
"worker-farm": "^1.5.2"
"terser": "^5.3.5"
},
"devDependencies": {
"@babel/cli": "^7.1.5",
"@babel/core": "^7.1.6",
"@babel/polyfill": "^7.0.0",
"@babel/preset-env": "^7.1.6",
"@commitlint/cli": "^7.0.0",
"@commitlint/config-conventional": "^7.0.1",
"@webpack-contrib/defaults": "^3.0.0",
"@babel/cli": "^7.11.6",
"@babel/core": "^7.11.6",
"@babel/preset-env": "^7.11.5",
"@commitlint/cli": "^11.0.0",
"@commitlint/config-conventional": "^11.0.0",
"@webpack-contrib/defaults": "^6.3.0",
"@webpack-contrib/eslint-config-webpack": "^3.0.0",
"babel-core": "^7.0.0-bridge.0",
"babel-jest": "^23.6.0",
"conventional-github-releaser": "^3.1.2",
"cross-env": "^5.1.3",
"del": "^3.0.0",
"del-cli": "^1.1.0",
"eslint": "^5.5.0",
"eslint-config-webpack": "^1.2.5",
"eslint-plugin-import": "^2.8.0",
"eslint-plugin-prettier": "^3.0.0",
"husky": "^1.2.1",
"jest": "^23.5.0",
"lint-staged": "^8.1.0",
"memory-fs": "^0.4.1",
"prettier": "^1.14.0",
"standard-version": "^4.3.0",
"uglify-js": "^3.4.3",
"webpack": "^4.16.3"
"babel-jest": "^26.5.2",
"copy-webpack-plugin": "^6.2.1",
"cross-env": "^7.0.2",
"del": "^6.0.0",
"del-cli": "^3.0.1",
"eslint": "^7.11.0",
"eslint-config-prettier": "^6.12.0",
"eslint-plugin-import": "^2.22.1",
"file-loader": "^6.1.1",
"husky": "^4.3.0",
"jest": "^26.5.3",
"lint-staged": "^10.4.0",
"memfs": "^3.2.0",
"npm-run-all": "^4.1.5",
"prettier": "^2.1.2",
"standard-version": "^9.0.0",
"uglify-js": "^3.11.2",
"webpack": "^5.1.0",
"worker-loader": "^3.0.4"
},
"keywords": [
"uglify",
@@ -91,34 +92,5 @@
"minify",
"optimize",
"optimizer"
],
"babel": {
"presets": [
[
"@babel/preset-env",
{
"targets": {
"node": "6.9.0"
},
"useBuiltIns": "usage"
}
]
]
},
"husky": {
"hooks": {
"pre-commit": "lint-staged"
}
},
"lint-staged": {
"*.js": [
"eslint --fix",
"git add"
]
},
"commitlint": {
"extends": [
"@commitlint/config-conventional"
]
}
]
}
106 changes: 0 additions & 106 deletions src/TaskRunner.js

This file was deleted.

634 changes: 347 additions & 287 deletions src/index.js

Large diffs are not rendered by default.

135 changes: 72 additions & 63 deletions src/minify.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,7 @@
/* eslint-disable
arrow-body-style
*/
import terser from 'terser';
const { minify: terserMinify } = require('terser');

const buildTerserOptions = ({
ecma,
warnings,
parse = {},
compress = {},
mangle,
@@ -20,8 +16,6 @@ const buildTerserOptions = ({
/* eslint-enable camelcase */
safari10,
} = {}) => ({
ecma,
warnings,
parse: { ...parse },
compress: typeof compress === 'boolean' ? compress : { ...compress },
// eslint-disable-next-line no-nested-ternary
@@ -32,51 +26,55 @@ const buildTerserOptions = ({
? mangle
: { ...mangle },
output: {
shebang: true,
comments: false,
beautify: false,
semicolons: true,
...output,
},
module,
// Ignoring sourceMap from options
sourceMap: null,
toplevel,
nameCache,
ie8,
ecma,
keep_classnames,
keep_fnames,
ie8,
module,
nameCache,
safari10,
toplevel,
});

const buildComments = (options, terserOptions, extractedComments) => {
function isObject(value) {
const type = typeof value;

return value != null && (type === 'object' || type === 'function');
}

const buildComments = (extractComments, terserOptions, extractedComments) => {
const condition = {};
const commentsOpts = terserOptions.output.comments;
const { comments } = terserOptions.output;

// Use /^\**!|@preserve|@license|@cc_on/i RegExp
if (typeof options.extractComments === 'boolean') {
condition.preserve = commentsOpts;
condition.extract = /^\**!|@preserve|@license|@cc_on/i;
} else if (
typeof options.extractComments === 'string' ||
options.extractComments instanceof RegExp
) {
// extractComments specifies the extract condition and commentsOpts specifies the preserve condition
condition.preserve = commentsOpts;
condition.extract = options.extractComments;
} else if (typeof options.extractComments === 'function') {
condition.preserve = commentsOpts;
condition.extract = options.extractComments;
condition.preserve = typeof comments !== 'undefined' ? comments : false;

if (typeof extractComments === 'boolean' && extractComments) {
condition.extract = 'some';
} else if (
Object.prototype.hasOwnProperty.call(options.extractComments, 'condition')
typeof extractComments === 'string' ||
extractComments instanceof RegExp
) {
// Extract condition is given in extractComments.condition
condition.preserve = commentsOpts;
condition.extract = options.extractComments.condition;
condition.extract = extractComments;
} else if (typeof extractComments === 'function') {
condition.extract = extractComments;
} else if (isObject(extractComments)) {
condition.extract =
typeof extractComments.condition === 'boolean' &&
extractComments.condition
? 'some'
: typeof extractComments.condition !== 'undefined'
? extractComments.condition
: 'some';
} else {
// No extract condition is given. Extract comments that match commentsOpts instead of preserving them
condition.preserve = false;
condition.extract = commentsOpts;
// No extract
// Preserve using "commentsOpts" or "some"
condition.preserve = typeof comments !== 'undefined' ? comments : 'some';
condition.extract = false;
}

// Ensure that both conditions are functions
@@ -101,8 +99,8 @@ const buildComments = (options, terserOptions, extractedComments) => {
if (condition[key] === 'some') {
condition[key] = (astNode, comment) => {
return (
comment.type === 'comment2' &&
/^\**!|@preserve|@license|@cc_on/i.test(comment.value)
(comment.type === 'comment2' || comment.type === 'comment1') &&
/@preserve|@lic|@cc_on|^\**!/i.test(comment.value)
);
};

@@ -142,45 +140,56 @@ const buildComments = (options, terserOptions, extractedComments) => {
};
};

const minify = (options) => {
async function minify(options) {
const {
file,
name,
input,
inputSourceMap,
extractComments,
minify: minifyFn,
minimizerOptions,
} = options;

if (minifyFn) {
return minifyFn({ [file]: input }, inputSourceMap);
return minifyFn({ [name]: input }, inputSourceMap, minimizerOptions);
}

// Copy terser options
const terserOptions = buildTerserOptions(options.terserOptions);
const terserOptions = buildTerserOptions(minimizerOptions);

// Add source map data
// Let terser generate a SourceMap
if (inputSourceMap) {
terserOptions.sourceMap = {
content: inputSourceMap,
};
terserOptions.sourceMap = { asObject: true };
}

const extractedComments = [];
const { extractComments } = options;

if (extractComments) {
terserOptions.output.comments = buildComments(
options,
terserOptions,
extractedComments
);
}

const { error, map, code, warnings } = terser.minify(
{ [file]: input },
terserOptions
terserOptions.output.comments = buildComments(
extractComments,
terserOptions,
extractedComments
);

return { error, map, code, warnings, extractedComments };
};

export default minify;
const result = await terserMinify({ [name]: input }, terserOptions);

return { ...result, extractedComments };
}

function transform(options) {
// 'use strict' => this === undefined (Clean Scope)
// Safer for possible security issues, albeit not critical at all here
// eslint-disable-next-line no-new-func, no-param-reassign
options = new Function(
'exports',
'require',
'module',
'__filename',
'__dirname',
`'use strict'\nreturn ${options}`
)(exports, require, module, __filename, __dirname);

return minify(options);
}

module.exports.minify = minify;
module.exports.transform = transform;
102 changes: 40 additions & 62 deletions src/options.json
Original file line number Diff line number Diff line change
@@ -1,86 +1,68 @@
{
"additionalProperties": false,
"definitions": {
"file-conditions": {
"Rule": {
"description": "Filtering rule as regex or string.",
"anyOf": [
{
"instanceof": "RegExp"
"instanceof": "RegExp",
"tsType": "RegExp"
},
{
"type": "string"
"type": "string",
"minLength": 1
}
]
}
},
"properties": {
"test": {
},
"Rules": {
"description": "Filtering rules.",
"anyOf": [
{
"$ref": "#/definitions/file-conditions"
},
{
"type": "array",
"items": {
"anyOf": [
"description": "A rule condition.",
"oneOf": [
{
"$ref": "#/definitions/file-conditions"
"$ref": "#/definitions/Rule"
}
]
},
"type": "array"
}
},
{
"$ref": "#/definitions/Rule"
}
]
},
"include": {
"anyOf": [
{
"$ref": "#/definitions/file-conditions"
},
}
},
"title": "TerserPluginOptions",
"type": "object",
"additionalProperties": false,
"properties": {
"test": {
"description": "Include all modules that pass test assertion.",
"oneOf": [
{
"items": {
"anyOf": [
{
"$ref": "#/definitions/file-conditions"
}
]
},
"type": "array"
"$ref": "#/definitions/Rules"
}
]
},
"exclude": {
"anyOf": [
{
"$ref": "#/definitions/file-conditions"
},
"include": {
"description": "Include all modules matching any of these conditions.",
"oneOf": [
{
"items": {
"anyOf": [
{
"$ref": "#/definitions/file-conditions"
}
]
},
"type": "array"
"$ref": "#/definitions/Rules"
}
]
},
"chunkFilter": {
"instanceof": "Function"
},
"cache": {
"anyOf": [
{
"type": "boolean"
},
"exclude": {
"description": "Exclude all modules matching any of these conditions.",
"oneOf": [
{
"type": "string"
"$ref": "#/definitions/Rules"
}
]
},
"cacheKeys": {
"instanceof": "Function"
},
"parallel": {
"description": "Use multi-process parallel running to improve the build speed.",
"anyOf": [
{
"type": "boolean"
@@ -90,17 +72,17 @@
}
]
},
"sourceMap": {
"type": "boolean"
},
"minify": {
"description": "Allows you to override default minify function.",
"instanceof": "Function"
},
"terserOptions": {
"description": "Options for `terser`.",
"additionalProperties": true,
"type": "object"
},
"extractComments": {
"description": "Whether comments shall be extracted to a separate file.",
"anyOf": [
{
"type": "boolean"
@@ -160,10 +142,6 @@
"type": "object"
}
]
},
"warningsFilter": {
"instanceof": "Function"
}
},
"type": "object"
}
}
21 changes: 0 additions & 21 deletions src/worker.js

This file was deleted.

1,263 changes: 1,158 additions & 105 deletions test/TerserPlugin.test.js

Large diffs are not rendered by default.

1,264 changes: 1,214 additions & 50 deletions test/__snapshots__/TerserPlugin.test.js.snap

Large diffs are not rendered by default.

914 changes: 327 additions & 587 deletions test/__snapshots__/cache-option.test.js.snap

Large diffs are not rendered by default.

108 changes: 0 additions & 108 deletions test/__snapshots__/chunkFilter-option.test.js.snap

This file was deleted.

702 changes: 192 additions & 510 deletions test/__snapshots__/exclude-option.test.js.snap

Large diffs are not rendered by default.

6,258 changes: 5,124 additions & 1,134 deletions test/__snapshots__/extractComments-option.test.js.snap

Large diffs are not rendered by default.

716 changes: 195 additions & 521 deletions test/__snapshots__/include-option.test.js.snap

Large diffs are not rendered by default.

467 changes: 64 additions & 403 deletions test/__snapshots__/minify-option.test.js.snap

Large diffs are not rendered by default.

231 changes: 0 additions & 231 deletions test/__snapshots__/parallel-option-failure.test.js.snap

This file was deleted.

137 changes: 102 additions & 35 deletions test/__snapshots__/parallel-option.test.js.snap

Large diffs are not rendered by default.

339 changes: 310 additions & 29 deletions test/__snapshots__/sourceMap-option.test.js.snap

Large diffs are not rendered by default.

152 changes: 0 additions & 152 deletions test/__snapshots__/supports-multicompiler.test.js.snap

This file was deleted.

1,019 changes: 457 additions & 562 deletions test/__snapshots__/terserOptions-option.test.js.snap

Large diffs are not rendered by default.

1,716 changes: 617 additions & 1,099 deletions test/__snapshots__/test-option.test.js.snap

Large diffs are not rendered by default.

178 changes: 178 additions & 0 deletions test/__snapshots__/validate-options.test.js.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,178 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`validation 1`] = `
"Invalid options object. Terser Plugin has been initialized using an options object that does not match the API schema.
- options.test should be one of these:
[RegExp | non-empty string, ...] | RegExp | non-empty string
-> Filtering rules.
Details:
* options.test should be an array:
[RegExp | non-empty string, ...]
* options.test should be one of these:
RegExp | non-empty string
-> Filtering rule as regex or string.
Details:
* options.test should be an instance of RegExp.
* options.test should be a non-empty string."
`;

exports[`validation 2`] = `
"Invalid options object. Terser Plugin has been initialized using an options object that does not match the API schema.
- options.test should be one of these:
[RegExp | non-empty string, ...] | RegExp | non-empty string
-> Filtering rules.
Details:
* options.test[0] should be one of these:
RegExp | non-empty string
-> Filtering rule as regex or string.
Details:
* options.test[0] should be an instance of RegExp.
* options.test[0] should be a non-empty string."
`;

exports[`validation 3`] = `
"Invalid options object. Terser Plugin has been initialized using an options object that does not match the API schema.
- options.include should be one of these:
[RegExp | non-empty string, ...] | RegExp | non-empty string
-> Filtering rules.
Details:
* options.include should be an array:
[RegExp | non-empty string, ...]
* options.include should be one of these:
RegExp | non-empty string
-> Filtering rule as regex or string.
Details:
* options.include should be an instance of RegExp.
* options.include should be a non-empty string."
`;

exports[`validation 4`] = `
"Invalid options object. Terser Plugin has been initialized using an options object that does not match the API schema.
- options.include should be one of these:
[RegExp | non-empty string, ...] | RegExp | non-empty string
-> Filtering rules.
Details:
* options.include[0] should be one of these:
RegExp | non-empty string
-> Filtering rule as regex or string.
Details:
* options.include[0] should be an instance of RegExp.
* options.include[0] should be a non-empty string."
`;

exports[`validation 5`] = `
"Invalid options object. Terser Plugin has been initialized using an options object that does not match the API schema.
- options.exclude should be one of these:
[RegExp | non-empty string, ...] | RegExp | non-empty string
-> Filtering rules.
Details:
* options.exclude should be an array:
[RegExp | non-empty string, ...]
* options.exclude should be one of these:
RegExp | non-empty string
-> Filtering rule as regex or string.
Details:
* options.exclude should be an instance of RegExp.
* options.exclude should be a non-empty string."
`;

exports[`validation 6`] = `
"Invalid options object. Terser Plugin has been initialized using an options object that does not match the API schema.
- options.exclude should be one of these:
[RegExp | non-empty string, ...] | RegExp | non-empty string
-> Filtering rules.
Details:
* options.exclude[0] should be one of these:
RegExp | non-empty string
-> Filtering rule as regex or string.
Details:
* options.exclude[0] should be an instance of RegExp.
* options.exclude[0] should be a non-empty string."
`;

exports[`validation 7`] = `
"Invalid options object. Terser Plugin has been initialized using an options object that does not match the API schema.
- options.parallel should be one of these:
boolean | integer
-> Use multi-process parallel running to improve the build speed.
Details:
* options.parallel should be a boolean.
* options.parallel should be a integer."
`;

exports[`validation 8`] = `
"Invalid options object. Terser Plugin has been initialized using an options object that does not match the API schema.
- options.parallel should be one of these:
boolean | integer
-> Use multi-process parallel running to improve the build speed.
Details:
* options.parallel should be a boolean.
* options.parallel should be a integer."
`;

exports[`validation 9`] = `
"Invalid options object. Terser Plugin has been initialized using an options object that does not match the API schema.
- options.minify should be an instance of function.
-> Allows you to override default minify function."
`;

exports[`validation 10`] = `
"Invalid options object. Terser Plugin has been initialized using an options object that does not match the API schema.
- options.terserOptions should be an object:
object {}
-> Options for \`terser\`."
`;

exports[`validation 11`] = `
"Invalid options object. Terser Plugin has been initialized using an options object that does not match the API schema.
- options.extractComments should be one of these:
boolean | string | RegExp | function | object { condition?, filename?, banner? }
-> Whether comments shall be extracted to a separate file.
Details:
* options.extractComments.condition should be one of these:
boolean | string | RegExp | function
Details:
* options.extractComments.condition should be a boolean.
* options.extractComments.condition should be a string.
* options.extractComments.condition should be an instance of RegExp.
* options.extractComments.condition should be an instance of function."
`;
exports[`validation 12`] = `
"Invalid options object. Terser Plugin has been initialized using an options object that does not match the API schema.
- options.extractComments should be one of these:
boolean | string | RegExp | function | object { condition?, filename?, banner? }
-> Whether comments shall be extracted to a separate file.
Details:
* options.extractComments.filename should be one of these:
string | function
Details:
* options.extractComments.filename should be a string.
* options.extractComments.filename should be an instance of function."
`;
exports[`validation 13`] = `
"Invalid options object. Terser Plugin has been initialized using an options object that does not match the API schema.
- options.extractComments should be one of these:
boolean | string | RegExp | function | object { condition?, filename?, banner? }
-> Whether comments shall be extracted to a separate file.
Details:
* options.extractComments.banner should be one of these:
boolean | string | function
Details:
* options.extractComments.banner should be a boolean.
* options.extractComments.banner should be a string.
* options.extractComments.banner should be an instance of function."
`;
exports[`validation 14`] = `
"Invalid options object. Terser Plugin has been initialized using an options object that does not match the API schema.
- options.extractComments has an unknown property 'unknown'. These properties are valid:
object { condition?, filename?, banner? }"
`;
exports[`validation 15`] = `
"Invalid options object. Terser Plugin has been initialized using an options object that does not match the API schema.
- options has an unknown property 'unknown'. These properties are valid:
object { test?, include?, exclude?, parallel?, minify?, terserOptions?, extractComments? }"
`;
209 changes: 0 additions & 209 deletions test/__snapshots__/validation.test.js.snap

This file was deleted.

48 changes: 0 additions & 48 deletions test/__snapshots__/warningsFilter-option.test.js.snap

This file was deleted.

166 changes: 141 additions & 25 deletions test/__snapshots__/worker.test.js.snap
Original file line number Diff line number Diff line change
@@ -1,61 +1,177 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`matches snapshot normalizes when options.extractComments is regex: test1.js 1`] = `
exports[`worker normalizes when minimizerOptions.output.comments is string: all 1`] = `
Object {
"code": "var foo=1;/* hello */
// Comment
/* duplicate */
/* duplicate */",
"extractedComments": Array [],
}
`;

exports[`worker should match snapshot when minimizerOptions.compress.comments is boolean 1`] = `
Object {
"code": "var foo=1;",
"error": undefined,
"extractedComments": Array [],
"map": undefined,
"warnings": undefined,
}
`;

exports[`matches snapshot normalizes when terserOptions.extractComments is number: test4.js 1`] = `
exports[`worker should match snapshot when minimizerOptions.compress.comments is object 1`] = `
Object {
"code": "var foo=1;",
"error": undefined,
"extractedComments": Array [],
"map": undefined,
"warnings": undefined,
}
`;

exports[`matches snapshot normalizes when terserOptions.output.comments is string: all: test2.js 1`] = `
exports[`worker should match snapshot when minimizerOptions.extractComments is number 1`] = `
Object {
"code": "var foo=1;/* hello */",
"error": undefined,
"code": "var foo=1;",
"extractedComments": Array [],
"map": undefined,
"warnings": undefined,
}
`;

exports[`matches snapshot normalizes when terserOptions.output.comments is string: some: test3.js 1`] = `
exports[`worker should match snapshot when minimizerOptions.mangle is "null" 1`] = `
Object {
"code": "var foo=1;",
"extractedComments": Array [],
}
`;

exports[`worker should match snapshot when minimizerOptions.mangle is boolean 1`] = `
Object {
"code": "var foo=1;",
"extractedComments": Array [],
}
`;

exports[`worker should match snapshot when minimizerOptions.mangle is object 1`] = `
Object {
"code": "var a=1;",
"extractedComments": Array [],
}
`;

exports[`worker should match snapshot when minimizerOptions.output.comments is string: some 1`] = `
Object {
"code": "var foo=1;",
"extractedComments": Array [],
}
`;

exports[`worker should match snapshot when options.extractComments is "all" value 1`] = `
Object {
"code": "var foo=1;",
"extractedComments": Array [
"/* hello */",
"// Comment",
"/* duplicate */",
],
}
`;

exports[`worker should match snapshot when options.extractComments is "false" 1`] = `
Object {
"code": "var foo=1;",
"extractedComments": Array [],
}
`;

exports[`worker should match snapshot when options.extractComments is "some" value 1`] = `
Object {
"code": "var foo=1;",
"extractedComments": Array [],
}
`;

exports[`worker should match snapshot when options.extractComments is "true" 1`] = `
Object {
"code": "var foo=1;",
"extractedComments": Array [],
}
`;

exports[`worker should match snapshot when options.extractComments is "true" 2`] = `
"var foo = 1;/* hello */
// Comment
/* duplicate */
/* duplicate */"
`;

exports[`worker should match snapshot when options.extractComments is Function 1`] = `
Object {
"code": "var foo=1;",
"extractedComments": Array [
"/* hello */",
"// Comment",
"/* duplicate */",
],
}
`;

exports[`worker should match snapshot when options.extractComments is Object with "all" value 1`] = `
Object {
"code": "var foo=1;",
"extractedComments": Array [
"/* hello */",
"// Comment",
"/* duplicate */",
],
}
`;

exports[`worker should match snapshot when options.extractComments is Object with "some" value 1`] = `
Object {
"code": "var foo=1;",
"extractedComments": Array [],
}
`;

exports[`worker should match snapshot when options.extractComments is Object with "true" value 1`] = `
Object {
"code": "var foo=1;",
"extractedComments": Array [],
}
`;

exports[`worker should match snapshot when options.extractComments is RegExp 1`] = `
Object {
"code": "var foo=1;",
"extractedComments": Array [
"/* hello */",
],
}
`;

exports[`worker should match snapshot when options.extractComments is empty Object 1`] = `
Object {
"code": "var foo=1;",
"error": undefined,
"extractedComments": Array [],
"map": undefined,
"warnings": undefined,
}
`;

exports[`matches snapshot when applied with extract option set to a single file: test5.js 1`] = `
exports[`worker should match snapshot with extract option set to a single file 1`] = `
Object {
"code": "/******/function hello(o){console.log(o)}",
"error": undefined,
"extractedComments": Array [],
"map": undefined,
"warnings": undefined,
}
`;

exports[`matches snapshot when options.inputSourceMap: test6.js 1`] = `
exports[`worker should match snapshot with options.inputSourceMap 1`] = `
Object {
"code": "function foo(f){if(f)return bar()}",
"error": undefined,
"extractedComments": Array [],
"map": "{\\"version\\":3,\\"sources\\":[\\"test1.js\\"],\\"names\\":[\\"foo\\",\\"x\\",\\"not_called1\\"],\\"mappings\\":\\"AAAA,SAASA,IAAIC,GACT,GACIA,EAAA,OACAC\\"}",
"warnings": undefined,
"map": Object {
"mappings": "AAAA,SAASA,IAAIC,GAAK,GAAIA,EAAK,OAAOC",
"names": Array [
"foo",
"x",
"bar",
],
"sources": Array [
"test6.js",
],
"version": 3,
},
}
`;
674 changes: 395 additions & 279 deletions test/cache-option.test.js

Large diffs are not rendered by default.

44 changes: 0 additions & 44 deletions test/chunkFilter-option.test.js

This file was deleted.

8 changes: 4 additions & 4 deletions test/cjs.test.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import TerserPlugin from '../src';
import CJSTerserPlugin from '../src/cjs';
import src from '../src';
import cjs from '../src/cjs';

describe('CJS', () => {
it('should exported plugin', () => {
expect(CJSTerserPlugin).toEqual(TerserPlugin);
it('should export loader', () => {
expect(cjs).toEqual(src);
});
});
100 changes: 34 additions & 66 deletions test/exclude-option.test.js
Original file line number Diff line number Diff line change
@@ -1,105 +1,73 @@
import path from 'path';

import TerserPlugin from '../src/index';

import { cleanErrorStack, createCompiler, compile } from './helpers';
import {
compile,
getCompiler,
getErrors,
getWarnings,
readsAssets,
} from './helpers';

describe('when applied with `exclude` option', () => {
describe('exclude option', () => {
let compiler;

beforeEach(() => {
compiler = createCompiler({
compiler = getCompiler({
entry: {
excluded1: `${__dirname}/fixtures/excluded1.js`,
excluded2: `${__dirname}/fixtures/excluded2.js`,
entry: `${__dirname}/fixtures/entry.js`,
excluded1: path.resolve(__dirname, './fixtures/excluded1.js'),
excluded2: path.resolve(__dirname, './fixtures/excluded2.js'),
entry: path.resolve(__dirname, './fixtures/entry.js'),
},
});
});

it('matches snapshot for a single `exclude` value ({RegExp})', () => {
it('should match snapshot for a single RegExp value', async () => {
new TerserPlugin({
exclude: /excluded1/i,
}).apply(compiler);

return compile(compiler).then((stats) => {
const errors = stats.compilation.errors.map(cleanErrorStack);
const warnings = stats.compilation.warnings.map(cleanErrorStack);

expect(errors).toMatchSnapshot('errors');
expect(warnings).toMatchSnapshot('warnings');
const stats = await compile(compiler);

for (const file in stats.compilation.assets) {
if (
Object.prototype.hasOwnProperty.call(stats.compilation.assets, file)
) {
expect(stats.compilation.assets[file].source()).toMatchSnapshot(file);
}
}
});
expect(readsAssets(compiler, stats)).toMatchSnapshot('assets');
expect(getErrors(stats)).toMatchSnapshot('errors');
expect(getWarnings(stats)).toMatchSnapshot('warnings');
});

it('matches snapshot for a single `exclude` value ({String})', () => {
it('should match snapshot for a single String value', async () => {
new TerserPlugin({
exclude: 'excluded1',
}).apply(compiler);

return compile(compiler).then((stats) => {
const errors = stats.compilation.errors.map(cleanErrorStack);
const warnings = stats.compilation.warnings.map(cleanErrorStack);
const stats = await compile(compiler);

expect(errors).toMatchSnapshot('errors');
expect(warnings).toMatchSnapshot('warnings');

for (const file in stats.compilation.assets) {
if (
Object.prototype.hasOwnProperty.call(stats.compilation.assets, file)
) {
expect(stats.compilation.assets[file].source()).toMatchSnapshot(file);
}
}
});
expect(readsAssets(compiler, stats)).toMatchSnapshot('assets');
expect(getErrors(stats)).toMatchSnapshot('errors');
expect(getWarnings(stats)).toMatchSnapshot('warnings');
});

it('matches snapshot for multiple `exclude` values ({RegExp})', () => {
it('should match snapshot for multiple RegExp values', async () => {
new TerserPlugin({
exclude: [/excluded1/i, /excluded2/i],
}).apply(compiler);

return compile(compiler).then((stats) => {
const errors = stats.compilation.errors.map(cleanErrorStack);
const warnings = stats.compilation.warnings.map(cleanErrorStack);
const stats = await compile(compiler);

expect(errors).toMatchSnapshot('errors');
expect(warnings).toMatchSnapshot('warnings');

for (const file in stats.compilation.assets) {
if (
Object.prototype.hasOwnProperty.call(stats.compilation.assets, file)
) {
expect(stats.compilation.assets[file].source()).toMatchSnapshot(file);
}
}
});
expect(readsAssets(compiler, stats)).toMatchSnapshot('assets');
expect(getErrors(stats)).toMatchSnapshot('errors');
expect(getWarnings(stats)).toMatchSnapshot('warnings');
});

it('matches snapshot for multiple `exclude` values ({String})', () => {
it('should match snapshot for multiple String values', async () => {
new TerserPlugin({
exclude: ['excluded1', 'excluded2'],
}).apply(compiler);

return compile(compiler).then((stats) => {
const errors = stats.compilation.errors.map(cleanErrorStack);
const warnings = stats.compilation.warnings.map(cleanErrorStack);
const stats = await compile(compiler);

expect(errors).toMatchSnapshot('errors');
expect(warnings).toMatchSnapshot('warnings');

for (const file in stats.compilation.assets) {
if (
Object.prototype.hasOwnProperty.call(stats.compilation.assets, file)
) {
expect(stats.compilation.assets[file].source()).toMatchSnapshot(file);
}
}
});
expect(readsAssets(compiler, stats)).toMatchSnapshot('assets');
expect(getErrors(stats)).toMatchSnapshot('errors');
expect(getWarnings(stats)).toMatchSnapshot('warnings');
});
});
720 changes: 499 additions & 221 deletions test/extractComments-option.test.js

Large diffs are not rendered by default.

7 changes: 7 additions & 0 deletions test/fixtures/asset-resource.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import script from './emitted.js'

const myVar = 12;

console.log(myVar, script);

export default 12;
2 changes: 2 additions & 0 deletions test/fixtures/comments.js
Original file line number Diff line number Diff line change
@@ -26,4 +26,6 @@ import('./nested/comments.js');
* Foo
*/

// @lic

module.exports = Math.random();
2 changes: 2 additions & 0 deletions test/fixtures/copy.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
var foo = 12;
console.log(foo);
2 changes: 2 additions & 0 deletions test/fixtures/copy.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
var foo = 12;
console.log(foo);
2 changes: 2 additions & 0 deletions test/fixtures/copy.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
var foo = 12;
console.log(foo);
5 changes: 5 additions & 0 deletions test/fixtures/emit-loader.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
module.exports = function(content) {
this.emitFile("extra-file.js", 'var a = 1; console.log(a);');

return content;
};
1 change: 1 addition & 0 deletions test/fixtures/emitted.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
console.log('HERE');
Empty file added test/fixtures/empty.js
Empty file.
11 changes: 7 additions & 4 deletions test/fixtures/entry.mjs
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
// foo
/* @preserve*/
// bar
const a = 2 + 2;

module.exports = function Foo() {
function test() {
const b = 2 + 2;
console.log(b + 1 + 2);
};
console.log(b + 1 + 2 + a);
}

test();

module.exports = test;
7 changes: 7 additions & 0 deletions test/fixtures/file-loader.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import script from '!!file-loader?name=[path][name].[ext]!./emitted.js'

const myVar = 12;

console.log(myVar, script);

export default 12;
1 change: 1 addition & 0 deletions test/fixtures/file.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
module.exports = "ok";
7 changes: 7 additions & 0 deletions test/fixtures/file.worker.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
/*! Legal Comment 1 */

/*! Legal Comment 2 */

/*! Legal Comment 3 */

onmessage = function (event) {};
1 change: 1 addition & 0 deletions test/fixtures/shebang-1.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
console.log('HERE');
3 changes: 3 additions & 0 deletions test/fixtures/shebang.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
/* Comment */
/*! Legal Comment */
console.log('HERE');
10 changes: 10 additions & 0 deletions test/fixtures/worker-loader.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
/*! Legal Comment */

import Worker from './file.worker.js';

const worker = new Worker();

worker.postMessage({ a: 1 });
worker.onmessage = function (event) {};

worker.addEventListener('message', function (event) {});
96 changes: 0 additions & 96 deletions test/helpers.js

This file was deleted.

16 changes: 16 additions & 0 deletions test/helpers/BrokenCodePlugin.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import webpack from 'webpack';

export default class BrokenCodePlugin {
apply(compiler) {
const plugin = { name: this.constructor.name };

compiler.hooks.thisCompilation.tap(plugin, (compilation) => {
compilation.hooks.additionalAssets.tap(plugin, () => {
// eslint-disable-next-line no-param-reassign
compilation.assets['broken.js'] = new webpack.sources.RawSource(
'`Broken==='
);
});
});
}
}
16 changes: 16 additions & 0 deletions test/helpers/ExistingCommentsFile.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import webpack from 'webpack';

export default class ExistingCommentsFile {
apply(compiler) {
const plugin = { name: this.constructor.name };

compiler.hooks.thisCompilation.tap(plugin, (compilation) => {
compilation.hooks.additionalAssets.tap(plugin, () => {
// eslint-disable-next-line no-param-reassign
compilation.assets['licenses.txt'] = new webpack.sources.RawSource(
'// Existing Comment'
);
});
});
}
}
25 changes: 25 additions & 0 deletions test/helpers/ModifyExistingAsset.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import webpack from 'webpack';

export default class ExistingCommentsFile {
constructor(options = {}) {
this.options = options;
}

apply(compiler) {
const plugin = { name: this.constructor.name };

compiler.hooks.thisCompilation.tap(plugin, (compilation) => {
compilation.hooks.additionalAssets.tap(plugin, () => {
// eslint-disable-next-line no-param-reassign
compilation.assets[
this.options.name
] = new webpack.sources.ConcatSource(
`function changed() {} ${
this.options.comment ? '/*! CHANGED */' : ''
}`,
compilation.assets[this.options.name]
);
});
});
}
}
11 changes: 11 additions & 0 deletions test/helpers/compile.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
export default (compiler) => {
return new Promise((resolve, reject) => {
compiler.run((error, stats) => {
if (error) {
return reject(error);
}

return resolve(stats);
});
});
};
9 changes: 9 additions & 0 deletions test/helpers/countPlugins.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
export default function countPlugins({ hooks }) {
return Object.keys(hooks).reduce((aggregate, name) => {
// eslint-disable-next-line no-param-reassign
aggregate[name] = Array.isArray(hooks[name].taps)
? hooks[name].taps.length
: 0;
return aggregate;
}, {});
}
22 changes: 22 additions & 0 deletions test/helpers/execute.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import Module from 'module';
import path from 'path';

const parentModule = module;

export default (code) => {
const resource = 'test.js';
const module = new Module(resource, parentModule);
// eslint-disable-next-line no-underscore-dangle
module.paths = Module._nodeModulePaths(
path.resolve(__dirname, '../fixtures')
);
module.filename = resource;

// eslint-disable-next-line no-underscore-dangle
module._compile(
`let __export__;${code};module.exports = __export__;`,
resource
);

return module.exports;
};
31 changes: 31 additions & 0 deletions test/helpers/getCompiler.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import path from 'path';

import webpack from 'webpack';
import { createFsFromVolume, Volume } from 'memfs';

export default function getCompiler(options = {}) {
const compiler = webpack(
Array.isArray(options)
? options
: {
mode: 'production',
bail: true,
entry: path.resolve(__dirname, '../fixtures/entry.js'),
optimization: {
minimize: false,
},
output: {
pathinfo: false,
path: path.resolve(__dirname, 'dist'),
filename: '[name].js',
chunkFilename: '[id].[name].js',
},
plugins: [],
...options,
}
);

compiler.outputFileSystem = createFsFromVolume(new Volume());

return compiler;
}
5 changes: 5 additions & 0 deletions test/helpers/getErrors.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import normalizeErrors from './normalizeErrors';

export default (stats) => {
return normalizeErrors(stats.compilation.errors).sort();
};
5 changes: 5 additions & 0 deletions test/helpers/getWarnings.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import normalizeErrors from './normalizeErrors';

export default (stats) => {
return normalizeErrors(stats.compilation.warnings).sort();
};
27 changes: 27 additions & 0 deletions test/helpers/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import BrokenCodePlugin from './BrokenCodePlugin';
import compile from './compile';
import countPlugins from './countPlugins';
import execute from './execute';
import ExistingCommentsFile from './ExistingCommentsFile';
import getCompiler from './getCompiler';
import getErrors from './getErrors';
import getWarnings from './getWarnings';
import ModifyExistingAsset from './ModifyExistingAsset';
import readAsset from './readAsset';
import readsAssets from './readAssets';
import normalizeErrors from './normalizeErrors';

export {
BrokenCodePlugin,
compile,
countPlugins,
ExistingCommentsFile,
execute,
getCompiler,
getErrors,
getWarnings,
ModifyExistingAsset,
normalizeErrors,
readAsset,
readsAssets,
};
19 changes: 19 additions & 0 deletions test/helpers/normalizeErrors.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
function removeCWD(str) {
const isWin = process.platform === 'win32';
let cwd = process.cwd();

if (isWin) {
// eslint-disable-next-line no-param-reassign
str = str.replace(/\\/g, '/');
// eslint-disable-next-line no-param-reassign
cwd = cwd.replace(/\\/g, '/');
}

return str.replace(new RegExp(cwd, 'g'), '');
}

export default (errors) => {
return errors.map((error) =>
removeCWD(error.toString().split('\n').slice(0, 2).join('\n'))
);
};
23 changes: 23 additions & 0 deletions test/helpers/readAsset.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import path from 'path';

export default (asset, compiler, stats) => {
const usedFs = compiler.outputFileSystem;
const outputPath = stats.compilation.outputOptions.path;

let data = '';
let targetFile = asset;

const queryStringIdx = targetFile.indexOf('?');

if (queryStringIdx >= 0) {
targetFile = targetFile.substr(0, queryStringIdx);
}

try {
data = usedFs.readFileSync(path.join(outputPath, targetFile)).toString();
} catch (error) {
data = error.toString();
}

return data;
};
11 changes: 11 additions & 0 deletions test/helpers/readAssets.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import readAsset from './readAsset';

export default function readAssets(compiler, stats) {
const assets = {};

Object.keys(stats.compilation.assets).forEach((asset) => {
assets[asset] = readAsset(asset, compiler, stats);
});

return assets;
}
28 changes: 28 additions & 0 deletions test/helpers/snapshotResolver.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
const path = require('path');

const webpack = require('webpack');

// eslint-disable-next-line global-require
const [webpackVersion] = webpack.version;
const snapshotExtension = `.snap.webpack${webpackVersion}`;

// eslint-disable-next-line no-console
console.log('Current webpack version:', webpackVersion);

module.exports = {
resolveSnapshotPath: (testPath) =>
path.join(
path.dirname(testPath),
'__snapshots__',
`${path.basename(testPath)}${snapshotExtension}`
),
resolveTestPath: (snapshotPath) =>
snapshotPath
.replace(`${path.sep}__snapshots__`, '')
.slice(0, -snapshotExtension.length),
testPathForConsistencyCheck: path.join(
'consistency_check',
'__tests__',
'example.test.js'
),
};
100 changes: 34 additions & 66 deletions test/include-option.test.js
Original file line number Diff line number Diff line change
@@ -1,105 +1,73 @@
import path from 'path';

import TerserPlugin from '../src/index';

import { cleanErrorStack, createCompiler, compile } from './helpers';
import {
compile,
getCompiler,
getErrors,
getWarnings,
readsAssets,
} from './helpers';

describe('when applied with `include` option', () => {
describe('include option', () => {
let compiler;

beforeEach(() => {
compiler = createCompiler({
compiler = getCompiler({
entry: {
included1: `${__dirname}/fixtures/included1.js`,
included2: `${__dirname}/fixtures/included2.js`,
entry: `${__dirname}/fixtures/entry.js`,
included1: path.resolve(__dirname, './fixtures/included1.js'),
included2: path.resolve(__dirname, './fixtures/included2.js'),
entry: path.resolve(__dirname, './fixtures/entry.js'),
},
});
});

it('matches snapshot for a single `include` value ({RegExp})', () => {
it('should match snapshot for a single RegExp value', async () => {
new TerserPlugin({
include: /included1/i,
}).apply(compiler);

return compile(compiler).then((stats) => {
const errors = stats.compilation.errors.map(cleanErrorStack);
const warnings = stats.compilation.warnings.map(cleanErrorStack);

expect(errors).toMatchSnapshot('errors');
expect(warnings).toMatchSnapshot('warnings');
const stats = await compile(compiler);

for (const file in stats.compilation.assets) {
if (
Object.prototype.hasOwnProperty.call(stats.compilation.assets, file)
) {
expect(stats.compilation.assets[file].source()).toMatchSnapshot(file);
}
}
});
expect(readsAssets(compiler, stats)).toMatchSnapshot('assets');
expect(getErrors(stats)).toMatchSnapshot('errors');
expect(getWarnings(stats)).toMatchSnapshot('warnings');
});

it('matches snapshot for a single `include` value ({String})', () => {
it('should match snapshot for a single String value', async () => {
new TerserPlugin({
include: 'included1',
}).apply(compiler);

return compile(compiler).then((stats) => {
const errors = stats.compilation.errors.map(cleanErrorStack);
const warnings = stats.compilation.warnings.map(cleanErrorStack);
const stats = await compile(compiler);

expect(errors).toMatchSnapshot('errors');
expect(warnings).toMatchSnapshot('warnings');

for (const file in stats.compilation.assets) {
if (
Object.prototype.hasOwnProperty.call(stats.compilation.assets, file)
) {
expect(stats.compilation.assets[file].source()).toMatchSnapshot(file);
}
}
});
expect(readsAssets(compiler, stats)).toMatchSnapshot('assets');
expect(getErrors(stats)).toMatchSnapshot('errors');
expect(getWarnings(stats)).toMatchSnapshot('warnings');
});

it('matches snapshot for multiple `include` values ({RegExp})', () => {
it('should match snapshot for multiple RegExp values', async () => {
new TerserPlugin({
include: [/included1/i, /included2/i],
}).apply(compiler);

return compile(compiler).then((stats) => {
const errors = stats.compilation.errors.map(cleanErrorStack);
const warnings = stats.compilation.warnings.map(cleanErrorStack);
const stats = await compile(compiler);

expect(errors).toMatchSnapshot('errors');
expect(warnings).toMatchSnapshot('warnings');

for (const file in stats.compilation.assets) {
if (
Object.prototype.hasOwnProperty.call(stats.compilation.assets, file)
) {
expect(stats.compilation.assets[file].source()).toMatchSnapshot(file);
}
}
});
expect(readsAssets(compiler, stats)).toMatchSnapshot('assets');
expect(getErrors(stats)).toMatchSnapshot('errors');
expect(getWarnings(stats)).toMatchSnapshot('warnings');
});

it('matches snapshot for multiple `include` values ({String})', () => {
it('should match snapshot for multiple String values', async () => {
new TerserPlugin({
include: ['included1', 'included2'],
}).apply(compiler);

return compile(compiler).then((stats) => {
const errors = stats.compilation.errors.map(cleanErrorStack);
const warnings = stats.compilation.warnings.map(cleanErrorStack);
const stats = await compile(compiler);

expect(errors).toMatchSnapshot('errors');
expect(warnings).toMatchSnapshot('warnings');

for (const file in stats.compilation.assets) {
if (
Object.prototype.hasOwnProperty.call(stats.compilation.assets, file)
) {
expect(stats.compilation.assets[file].source()).toMatchSnapshot(file);
}
}
});
expect(readsAssets(compiler, stats)).toMatchSnapshot('assets');
expect(getErrors(stats)).toMatchSnapshot('errors');
expect(getWarnings(stats)).toMatchSnapshot('warnings');
});
});
Loading