From 9a9898b2373c0a21a5be6c100546a1ff15b334da Mon Sep 17 00:00:00 2001 From: evilebottnawi Date: Mon, 30 Jul 2018 21:52:03 +0300 Subject: [PATCH 01/17] refactor: tests --- test/cjs.test.js | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 test/cjs.test.js diff --git a/test/cjs.test.js b/test/cjs.test.js new file mode 100644 index 00000000..26081bc8 --- /dev/null +++ b/test/cjs.test.js @@ -0,0 +1,8 @@ +import UglifyJsPlugin from '../src'; +import CJSUglifyJsPlugin from '../src/cjs'; + +describe('CJS', () => { + it('should exported plugin', () => { + expect(CJSUglifyJsPlugin).toEqual(UglifyJsPlugin); + }); +}); From 1838b46c8e51f1824741e84ac048f05d1f4121ce Mon Sep 17 00:00:00 2001 From: evilebottnawi Date: Tue, 31 Jul 2018 18:46:20 +0300 Subject: [PATCH 02/17] refactor: `extractComments` tests --- .../extractComments-option.test.js.snap | 2007 ++++++++++++++++- test/extractComments-option.test.js | 526 ++--- test/fixtures/comments.js | 29 + test/fixtures/nested/comments.js | 27 + 4 files changed, 2145 insertions(+), 444 deletions(-) create mode 100644 test/fixtures/comments.js create mode 100644 test/fixtures/nested/comments.js diff --git a/test/__snapshots__/extractComments-option.test.js.snap b/test/__snapshots__/extractComments-option.test.js.snap index 9fc6d02d..9193bc49 100644 --- a/test/__snapshots__/extractComments-option.test.js.snap +++ b/test/__snapshots__/extractComments-option.test.js.snap @@ -1,130 +1,1995 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`when options.extractComments normalizes when options.extractComments is boolean - "true": errors 1`] = `Array []`; +exports[`when applied with \`extractComments\` option matches snapshot for a \`/Foo/\` value (regexp): chunks/0.0.42bf13661c716a174f76.js 1`] = ` +"/*! For license information please see 0.0.42bf13661c716a174f76.js.LICENSE */ +webpackJsonp([0],[,function(n,o){n.exports=Math.random()}]);" +`; -exports[`when options.extractComments normalizes when options.extractComments is boolean - "true": test.js 1`] = `"var foo=1;"`; +exports[`when applied with \`extractComments\` option matches snapshot for a \`/Foo/\` value (regexp): chunks/0.0.42bf13661c716a174f76.js.LICENSE 1`] = ` +"/*! Legal Foo */ -exports[`when options.extractComments normalizes when options.extractComments is boolean - "true": test1.js 1`] = ` -"/*! For license information please see test1.js.LICENSE */ -var foo=1;" -`; +// Foo -exports[`when options.extractComments normalizes when options.extractComments is boolean - "true": test1.js.LICENSE 1`] = ` -"/*! Legal Comment */ +/* + Foo Bar + */ + +/* +* Foo +*/ " `; -exports[`when options.extractComments normalizes when options.extractComments is boolean - "true": warnings 1`] = `Array []`; +exports[`when applied with \`extractComments\` option matches snapshot for a \`/Foo/\` value (regexp): errors 1`] = `Array []`; -exports[`when options.extractComments normalizes when options.extractComments is function: errors 1`] = `Array []`; +exports[`when applied with \`extractComments\` option matches snapshot for a \`/Foo/\` value (regexp): filename/manifest.3221d314bfa94c03ba98.js 1`] = `"!function(e){var n=window.webpackJsonp;window.webpackJsonp=function(r,c,u){for(var a,i,f,s=0,l=[];s { - it('normalizes extractConmments', () => { - const pluginEnvironment = new PluginEnvironment(); - const compilerEnv = pluginEnvironment.getEnvironmentStub(); - compilerEnv.context = ''; - - const plugin = new UglifyJsPlugin({ - uglifyOptions: { - warnings: true, - mangle: { - properties: { - builtins: true, - }, - }, - }, - extractComments: true, - }); - plugin.apply(compilerEnv); +import { cleanErrorStack, compile, createCompiler } from './helpers'; - const [eventBinding] = pluginEnvironment.getEventBindings(); - const chunkPluginEnvironment = new PluginEnvironment(); +describe('when applied with `extractComments` option', () => { + let compiler; - const compilation = chunkPluginEnvironment.getEnvironmentStub(); - compilation.assets = { - 'test.js': { - source: () => 'var foo = 1;', + beforeEach(() => { + compiler = createCompiler({ + entry: { + one: `${__dirname}/fixtures/comments.js`, }, - 'test1.js': { - source: () => 'function foo(x) { if (x) { return bar(); not_called1(); } }', - map: () => { - return { - version: 3, - sources: ['test1.js'], - names: ['foo', 'x', 'bar', 'not_called1'], - mappings: 'AAAA,QAASA,KAAIC,GACT,GAAIA,EAAG,CACH,MAAOC,MACPC', - }; - }, + output: { + filename: 'filename/[name].[chunkhash].js', + chunkFilename: 'chunks/[id].[name].[chunkhash].js', }, - }; - compilation.warnings = []; - compilation.errors = []; + }); + }); + + it('matches snapshot when is not specify', () => { + new UglifyJsPlugin().apply(compiler); - eventBinding.handler(compilation); - const [compilationEventBinding] = chunkPluginEnvironment.getEventBindings(); + return compile(compiler).then((stats) => { + const errors = stats.compilation.errors.map(cleanErrorStack); + const warnings = stats.compilation.warnings.map(cleanErrorStack); - compilationEventBinding.handler([{ - files: ['test.js'], - }], () => { - expect(compilation.errors.length).toBe(0); + 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); + } + } }); }); - it('normalizes when options.extractComments is not specify', () => { - const pluginEnvironment = new PluginEnvironment(); - const compilerEnv = pluginEnvironment.getEnvironmentStub(); - compilerEnv.context = ''; - - const plugin = new UglifyJsPlugin(); - plugin.apply(compilerEnv); - const [eventBinding] = pluginEnvironment.getEventBindings(); - const chunkPluginEnvironment = new PluginEnvironment(); - const compilation = chunkPluginEnvironment.getEnvironmentStub(); - compilation.assets = { - 'test.js': { - source: () => '// Comment\nvar foo = 1;', - }, - 'test1.js': { - source: () => '/*! Legal Comment */\nvar foo = 1;', - }, - }; - compilation.warnings = []; - compilation.errors = []; - - eventBinding.handler(compilation); - const [compilationEventBinding] = chunkPluginEnvironment.getEventBindings(); - - compilationEventBinding.handler([{ - files: ['test.js', 'test1.js'], - }], () => { - for (const file in compilation.assets) { - if (Object.prototype.hasOwnProperty.call(compilation.assets, file)) { - expect(compilation.assets[file].source()).toMatchSnapshot(file); + it('matches snapshot for a `true` value', () => { + new UglifyJsPlugin({ extractComments: true }).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'); + + 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(compilation.errors).toMatchSnapshot('errors'); - expect(compilation.warnings).toMatchSnapshot('warnings'); }); }); - it('normalizes when options.extractComments is boolean - "true"', () => { - const pluginEnvironment = new PluginEnvironment(); - const compilerEnv = pluginEnvironment.getEnvironmentStub(); - compilerEnv.context = ''; + it('matches snapshot for a `false` value', () => { + new UglifyJsPlugin({ extractComments: false }).apply(compiler); - const plugin = new UglifyJsPlugin({ - extractComments: true, - }); - plugin.apply(compilerEnv); - const [eventBinding] = pluginEnvironment.getEventBindings(); - const chunkPluginEnvironment = new PluginEnvironment(); - const compilation = chunkPluginEnvironment.getEnvironmentStub(); - compilation.assets = { - 'test.js': { - source: () => '// Comment\nvar foo = 1;', - }, - 'test1.js': { - source: () => '/*! Legal Comment */\nvar foo = 1;', - }, - }; - compilation.warnings = []; - compilation.errors = []; - - eventBinding.handler(compilation); - const [compilationEventBinding] = chunkPluginEnvironment.getEventBindings(); - - compilationEventBinding.handler([{ - files: ['test.js', 'test1.js'], - }], () => { - for (const file in compilation.assets) { - if (Object.prototype.hasOwnProperty.call(compilation.assets, file)) { - expect(compilation.assets[file].source()).toMatchSnapshot(file); + 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'); + + 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(compilation.errors).toMatchSnapshot('errors'); - expect(compilation.warnings).toMatchSnapshot('warnings'); }); }); - it('normalizes when options.extractComments is regex', () => { - const pluginEnvironment = new PluginEnvironment(); - const compilerEnv = pluginEnvironment.getEnvironmentStub(); - compilerEnv.context = ''; + it('matches snapshot for a `/Foo/` value (regexp)', () => { + new UglifyJsPlugin({ extractComments: /Foo/ }).apply(compiler); - const plugin = new UglifyJsPlugin({ - extractComments: /foo/, - }); - plugin.apply(compilerEnv); - const [eventBinding] = pluginEnvironment.getEventBindings(); - const chunkPluginEnvironment = new PluginEnvironment(); - const compilation = chunkPluginEnvironment.getEnvironmentStub(); - compilation.assets = { - 'test.js': { - source: () => '// Comment\nvar foo = 1;', - }, - 'test1.js': { - source: () => '// foo\nvar foo = 1;', - }, - }; - compilation.warnings = []; - compilation.errors = []; - - eventBinding.handler(compilation); - const [compilationEventBinding] = chunkPluginEnvironment.getEventBindings(); - - compilationEventBinding.handler([{ - files: ['test.js', 'test1.js'], - }], () => { - for (const file in compilation.assets) { - if (Object.prototype.hasOwnProperty.call(compilation.assets, file)) { - expect(compilation.assets[file].source()).toMatchSnapshot(file); + 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'); + + 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(compilation.errors).toMatchSnapshot('errors'); - expect(compilation.warnings).toMatchSnapshot('warnings'); }); }); - it('normalizes when options.extractComments is string', () => { - const pluginEnvironment = new PluginEnvironment(); - const compilerEnv = pluginEnvironment.getEnvironmentStub(); - compilerEnv.context = ''; + it('matches snapshot for a `all` value (string)', () => { + new UglifyJsPlugin({ extractComments: 'all' }).apply(compiler); - const plugin = new UglifyJsPlugin({ - extractComments: 'all', - }); - plugin.apply(compilerEnv); - const [eventBinding] = pluginEnvironment.getEventBindings(); - const chunkPluginEnvironment = new PluginEnvironment(); - const compilation = chunkPluginEnvironment.getEnvironmentStub(); - compilation.assets = { - 'test.js': { - source: () => '// Comment\nvar foo = 1;', - }, - 'test1.js': { - source: () => '/* Comment */\nvar foo = 1;', - }, - }; - compilation.warnings = []; - compilation.errors = []; - - eventBinding.handler(compilation); - const [compilationEventBinding] = chunkPluginEnvironment.getEventBindings(); - - compilationEventBinding.handler([{ - files: ['test.js', 'test1.js'], - }], () => { - for (const file in compilation.assets) { - if (Object.prototype.hasOwnProperty.call(compilation.assets, file)) { - expect(compilation.assets[file].source()).toMatchSnapshot(file); + 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'); + + 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(compilation.errors).toMatchSnapshot('errors'); - expect(compilation.warnings).toMatchSnapshot('warnings'); }); }); - it('normalizes when options.extractComments is function', () => { - const pluginEnvironment = new PluginEnvironment(); - const compilerEnv = pluginEnvironment.getEnvironmentStub(); - compilerEnv.context = ''; + it('matches snapshot for a `some` value (string)', () => { + new UglifyJsPlugin({ extractComments: 'some' }).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 plugin = new UglifyJsPlugin({ - extractComments: () => true, + for (const file in stats.compilation.assets) { + if (Object.prototype.hasOwnProperty.call(stats.compilation.assets, file)) { + expect(stats.compilation.assets[file].source()).toMatchSnapshot(file); + } + } }); - plugin.apply(compilerEnv); - const [eventBinding] = pluginEnvironment.getEventBindings(); - const chunkPluginEnvironment = new PluginEnvironment(); - const compilation = chunkPluginEnvironment.getEnvironmentStub(); - compilation.assets = { - 'test.js': { - source: () => '// Comment\nvar foo = 1;', - }, - 'test1.js': { - source: () => '/* Comment */\nvar foo = 1;', - }, - }; - compilation.warnings = []; - compilation.errors = []; - - eventBinding.handler(compilation); - const [compilationEventBinding] = chunkPluginEnvironment.getEventBindings(); - - compilationEventBinding.handler([{ - files: ['test.js', 'test1.js'], - }], () => { - for (const file in compilation.assets) { - if (Object.prototype.hasOwnProperty.call(compilation.assets, file)) { - expect(compilation.assets[file].source()).toMatchSnapshot(file); + }); + + it('matches snapshot for a `Foo` value (string)', () => { + new UglifyJsPlugin({ extractComments: 'Foo' }).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'); + + 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(compilation.errors).toMatchSnapshot('errors'); - expect(compilation.warnings).toMatchSnapshot('warnings'); }); }); - it('normalizes when options.extractComments is object', () => { - const pluginEnvironment = new PluginEnvironment(); - const compilerEnv = pluginEnvironment.getEnvironmentStub(); - compilerEnv.context = ''; + it('matches snapshot for a `function value', () => { + new UglifyJsPlugin({ extractComments: () => true }).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'); + + for (const file in stats.compilation.assets) { + if (Object.prototype.hasOwnProperty.call(stats.compilation.assets, file)) { + expect(stats.compilation.assets[file].source()).toMatchSnapshot(file); + } + } + }); + }); - const plugin = new UglifyJsPlugin({ + it('matches snapshot for a object value (extracts comments to multiple files)', () => { + new UglifyJsPlugin({ extractComments: { condition: true, filename(file) { @@ -261,176 +171,46 @@ describe('when options.extractComments', () => { return `License information can be found in ${licenseFile}`; }, }, - }); - plugin.apply(compilerEnv); - const [eventBinding] = pluginEnvironment.getEventBindings(); - const chunkPluginEnvironment = new PluginEnvironment(); - const compilation = chunkPluginEnvironment.getEnvironmentStub(); - compilation.assets = { - 'test.js': { - source: () => '// Comment\nvar foo = 1;', - }, - }; - compilation.warnings = []; - compilation.errors = []; - - eventBinding.handler(compilation); - const [compilationEventBinding] = chunkPluginEnvironment.getEventBindings(); - - compilationEventBinding.handler([{ - files: ['test.js'], - }], () => { - for (const file in compilation.assets) { - if (Object.prototype.hasOwnProperty.call(compilation.assets, file)) { - expect(compilation.assets[file].source()).toMatchSnapshot(file); - } - } - expect(compilation.errors).toMatchSnapshot('errors'); - expect(compilation.warnings).toMatchSnapshot('warnings'); - }); - }); + }).apply(compiler); - it('normalizes when options.extractComments is string - "all" && license file should be relative source file', () => { - const pluginEnvironment = new PluginEnvironment(); - const compilerEnv = pluginEnvironment.getEnvironmentStub(); - compilerEnv.context = ''; + return compile(compiler).then((stats) => { + const errors = stats.compilation.errors.map(cleanErrorStack); + const warnings = stats.compilation.warnings.map(cleanErrorStack); - const plugin = new UglifyJsPlugin({ - extractComments: 'all', - }); - plugin.apply(compilerEnv); - const [eventBinding] = pluginEnvironment.getEventBindings(); - const chunkPluginEnvironment = new PluginEnvironment(); - const compilation = chunkPluginEnvironment.getEnvironmentStub(); - compilation.assets = { - 'nested/test.js': { - source: () => '// Comment\nvar foo = 1;', - }, - 'nested/nested/test1.js': { - source: () => '/* Comment */\nvar foo = 1;', - }, - }; - compilation.warnings = []; - compilation.errors = []; - - eventBinding.handler(compilation); - const [compilationEventBinding] = chunkPluginEnvironment.getEventBindings(); - - compilationEventBinding.handler([{ - files: ['nested/test.js', 'nested/nested/test1.js'], - }], () => { - for (const file in compilation.assets) { - if (Object.prototype.hasOwnProperty.call(compilation.assets, file)) { - expect(compilation.assets[file].source()).toMatchSnapshot(file); + 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(compilation.errors).toMatchSnapshot('errors'); - expect(compilation.warnings).toMatchSnapshot('warnings'); }); }); - describe('when applied with extract option set to a single file', () => { - let eventBindings; - let eventBinding; - - beforeEach(() => { - const pluginEnvironment = new PluginEnvironment(); - const compilerEnv = pluginEnvironment.getEnvironmentStub(); - compilerEnv.context = ''; - - const plugin = new UglifyJsPlugin({ - uglifyOptions: { - output: { - comments: 'all', - }, - }, - extractComments: { - condition: /.*/, - filename: 'extracted-comments.js', + it('matches snapshot for a object value (extracts comments to a single file)', () => { + new UglifyJsPlugin({ + extractComments: { + condition: true, + filename: 'extracted-comments.js', + banner(licenseFile) { + return `License information can be found in ${licenseFile}`; }, - }); - plugin.apply(compilerEnv); - eventBindings = pluginEnvironment.getEventBindings(); - }); + }, + }).apply(compiler); - it('binds one event handler', () => { - expect(eventBindings.length).toBe(1); - }); + 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'); - describe('compilation handler', () => { - beforeEach(() => { - [eventBinding] = eventBindings; - }); - - it('binds to compilation event', () => { - expect(eventBinding.name).toBe('compilation'); - }); - - describe('when called', () => { - let chunkPluginEnvironment; - let compilationEventBindings; - let compilationEventBinding; - let compilation; - - beforeEach(() => { - chunkPluginEnvironment = new PluginEnvironment(); - compilation = chunkPluginEnvironment.getEnvironmentStub(); - compilation.assets = { - 'test.js': { - source: () => '/* This is a comment from test.js */ function foo(bar) { return bar; }', - }, - 'test2.js': { - source: () => '// This is a comment from test2.js\nfunction foo2(bar) { return bar; }', - }, - 'test3.js': { - source: () => '/* This is a comment from test3.js */ function foo3(bar) { return bar; }\n// This is another comment from test3.js\nfunction foobar3(baz) { return baz; }', - }, - }; - compilation.errors = []; - compilation.warnings = []; - - eventBinding.handler(compilation); - compilationEventBindings = chunkPluginEnvironment.getEventBindings(); - }); - - it('binds one event handler', () => { - expect(compilationEventBindings.length).toBe(1); - }); - - describe('optimize-chunk-assets handler', () => { - beforeEach(() => { - [compilationEventBinding] = compilationEventBindings; - }); - - it('binds to optimize-chunk-assets event', () => { - expect(compilationEventBinding.name).toEqual('optimize-chunk-assets'); - }); - - it('preserves comments', () => { - compilationEventBinding.handler([{ - files: ['test.js', 'test2.js', 'test3.js'], - }], () => { - expect(compilation.assets['test.js'].source()).toEqual(expect.stringContaining('/*')); - expect(compilation.assets['test2.js'].source()).toEqual(expect.stringContaining('//')); - expect(compilation.assets['test3.js'].source()).toEqual(expect.stringContaining('/*')); - expect(compilation.assets['test3.js'].source()).toEqual(expect.stringContaining('//')); - }); - }); - - it('extracts comments to specified file', () => { - compilationEventBinding.handler([{ - files: ['test.js', 'test2.js', 'test3.js'], - }], () => { - expect(compilation.errors.length).toBe(0); - expect(compilation.assets['extracted-comments.js'].source()).toEqual(expect.stringContaining('/* This is a comment from test.js */')); - expect(compilation.assets['extracted-comments.js'].source()).toEqual(expect.stringContaining('// This is a comment from test2.js')); - expect(compilation.assets['extracted-comments.js'].source()).toEqual(expect.stringContaining('/* This is a comment from test3.js */')); - expect(compilation.assets['extracted-comments.js'].source()).toEqual(expect.stringContaining('// This is another comment from test3.js')); - expect(compilation.assets['extracted-comments.js'].source()).not.toEqual(expect.stringContaining('function')); - }); - }); - }); - }); + for (const file in stats.compilation.assets) { + if (Object.prototype.hasOwnProperty.call(stats.compilation.assets, file)) { + expect(stats.compilation.assets[file].source()).toMatchSnapshot(file); + } + } }); }); }); diff --git a/test/fixtures/comments.js b/test/fixtures/comments.js new file mode 100644 index 00000000..3998a189 --- /dev/null +++ b/test/fixtures/comments.js @@ -0,0 +1,29 @@ +import('./nested/comments.js'); + +/*! Legal Comment */ + +/** + * @preserve Copyright 2009 SomeThirdParty. + * Here is the full license text and copyright + * notice for this file. Note that the notice can span several + * lines and is only terminated by the closing star and slash: + */ + +/** + * Utility functions for the foo package. + * @license Apache-2.0 + */ + +/*! Legal Foo */ + +// Foo + +/* + Foo Bar + */ + +/* +* Foo +*/ + +module.exports = Math.random(); diff --git a/test/fixtures/nested/comments.js b/test/fixtures/nested/comments.js new file mode 100644 index 00000000..daf02719 --- /dev/null +++ b/test/fixtures/nested/comments.js @@ -0,0 +1,27 @@ +/*! Legal Comment */ + +/** + * @preserve Copyright 2009 SomeThirdParty. + * Here is the full license text and copyright + * notice for this file. Note that the notice can span several + * lines and is only terminated by the closing star and slash: + */ + +/** + * Utility functions for the foo package. + * @license Apache-2.0 + */ + +/*! Legal Foo */ + +// Foo + +/* + Foo Bar + */ + +/* +* Foo +*/ + +module.exports = Math.random(); From e67c3291ac223abe7f62c78181dbccd7de746805 Mon Sep 17 00:00:00 2001 From: evilebottnawi Date: Tue, 31 Jul 2018 18:52:33 +0300 Subject: [PATCH 03/17] refactor: ignore some lines to coverage --- src/index.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/index.js b/src/index.js index dab8c029..fd212f40 100644 --- a/src/index.js +++ b/src/index.js @@ -321,6 +321,7 @@ class UglifyJsPlugin { }); }; + /* istanbul ignore if */ if (compiler.hooks) { const plugin = { name: 'UglifyJSPlugin' }; From 5229d3fbe401011839714712163c8e7c54315f56 Mon Sep 17 00:00:00 2001 From: evilebottnawi Date: Tue, 31 Jul 2018 19:23:11 +0300 Subject: [PATCH 04/17] tests: minify error --- src/uglify/Runner.js | 4 +- test/__snapshots__/minify-option.test.js.snap | 143 ++++++++++++++++++ test/minify-option.test.js | 33 ++++ 3 files changed, 178 insertions(+), 2 deletions(-) diff --git a/src/uglify/Runner.js b/src/uglify/Runner.js index c9c22667..e43549de 100644 --- a/src/uglify/Runner.js +++ b/src/uglify/Runner.js @@ -33,8 +33,8 @@ export default class Runner { this.boundWorkers = (options, cb) => { try { cb(null, minify(options)); - } catch (errors) { - cb(errors); + } catch (error) { + cb(error); } }; } diff --git a/test/__snapshots__/minify-option.test.js.snap b/test/__snapshots__/minify-option.test.js.snap index 790f54a5..aa9799aa 100644 --- a/test/__snapshots__/minify-option.test.js.snap +++ b/test/__snapshots__/minify-option.test.js.snap @@ -244,3 +244,146 @@ exports[`when applied with \`minify\` option matches snapshot for \`uglify-js\` exports[`when applied with \`minify\` option matches snapshot for \`uglify-js\` minifier: manifest.js 1`] = `"!function(i){var p=window.webpackJsonp;window.webpackJsonp=function(r,n,e){for(var o,t,u,c=0,f=[];c { } }); }); + + it('matches snapshot for errors in `minify` option', () => { + const compiler = createCompiler({ + entry: `${__dirname}/fixtures/minify/es6.js`, + output: { + path: `${__dirname}/dist-terser`, + filename: '[name].js', + chunkFilename: '[id].[name].js', + }, + }); + + new UglifyJsPlugin({ + parallel: true, + minify() { + throw Error('Error'); + }, + }).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'); + + for (const file in stats.compilation.assets) { + if (Object.prototype.hasOwnProperty.call(stats.compilation.assets, file)) { + expect(stats.compilation.assets[file].source()).toMatchSnapshot(file); + } + } + }); + }); }); From 10bbb35faad410cccbde45cf160960dbe0acd9cb Mon Sep 17 00:00:00 2001 From: evilebottnawi Date: Tue, 31 Jul 2018 19:26:07 +0300 Subject: [PATCH 05/17] refactor: `RequestShortener` --- src/index.js | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/index.js b/src/index.js index fd212f40..5a2089b5 100644 --- a/src/index.js +++ b/src/index.js @@ -118,8 +118,6 @@ class UglifyJsPlugin { } apply(compiler) { - const requestShortener = new RequestShortener(compiler.context); - const buildModuleFn = (moduleArg) => { // to get detailed location info about errors moduleArg.useSourceMap = true; @@ -209,7 +207,7 @@ class UglifyJsPlugin { error, file, UglifyJsPlugin.buildSourceMap(inputSourceMap), - requestShortener, + new RequestShortener(compiler.context), ), ); } @@ -240,7 +238,7 @@ class UglifyJsPlugin { error, file, sourceMap, - requestShortener, + new RequestShortener(compiler.context), ), ); @@ -305,7 +303,7 @@ class UglifyJsPlugin { file, sourceMap, this.options.warningsFilter, - requestShortener, + new RequestShortener(compiler.context), ); if (builtWarning) { From bfdfa36c87376da7a07d94ec687eb6c8d4ef0853 Mon Sep 17 00:00:00 2001 From: evilebottnawi Date: Tue, 31 Jul 2018 19:55:13 +0300 Subject: [PATCH 06/17] refactor: `sourceMap` tests --- .../sourceMap-option.test.js.snap | 402 +----------------- test/sourceMap-option.test.js | 316 +++----------- 2 files changed, 92 insertions(+), 626 deletions(-) diff --git a/test/__snapshots__/sourceMap-option.test.js.snap b/test/__snapshots__/sourceMap-option.test.js.snap index ad1cdd6f..1f174913 100644 --- a/test/__snapshots__/sourceMap-option.test.js.snap +++ b/test/__snapshots__/sourceMap-option.test.js.snap @@ -1,401 +1,43 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`when options.sourceMap true and options.parallel true compilation handler when called optimize-chunk-assets handler only calls callback once: errors 1`] = `Array []`; +exports[`when options.sourceMap matches snapshot for a single \`false\` value (\`devtool\` is \`false\`): entry.e16453731320636f520c.js 1`] = `"webpackJsonp([0],[function(o,n){o.exports=function(){console.log(7)}}],[0]);"`; -exports[`when options.sourceMap true and options.parallel true compilation handler when called optimize-chunk-assets handler only calls callback once: warnings 1`] = ` -Array [ - [Error: test4.js contains invalid source map], -] -`; - -exports[`when options.sourceMap true and options.parallel true matches snapshot: asset main.0c220ec66316af2c1b24.js 1`] = `"webpackJsonp([0],[function(o,n){o.exports=function(){console.log(7)}}],[0]);"`; - -exports[`when options.sourceMap true and options.parallel true matches snapshot: asset manifest.d6857f782c13a99b5917.js 1`] = `"!function(r){var n=window.webpackJsonp;window.webpackJsonp=function(e,u,c){for(var f,i,p,a=0,l=[];a { - const assets = { - 'test.js': { - source: () => 'function test(foo) { foo = 1; }', - }, - 'test1.js': { - source: () => 'function test1(foo) { foo = 1; }', - }, - 'test2.js': { - source: () => 'function test2(foo) { foo = 1; }', - }, - 'test3.js': { - source: () => 'function test3(foo) { foo = 1; }', - }, - 'test4.js': { - sourceAndMap: () => { - return { - source: 'function foo(x) { if (x) { return bar(); not_called1(); } }', - map: null, - }; + it('matches snapshot for a single `false` value (`devtool` is `source-map`)', () => { + const compiler = createCompiler({ + entry: { + entry: `${__dirname}/fixtures/entry.js`, }, - }, - }; - - describe('true', () => { - let eventBindings; - let eventBinding; - - beforeEach(() => { - const pluginEnvironment = new PluginEnvironment(); - const compilerEnv = pluginEnvironment.getEnvironmentStub(); - compilerEnv.context = ''; - compilerEnv.devtool = 'source-map'; - - const plugin = new UglifyJsPlugin({ - sourceMap: true, - }); - plugin.apply(compilerEnv); - eventBindings = pluginEnvironment.getEventBindings(); - }); - - it('binds one event handler', () => { - expect(eventBindings.length).toBe(1); + devtool: 'source-map', }); - describe('compilation handler', () => { - beforeEach(() => { - [eventBinding] = eventBindings; - }); - - it('binds to compilation event', () => { - expect(eventBinding.name).toBe('compilation'); - }); - - describe('when called', () => { - let chunkPluginEnvironment; - let compilationEventBindings; - let compilationEventBinding; - let compilation; - let callback; - - beforeEach(() => { - chunkPluginEnvironment = new PluginEnvironment(); - compilation = chunkPluginEnvironment.getEnvironmentStub(); - compilation.assets = Object.assign({}, assets); - compilation.warnings = []; - compilation.errors = []; - - eventBinding.handler(compilation); - compilationEventBindings = chunkPluginEnvironment.getEventBindings(); - }); - - it('binds two event handler', () => { - expect(compilationEventBindings[0].name).toBe('build-module'); - expect(compilationEventBindings[1].name).toBe('optimize-chunk-assets'); - }); + new UglifyJsPlugin({ sourceMap: false }).apply(compiler); - describe('build-module handler', () => { - beforeEach(() => { - [compilationEventBinding] = compilationEventBindings; - }); + return compile(compiler).then((stats) => { + const errors = stats.compilation.errors.map(cleanErrorStack); + const warnings = stats.compilation.warnings.map(cleanErrorStack); - it('binds to build-module event', () => { - expect(compilationEventBinding.name).toEqual('build-module'); - }); + expect(errors).toMatchSnapshot('errors'); + expect(warnings).toMatchSnapshot('warnings'); - it('build-module handler', (done) => { - const moduleArgs = { useSourceMap: false }; - const mockBuildModuleEvent = jest.fn(() => compilationEventBinding.handler(moduleArgs)); - - mockBuildModuleEvent(); - - expect(mockBuildModuleEvent.mock.calls.length).toBe(1); - expect(moduleArgs.useSourceMap).toBe(true); - done(); - }); - }); - - describe('optimize-chunk-assets handler', () => { - beforeEach(() => { - [, compilationEventBinding] = compilationEventBindings; - }); - - it('binds to optimize-chunk-assets event', () => { - expect(compilationEventBinding.name).toEqual('optimize-chunk-assets'); - }); - - it('only calls callback once', (done) => { - callback = jest.fn(); - compilationEventBinding.handler([{ - files: ['test.js', 'test1.js', 'test2.js', 'test3.js', 'test4.js'], - }], () => { - expect(compilation.warnings).toMatchSnapshot('warnings'); - expect(compilation.errors).toMatchSnapshot('errors'); - callback(); - expect(callback.mock.calls.length).toBe(1); - done(); - }); - }); - }); - }); + for (const file in stats.compilation.assets) { + if (Object.prototype.hasOwnProperty.call(stats.compilation.assets, file)) { + expect(stats.compilation.assets[file].source()).toMatchSnapshot(file); + } + } }); + }); - it('matches snapshot', () => { - const compiler = createCompiler(); - new UglifyJsPlugin({ sourceMap: true }).apply(compiler); - - return compile(compiler).then((stats) => { - const errors = stats.compilation.errors.map(cleanErrorStack); - const warnings = stats.compilation.warnings.map(cleanErrorStack); + it('matches snapshot for a single `false` value (`devtool` is `false`)', () => { + const compiler = createCompiler({ + entry: { + entry: `${__dirname}/fixtures/entry.js`, + }, + devtool: false, + }); - expect(errors).toMatchSnapshot('errors'); - expect(warnings).toMatchSnapshot('warnings'); + new UglifyJsPlugin({ sourceMap: false }).apply(compiler); - for (const file in stats.compilation.assets) { - if (Object.prototype.hasOwnProperty.call(stats.compilation.assets, file)) { - const asset = stats.compilation.assets[file].sourceAndMap(); + return compile(compiler).then((stats) => { + const errors = stats.compilation.errors.map(cleanErrorStack); + const warnings = stats.compilation.warnings.map(cleanErrorStack); - asset.map.sources = []; + expect(errors).toMatchSnapshot('errors'); + expect(warnings).toMatchSnapshot('warnings'); - expect(asset.source).toMatchSnapshot(`asset ${file}`); - expect(asset.map).toMatchSnapshot(`source map ${file}`); - } + for (const file in stats.compilation.assets) { + if (Object.prototype.hasOwnProperty.call(stats.compilation.assets, file)) { + expect(stats.compilation.assets[file].source()).toMatchSnapshot(file); } - }); + } }); }); - describe('true and options.parallel true', () => { - let eventBindings; - let eventBinding; - - beforeEach(() => { - const pluginEnvironment = new PluginEnvironment(); - const compilerEnv = pluginEnvironment.getEnvironmentStub(); - compilerEnv.context = ''; - - const plugin = new UglifyJsPlugin({ - parallel: true, - sourceMap: true, - }); - plugin.apply(compilerEnv); - eventBindings = pluginEnvironment.getEventBindings(); - }); - - it('binds one event handler', () => { - expect(eventBindings.length).toBe(1); + it('matches snapshot for a single `true` value (`devtool` is `source-map`)', () => { + const compiler = createCompiler({ + entry: { + entry: `${__dirname}/fixtures/entry.js`, + }, + devtool: 'source-map', }); - describe('compilation handler', () => { - beforeEach(() => { - [eventBinding] = eventBindings; - }); - - it('binds to compilation event', () => { - expect(eventBinding.name).toBe('compilation'); - }); - - describe('when called', () => { - let chunkPluginEnvironment; - let compilationEventBindings; - let compilationEventBinding; - let compilation; - let callback; - - beforeEach(() => { - chunkPluginEnvironment = new PluginEnvironment(); - compilation = chunkPluginEnvironment.getEnvironmentStub(); - compilation.assets = Object.assign({}, assets); - compilation.warnings = []; - compilation.errors = []; - - eventBinding.handler(compilation); - compilationEventBindings = chunkPluginEnvironment.getEventBindings(); - }); - - it('binds two event handler', () => { - expect(compilationEventBindings[0].name).toBe('build-module'); - expect(compilationEventBindings[1].name).toBe('optimize-chunk-assets'); - }); + new UglifyJsPlugin({ sourceMap: true }).apply(compiler); - describe('build-module handler', () => { - beforeEach(() => { - [compilationEventBinding] = compilationEventBindings; - }); + return compile(compiler).then((stats) => { + const errors = stats.compilation.errors.map(cleanErrorStack); + const warnings = stats.compilation.warnings.map(cleanErrorStack); - it('binds to build-module event', () => { - expect(compilationEventBinding.name).toEqual('build-module'); - }); + expect(errors).toMatchSnapshot('errors'); + expect(warnings).toMatchSnapshot('warnings'); - it('build-module handler', (done) => { - const moduleArgs = { useSourceMap: false }; - const mockBuildModuleEvent = jest.fn(() => compilationEventBinding.handler(moduleArgs)); - - mockBuildModuleEvent(); - - expect(mockBuildModuleEvent.mock.calls.length).toBe(1); - expect(moduleArgs.useSourceMap).toBe(true); - done(); - }); - }); - - describe('optimize-chunk-assets handler', () => { - beforeEach(() => { - [, compilationEventBinding] = compilationEventBindings; - }); - - it('binds to optimize-chunk-assets event', () => { - expect(compilationEventBinding.name).toEqual('optimize-chunk-assets'); - }); - - it('only calls callback once', (done) => { - callback = jest.fn(); - compilationEventBinding.handler([{ - files: ['test.js', 'test1.js', 'test2.js', 'test3.js', 'test4.js'], - }], () => { - expect(compilation.warnings).toMatchSnapshot('warnings'); - expect(compilation.errors).toMatchSnapshot('errors'); - callback(); - expect(callback.mock.calls.length).toBe(1); - done(); - }); - }); - }); - }); + for (const file in stats.compilation.assets) { + if (Object.prototype.hasOwnProperty.call(stats.compilation.assets, file)) { + expect(stats.compilation.assets[file].source()).toMatchSnapshot(file); + } + } }); + }); - it('matches snapshot', () => { - const compiler = createCompiler(); - new UglifyJsPlugin({ parallel: true, sourceMap: true }).apply(compiler); - - return compile(compiler).then((stats) => { - const errors = stats.compilation.errors.map(cleanErrorStack); - const warnings = stats.compilation.warnings.map(cleanErrorStack); + it('matches snapshot for a single `true` value (`devtool` is `false`)', () => { + const compiler = createCompiler({ + entry: { + entry: `${__dirname}/fixtures/entry.js`, + }, + devtool: false, + }); - expect(errors).toMatchSnapshot('errors'); - expect(warnings).toMatchSnapshot('warnings'); + new UglifyJsPlugin({ sourceMap: true }).apply(compiler); - for (const file in stats.compilation.assets) { - if (Object.prototype.hasOwnProperty.call(stats.compilation.assets, file)) { - const asset = stats.compilation.assets[file].sourceAndMap(); + return compile(compiler).then((stats) => { + const errors = stats.compilation.errors.map(cleanErrorStack); + const warnings = stats.compilation.warnings.map(cleanErrorStack); - asset.map.sources = []; + expect(errors).toMatchSnapshot('errors'); + expect(warnings).toMatchSnapshot('warnings'); - expect(asset.source).toMatchSnapshot(`asset ${file}`); - expect(asset.map).toMatchSnapshot(`source map ${file}`); - } + for (const file in stats.compilation.assets) { + if (Object.prototype.hasOwnProperty.call(stats.compilation.assets, file)) { + expect(stats.compilation.assets[file].source()).toMatchSnapshot(file); } - }); + } }); }); }); From 89cfeef256668af353dc4654bfbfa044eb70d2dd Mon Sep 17 00:00:00 2001 From: evilebottnawi Date: Tue, 31 Jul 2018 20:00:21 +0300 Subject: [PATCH 07/17] refactor: same order for tests --- test/extractComments-option.test.js | 8 ++-- test/uglifyOptions-option.test.js | 64 ++++++++++++++--------------- test/warningsFilter-option.test.js | 8 ++-- 3 files changed, 40 insertions(+), 40 deletions(-) diff --git a/test/extractComments-option.test.js b/test/extractComments-option.test.js index 34dc157d..cf81d979 100644 --- a/test/extractComments-option.test.js +++ b/test/extractComments-option.test.js @@ -34,8 +34,8 @@ describe('when applied with `extractComments` option', () => { }); }); - it('matches snapshot for a `true` value', () => { - new UglifyJsPlugin({ extractComments: true }).apply(compiler); + it('matches snapshot for a `false` value', () => { + new UglifyJsPlugin({ extractComments: false }).apply(compiler); return compile(compiler).then((stats) => { const errors = stats.compilation.errors.map(cleanErrorStack); @@ -52,8 +52,8 @@ describe('when applied with `extractComments` option', () => { }); }); - it('matches snapshot for a `false` value', () => { - new UglifyJsPlugin({ extractComments: false }).apply(compiler); + it('matches snapshot for a `true` value', () => { + new UglifyJsPlugin({ extractComments: true }).apply(compiler); return compile(compiler).then((stats) => { const errors = stats.compilation.errors.map(cleanErrorStack); diff --git a/test/uglifyOptions-option.test.js b/test/uglifyOptions-option.test.js index 15320827..12a9213d 100644 --- a/test/uglifyOptions-option.test.js +++ b/test/uglifyOptions-option.test.js @@ -129,14 +129,14 @@ describe('when applied with uglifyOptions options', () => { }); }); - it('matches snapshot for `warnings` option (boolean `true` value)', () => { + it('matches snapshot for `warnings` option (boolean `false` value)', () => { const compiler = createCompiler({ entry: `${__dirname}/fixtures/unreachable-code.js`, }); new UglifyJsPlugin({ uglifyOptions: { - warnings: true, + warnings: false, }, }).apply(compiler); @@ -155,14 +155,14 @@ describe('when applied with uglifyOptions options', () => { }); }); - it('matches snapshot for `warnings` option (boolean `false` value)', () => { + it('matches snapshot for `warnings` option (boolean `true` value)', () => { const compiler = createCompiler({ entry: `${__dirname}/fixtures/unreachable-code.js`, }); new UglifyJsPlugin({ uglifyOptions: { - warnings: false, + warnings: true, }, }).apply(compiler); @@ -207,12 +207,12 @@ describe('when applied with uglifyOptions options', () => { }); }); - it('matches snapshot for `compress` option (boolean `true` value)', () => { + it('matches snapshot for `compress` option (boolean `false` value)', () => { const compiler = createCompiler(); new UglifyJsPlugin({ uglifyOptions: { - compress: true, + compress: false, }, }).apply(compiler); @@ -231,12 +231,12 @@ describe('when applied with uglifyOptions options', () => { }); }); - it('matches snapshot for `compress` option (boolean `false` value)', () => { + it('matches snapshot for `compress` option (boolean `true` value)', () => { const compiler = createCompiler(); new UglifyJsPlugin({ uglifyOptions: { - compress: false, + compress: true, }, }).apply(compiler); @@ -281,12 +281,12 @@ describe('when applied with uglifyOptions options', () => { }); }); - it('matches snapshot for `mangle` option (boolean `true` value)', () => { + it('matches snapshot for `mangle` option (boolean `false` value)', () => { const compiler = createCompiler(); new UglifyJsPlugin({ uglifyOptions: { - mangle: true, + mangle: false, }, }).apply(compiler); @@ -305,12 +305,12 @@ describe('when applied with uglifyOptions options', () => { }); }); - it('matches snapshot for `mangle` option (boolean `false` value)', () => { + it('matches snapshot for `mangle` option (boolean `true` value)', () => { const compiler = createCompiler(); new UglifyJsPlugin({ uglifyOptions: { - mangle: false, + mangle: true, }, }).apply(compiler); @@ -407,12 +407,12 @@ describe('when applied with uglifyOptions options', () => { }); }); - it('matches snapshot for `toplevel` option (boolean `true` value)', () => { + it('matches snapshot for `toplevel` option (boolean `false` value)', () => { const compiler = createCompiler(); new UglifyJsPlugin({ uglifyOptions: { - toplevel: true, + toplevel: false, }, }).apply(compiler); @@ -431,12 +431,12 @@ describe('when applied with uglifyOptions options', () => { }); }); - it('matches snapshot for `toplevel` option (boolean `false` value)', () => { + it('matches snapshot for `toplevel` option (boolean `true` value)', () => { const compiler = createCompiler(); new UglifyJsPlugin({ uglifyOptions: { - toplevel: false, + toplevel: true, }, }).apply(compiler); @@ -479,12 +479,12 @@ describe('when applied with uglifyOptions options', () => { }); }); - it('matches snapshot for `ie8` option (boolean `true` value)', () => { + it('matches snapshot for `ie8` option (boolean `false` value)', () => { const compiler = createCompiler(); new UglifyJsPlugin({ uglifyOptions: { - ie8: true, + ie8: false, }, }).apply(compiler); @@ -503,12 +503,12 @@ describe('when applied with uglifyOptions options', () => { }); }); - it('matches snapshot for `ie8` option (boolean `false` value)', () => { + it('matches snapshot for `ie8` option (boolean `true` value)', () => { const compiler = createCompiler(); new UglifyJsPlugin({ uglifyOptions: { - ie8: false, + ie8: true, }, }).apply(compiler); @@ -527,12 +527,12 @@ describe('when applied with uglifyOptions options', () => { }); }); - it('matches snapshot for `keep_classnames` option (boolean `true` value)', () => { + it('matches snapshot for `keep_classnames` option (boolean `false` value)', () => { const compiler = createCompiler(); new UglifyJsPlugin({ uglifyOptions: { - keep_classnames: true, + keep_classnames: false, }, }).apply(compiler); @@ -551,12 +551,12 @@ describe('when applied with uglifyOptions options', () => { }); }); - it('matches snapshot for `keep_classnames` option (boolean `false` value)', () => { + it('matches snapshot for `keep_classnames` option (boolean `true` value)', () => { const compiler = createCompiler(); new UglifyJsPlugin({ uglifyOptions: { - keep_classnames: false, + keep_classnames: true, }, }).apply(compiler); @@ -575,12 +575,12 @@ describe('when applied with uglifyOptions options', () => { }); }); - it('matches snapshot for `keep_fnames` option (boolean `true` value)', () => { + it('matches snapshot for `keep_fnames` option (boolean `false` value)', () => { const compiler = createCompiler(); new UglifyJsPlugin({ uglifyOptions: { - keep_fnames: true, + keep_fnames: false, }, }).apply(compiler); @@ -599,12 +599,12 @@ describe('when applied with uglifyOptions options', () => { }); }); - it('matches snapshot for `keep_fnames` option (boolean `false` value)', () => { + it('matches snapshot for `keep_fnames` option (boolean `true` value)', () => { const compiler = createCompiler(); new UglifyJsPlugin({ uglifyOptions: { - keep_fnames: false, + keep_fnames: true, }, }).apply(compiler); @@ -623,12 +623,12 @@ describe('when applied with uglifyOptions options', () => { }); }); - it('matches snapshot for `safari10` option (boolean `true` value)', () => { + it('matches snapshot for `safari10` option (boolean `false` value)', () => { const compiler = createCompiler(); new UglifyJsPlugin({ uglifyOptions: { - safari10: true, + safari10: false, }, }).apply(compiler); @@ -647,12 +647,12 @@ describe('when applied with uglifyOptions options', () => { }); }); - it('matches snapshot for `safari10` option (boolean `false` value)', () => { + it('matches snapshot for `safari10` option (boolean `true` value)', () => { const compiler = createCompiler(); new UglifyJsPlugin({ uglifyOptions: { - safari10: false, + safari10: true, }, }).apply(compiler); diff --git a/test/warningsFilter-option.test.js b/test/warningsFilter-option.test.js index 55145589..12b6c2ba 100644 --- a/test/warningsFilter-option.test.js +++ b/test/warningsFilter-option.test.js @@ -17,7 +17,7 @@ describe('when applied with `warningsFilter` option', () => { }); }); - it('matches snapshot for a `function` value and `sourceMap` is `true`', () => { + it('matches snapshot for a `function` value and `sourceMap` is `false`', () => { new UglifyJsPlugin({ warningsFilter(source) { if (/unreachable-code-2\.js/.test(source)) { @@ -29,7 +29,7 @@ describe('when applied with `warningsFilter` option', () => { uglifyOptions: { warnings: true, }, - sourceMap: true, + sourceMap: false, }).apply(compiler); @@ -48,7 +48,7 @@ describe('when applied with `warningsFilter` option', () => { }); }); - it('matches snapshot for a `function` value and `sourceMap` is `false`', () => { + it('matches snapshot for a `function` value and `sourceMap` is `true`', () => { new UglifyJsPlugin({ warningsFilter(source) { if (/unreachable-code-2\.js/.test(source)) { @@ -60,7 +60,7 @@ describe('when applied with `warningsFilter` option', () => { uglifyOptions: { warnings: true, }, - sourceMap: false, + sourceMap: true, }).apply(compiler); From 1747a467d9d682525709904b74dda4845112d74c Mon Sep 17 00:00:00 2001 From: evilebottnawi Date: Tue, 31 Jul 2018 20:10:44 +0300 Subject: [PATCH 08/17] refactor: move `validation` test to own file --- test/UglifyJsPlugin.test.js | 174 ----------------- .../__snapshots__/UglifyJsPlugin.test.js.snap | 90 --------- test/validation.test.js | 176 ++++++++++++++++++ 3 files changed, 176 insertions(+), 264 deletions(-) create mode 100644 test/validation.test.js diff --git a/test/UglifyJsPlugin.test.js b/test/UglifyJsPlugin.test.js index 27ec597c..793bd3b2 100644 --- a/test/UglifyJsPlugin.test.js +++ b/test/UglifyJsPlugin.test.js @@ -185,180 +185,6 @@ describe('UglifyJsPlugin', () => { }); }); - it('should handle validation errors', () => { - /* eslint-disable no-new */ - expect(() => { - new UglifyJsPlugin({ test: /foo/ }); - }).not.toThrow('Validation Error'); - - expect(() => { - new UglifyJsPlugin({ test: [/foo/] }); - }).not.toThrow('Validation Error'); - - expect(() => { - new UglifyJsPlugin({ include: /foo/ }); - }).not.toThrow('Validation Error'); - - expect(() => { - new UglifyJsPlugin({ include: [/foo/] }); - }).not.toThrow('Validation Error'); - - expect(() => { - new UglifyJsPlugin({ exclude: /foo/ }); - }).not.toThrow('Validation Error'); - - expect(() => { - new UglifyJsPlugin({ exclude: [/foo/] }); - }).not.toThrow('Validation Error'); - - expect(() => { - new UglifyJsPlugin({ doesntExist: true }); - }).toThrowErrorMatchingSnapshot(); - - expect(() => { - new UglifyJsPlugin({ cache: true }); - }).not.toThrow('Validation Error'); - - expect(() => { - new UglifyJsPlugin({ cache: false }); - }).not.toThrow('Validation Error'); - - expect(() => { - new UglifyJsPlugin({ cache: 'path/to/cache/directory' }); - }).not.toThrow('Validation Error'); - - expect(() => { - new UglifyJsPlugin({ cache: {} }); - }).toThrowErrorMatchingSnapshot(); - - expect(() => { - new UglifyJsPlugin({ cacheKeys() {} }); - }).not.toThrow('Validation Error'); - - expect(() => { - new UglifyJsPlugin({ parallel: true }); - }).not.toThrow('Validation Error'); - - expect(() => { - new UglifyJsPlugin({ parallel: false }); - }).not.toThrow('Validation Error'); - - expect(() => { - new UglifyJsPlugin({ parallel: 2 }); - }).not.toThrow('Validation Error'); - - expect(() => { - new UglifyJsPlugin({ parallel: '2' }); - }).toThrowErrorMatchingSnapshot(); - - expect(() => { - new UglifyJsPlugin({ parallel: {} }); - }).toThrowErrorMatchingSnapshot(); - - expect(() => { - new UglifyJsPlugin({ sourceMap: true }); - }).not.toThrow('Validation Error'); - - expect(() => { - new UglifyJsPlugin({ sourceMap: false }); - }).not.toThrow('Validation Error'); - - expect(() => { - new UglifyJsPlugin({ sourceMap: 'true' }); - }).toThrowErrorMatchingSnapshot(); - - expect(() => { - new UglifyJsPlugin({ minify() {} }); - }).not.toThrow('Validation Error'); - - expect(() => { - new UglifyJsPlugin({ uglifyOptions: null }); - }).toThrowErrorMatchingSnapshot(); - - expect(() => { - new UglifyJsPlugin({ uglifyOptions: {} }); - }).not.toThrow('Validation Error'); - - expect(() => { - new UglifyJsPlugin({ - uglifyOptions: { - ecma: 5, - warnings: false, - parse: {}, - compress: true, - mangle: { inline: false }, - output: { comments: /^\**!|@preserve|@license|@cc_on/ }, - toplevel: false, - nameCache: {}, - ie8: false, - keep_classnames: false, - keep_fnames: false, - safari10: false, - }, - }); - }).not.toThrow('Validation Error'); - - expect(() => { - new UglifyJsPlugin({ uglifyOptions: { ie8: false } }); - }).not.toThrow('Validation Error'); - - expect(() => { - new UglifyJsPlugin({ uglifyOptions: { ie8: true } }); - }).not.toThrow('Validation Error'); - - expect(() => { - new UglifyJsPlugin({ uglifyOptions: { ie8: 'false' } }); - }).toThrowErrorMatchingSnapshot(); - - expect(() => { - new UglifyJsPlugin({ uglifyOptions: { emca: 5 } }); - }).not.toThrow(); - - expect(() => { - new UglifyJsPlugin({ uglifyOptions: { emca: 8 } }); - }).not.toThrow(); - - expect(() => { - new UglifyJsPlugin({ uglifyOptions: { ecma: 7.5 } }); - }).toThrowErrorMatchingSnapshot(); - - expect(() => { - new UglifyJsPlugin({ uglifyOptions: { ecma: true } }); - }).toThrowErrorMatchingSnapshot(); - - expect(() => { - new UglifyJsPlugin({ uglifyOptions: { ecma: '5' } }); - }).toThrowErrorMatchingSnapshot(); - - expect(() => { - new UglifyJsPlugin({ uglifyOptions: { ecma: 3 } }); - }).toThrowErrorMatchingSnapshot(); - - expect(() => { - new UglifyJsPlugin({ uglifyOptions: { ecma: 10 } }); - }).toThrowErrorMatchingSnapshot(); - - expect(() => { - new UglifyJsPlugin({ extractComments: true }); - }).not.toThrow('Validation Error'); - - expect(() => { - new UglifyJsPlugin({ extractComments: false }); - }).not.toThrow('Validation Error'); - - expect(() => { - new UglifyJsPlugin({ extractComments: /comment/ }); - }).not.toThrow('Validation Error'); - - expect(() => { - new UglifyJsPlugin({ extractComments() {} }); - }).not.toThrow('Validation Error'); - - expect(() => { - new UglifyJsPlugin({ warningsFilter() {} }); - }).not.toThrow('Validation Error'); - }); - it('should contains error when uglify has unknown option', () => { const compiler = createCompiler(); new UglifyJsPlugin({ diff --git a/test/__snapshots__/UglifyJsPlugin.test.js.snap b/test/__snapshots__/UglifyJsPlugin.test.js.snap index 0acf5757..76635886 100644 --- a/test/__snapshots__/UglifyJsPlugin.test.js.snap +++ b/test/__snapshots__/UglifyJsPlugin.test.js.snap @@ -135,96 +135,6 @@ exports[`UglifyJsPlugin should contains error when uglify has unknown option: ma exports[`UglifyJsPlugin should contains error when uglify has unknown option: warnings 1`] = `Array []`; -exports[`UglifyJsPlugin should handle validation errors 1`] = ` -"UglifyJs Plugin Invalid Options - -options['doesntExist'] is an invalid additional property -" -`; - -exports[`UglifyJsPlugin should handle validation errors 2`] = ` -"UglifyJs Plugin Invalid Options - -options.cache should be boolean -options.cache should be string -options.cache should match exactly one schema in oneOf -" -`; - -exports[`UglifyJsPlugin should handle validation errors 3`] = ` -"UglifyJs Plugin Invalid Options - -options.parallel should be boolean -options.parallel should be integer -options.parallel should match exactly one schema in oneOf -" -`; - -exports[`UglifyJsPlugin should handle validation errors 4`] = ` -"UglifyJs Plugin Invalid Options - -options.parallel should be boolean -options.parallel should be integer -options.parallel should match exactly one schema in oneOf -" -`; - -exports[`UglifyJsPlugin should handle validation errors 5`] = ` -"UglifyJs Plugin Invalid Options - -options.sourceMap should be boolean -" -`; - -exports[`UglifyJsPlugin should handle validation errors 6`] = ` -"UglifyJs Plugin Invalid Options - -options.uglifyOptions should be object -" -`; - -exports[`UglifyJsPlugin should handle validation errors 7`] = ` -"UglifyJs Plugin Invalid Options - -options.uglifyOptions.ie8 should be boolean -" -`; - -exports[`UglifyJsPlugin should handle validation errors 8`] = ` -"UglifyJs Plugin Invalid Options - -options.uglifyOptions.ecma should be integer -" -`; - -exports[`UglifyJsPlugin should handle validation errors 9`] = ` -"UglifyJs Plugin Invalid Options - -options.uglifyOptions.ecma should be integer -" -`; - -exports[`UglifyJsPlugin should handle validation errors 10`] = ` -"UglifyJs Plugin Invalid Options - -options.uglifyOptions.ecma should be integer -" -`; - -exports[`UglifyJsPlugin should handle validation errors 11`] = ` -"UglifyJs Plugin Invalid Options - -options.uglifyOptions.ecma should be >= 5 -" -`; - -exports[`UglifyJsPlugin should handle validation errors 12`] = ` -"UglifyJs Plugin Invalid Options - -options.uglifyOptions.ecma should be <= 8 -" -`; - exports[`UglifyJsPlugin when applied with no options matches snapshot: errors 1`] = `Array []`; exports[`UglifyJsPlugin when applied with no options matches snapshot: main.0c220ec66316af2c1b24.js 1`] = `"webpackJsonp([0],[function(o,n){o.exports=function(){console.log(7)}}],[0]);"`; diff --git a/test/validation.test.js b/test/validation.test.js new file mode 100644 index 00000000..7d118308 --- /dev/null +++ b/test/validation.test.js @@ -0,0 +1,176 @@ +import UglifyJsPlugin from '../src'; + +it('validation', () => { + /* eslint-disable no-new */ + expect(() => { + new UglifyJsPlugin({ test: /foo/ }); + }).not.toThrow('Validation Error'); + + expect(() => { + new UglifyJsPlugin({ test: [/foo/] }); + }).not.toThrow('Validation Error'); + + expect(() => { + new UglifyJsPlugin({ include: /foo/ }); + }).not.toThrow('Validation Error'); + + expect(() => { + new UglifyJsPlugin({ include: [/foo/] }); + }).not.toThrow('Validation Error'); + + expect(() => { + new UglifyJsPlugin({ exclude: /foo/ }); + }).not.toThrow('Validation Error'); + + expect(() => { + new UglifyJsPlugin({ exclude: [/foo/] }); + }).not.toThrow('Validation Error'); + + expect(() => { + new UglifyJsPlugin({ doesntExist: true }); + }).toThrowErrorMatchingSnapshot(); + + expect(() => { + new UglifyJsPlugin({ cache: true }); + }).not.toThrow('Validation Error'); + + expect(() => { + new UglifyJsPlugin({ cache: false }); + }).not.toThrow('Validation Error'); + + expect(() => { + new UglifyJsPlugin({ cache: 'path/to/cache/directory' }); + }).not.toThrow('Validation Error'); + + expect(() => { + new UglifyJsPlugin({ cache: {} }); + }).toThrowErrorMatchingSnapshot(); + + expect(() => { + new UglifyJsPlugin({ cacheKeys() {} }); + }).not.toThrow('Validation Error'); + + expect(() => { + new UglifyJsPlugin({ parallel: true }); + }).not.toThrow('Validation Error'); + + expect(() => { + new UglifyJsPlugin({ parallel: false }); + }).not.toThrow('Validation Error'); + + expect(() => { + new UglifyJsPlugin({ parallel: 2 }); + }).not.toThrow('Validation Error'); + + expect(() => { + new UglifyJsPlugin({ parallel: '2' }); + }).toThrowErrorMatchingSnapshot(); + + expect(() => { + new UglifyJsPlugin({ parallel: {} }); + }).toThrowErrorMatchingSnapshot(); + + expect(() => { + new UglifyJsPlugin({ sourceMap: true }); + }).not.toThrow('Validation Error'); + + expect(() => { + new UglifyJsPlugin({ sourceMap: false }); + }).not.toThrow('Validation Error'); + + expect(() => { + new UglifyJsPlugin({ sourceMap: 'true' }); + }).toThrowErrorMatchingSnapshot(); + + expect(() => { + new UglifyJsPlugin({ minify() {} }); + }).not.toThrow('Validation Error'); + + expect(() => { + new UglifyJsPlugin({ uglifyOptions: null }); + }).toThrowErrorMatchingSnapshot(); + + expect(() => { + new UglifyJsPlugin({ uglifyOptions: {} }); + }).not.toThrow('Validation Error'); + + expect(() => { + new UglifyJsPlugin({ + uglifyOptions: { + ecma: 5, + warnings: false, + parse: {}, + compress: true, + mangle: { inline: false }, + output: { comments: /^\**!|@preserve|@license|@cc_on/ }, + toplevel: false, + nameCache: {}, + ie8: false, + keep_classnames: false, + keep_fnames: false, + safari10: false, + }, + }); + }).not.toThrow('Validation Error'); + + expect(() => { + new UglifyJsPlugin({ uglifyOptions: { ie8: false } }); + }).not.toThrow('Validation Error'); + + expect(() => { + new UglifyJsPlugin({ uglifyOptions: { ie8: true } }); + }).not.toThrow('Validation Error'); + + expect(() => { + new UglifyJsPlugin({ uglifyOptions: { ie8: 'false' } }); + }).toThrowErrorMatchingSnapshot(); + + expect(() => { + new UglifyJsPlugin({ uglifyOptions: { emca: 5 } }); + }).not.toThrow(); + + expect(() => { + new UglifyJsPlugin({ uglifyOptions: { emca: 8 } }); + }).not.toThrow(); + + expect(() => { + new UglifyJsPlugin({ uglifyOptions: { ecma: 7.5 } }); + }).toThrowErrorMatchingSnapshot(); + + expect(() => { + new UglifyJsPlugin({ uglifyOptions: { ecma: true } }); + }).toThrowErrorMatchingSnapshot(); + + expect(() => { + new UglifyJsPlugin({ uglifyOptions: { ecma: '5' } }); + }).toThrowErrorMatchingSnapshot(); + + expect(() => { + new UglifyJsPlugin({ uglifyOptions: { ecma: 3 } }); + }).toThrowErrorMatchingSnapshot(); + + expect(() => { + new UglifyJsPlugin({ uglifyOptions: { ecma: 10 } }); + }).toThrowErrorMatchingSnapshot(); + + expect(() => { + new UglifyJsPlugin({ extractComments: true }); + }).not.toThrow('Validation Error'); + + expect(() => { + new UglifyJsPlugin({ extractComments: false }); + }).not.toThrow('Validation Error'); + + expect(() => { + new UglifyJsPlugin({ extractComments: /comment/ }); + }).not.toThrow('Validation Error'); + + expect(() => { + new UglifyJsPlugin({ extractComments() {} }); + }).not.toThrow('Validation Error'); + + expect(() => { + new UglifyJsPlugin({ warningsFilter() {} }); + }).not.toThrow('Validation Error'); + /* eslint-enable no-new */ +}); From 8ed2c7810a05b18cc9df207c441c80cf123edb0e Mon Sep 17 00:00:00 2001 From: evilebottnawi Date: Tue, 31 Jul 2018 20:18:43 +0300 Subject: [PATCH 09/17] refactor: basic test --- src/index.js | 1 + test/UglifyJsPlugin.test.js | 192 +----------------- .../__snapshots__/UglifyJsPlugin.test.js.snap | 143 +------------ .../uglifyOptions-option.test.js.snap | 135 ++++++++++++ test/uglifyOptions-option.test.js | 25 +++ 5 files changed, 169 insertions(+), 327 deletions(-) diff --git a/src/index.js b/src/index.js index 5a2089b5..68bf5878 100644 --- a/src/index.js +++ b/src/index.js @@ -156,6 +156,7 @@ class UglifyJsPlugin { inputSourceMap = map; } else { inputSourceMap = map; + compilation.warnings.push( new Error(`${file} contains invalid source map`), ); diff --git a/test/UglifyJsPlugin.test.js b/test/UglifyJsPlugin.test.js index 793bd3b2..1153de90 100644 --- a/test/UglifyJsPlugin.test.js +++ b/test/UglifyJsPlugin.test.js @@ -1,199 +1,15 @@ -import { RawSource } from 'webpack-sources'; import UglifyJsPlugin from '../src/index'; -import { cleanErrorStack, compile, createCompiler, PluginEnvironment } from './helpers'; +import { cleanErrorStack, compile, createCompiler } from './helpers'; describe('UglifyJsPlugin', () => { it('should exported as function', () => { expect(typeof new UglifyJsPlugin().apply).toBe('function'); }); - describe('when applied with no options', () => { - let eventBindings; - let eventBinding; - - beforeEach(() => { - const pluginEnvironment = new PluginEnvironment(); - const compilerEnv = pluginEnvironment.getEnvironmentStub(); - compilerEnv.context = ''; - - const plugin = new UglifyJsPlugin(); - plugin.apply(compilerEnv); - eventBindings = pluginEnvironment.getEventBindings(); - }); - - it('binds one event handler', () => { - expect(eventBindings.length).toBe(1); - }); - - describe('compilation handler', () => { - beforeEach(() => { - [eventBinding] = eventBindings; - }); - - it('binds to compilation event', () => { - expect(eventBinding.name).toBe('compilation'); - }); - - describe('when called', () => { - let chunkPluginEnvironment; - let compilationEventBindings; - let compilationEventBinding; - let compilation; - let callback; - - beforeEach(() => { - chunkPluginEnvironment = new PluginEnvironment(); - compilation = chunkPluginEnvironment.getEnvironmentStub(); - compilation.assets = { - 'test.js': {}, - 'test1.js': '', - 'test2.js': { - source: () => 'invalid javascript', - }, - 'test3.js': { - source: () => '/** @preserve Foo Bar */ function foo(longVariableName) { longVariableName = 1; }', - }, - }; - compilation.warnings = []; - compilation.errors = []; - - eventBinding.handler(compilation); - compilationEventBindings = chunkPluginEnvironment.getEventBindings(); - }); - - it('binds one event handler', () => { - expect(compilationEventBindings.length).toBe(1); - }); - - describe('optimize-chunk-assets handler', () => { - beforeEach(() => { - [compilationEventBinding] = compilationEventBindings; - }); - - it('binds to optimize-chunk-assets event', () => { - expect(compilationEventBinding.name).toEqual('optimize-chunk-assets'); - }); - - it('only calls callback once', () => { - callback = jest.fn(); - compilationEventBinding.handler([''], () => { - callback(); - expect(callback.mock.calls.length).toBe(1); - }); - }); - - it('default only parses filenames ending with .js', () => { - compilationEventBinding.handler([{ - files: ['test', 'test.js'], - }], () => { - expect(Object.keys(compilation.assets).length).toBe(4); - }); - }); - - it('empty asset', () => { - compilationEventBinding.handler([{ - files: ['test.js'], - }], () => { - expect(compilation.assets['test.js']).toEqual({}); - }); - }); - - it('outputs stack trace errors for invalid asset', () => { - compilationEventBinding.handler([{ - files: ['test1.js'], - }], () => { - expect(compilation.errors.length).toBe(1); - expect(compilation.errors[0]).toBeInstanceOf(Error); - expect(compilation.errors[0].message).toEqual(expect.stringContaining('asset.source is not a function')); - }); - }); - - it('outputs parsing errors for invalid javascript', () => { - compilationEventBinding.handler([{ - files: ['test2.js'], - }], () => { - expect(compilation.errors.length).toBe(1); - expect(compilation.errors[0]).toBeInstanceOf(Error); - expect(compilation.errors[0].message).toEqual(expect.stringContaining('Unexpected token')); - expect(compilation.errors[0].message).toEqual(expect.stringContaining('[test2.js:1,8]')); - }); - }); - - it('outputs no errors for valid javascript', () => { - compilationEventBinding.handler([{ - files: ['test3.js'], - }], () => { - expect(compilation.errors.length).toBe(0); - }); - }); - - it('outputs RawSource for valid javascript', () => { - compilationEventBinding.handler([{ - files: ['test3.js'], - }], () => { - expect(compilation.assets['test3.js']).toBeInstanceOf(RawSource); - }); - }); - - it('outputs mangled javascript', () => { - compilationEventBinding.handler([{ - files: ['test3.js'], - }], () => { - // eslint-disable-next-line no-underscore-dangle - expect(compilation.assets['test3.js']._value).not.toEqual(expect.stringContaining('longVariableName')); - }); - }); - - it('compresses and does not output beautified javascript', () => { - compilationEventBinding.handler([{ - files: ['test3.js'], - }], () => { - // eslint-disable-next-line no-underscore-dangle - expect(compilation.assets['test3.js']._value).not.toEqual(expect.stringContaining('\n')); - }); - }); - - it('preserves comments', () => { - compilationEventBinding.handler([{ - files: ['test3.js'], - }], () => { - // eslint-disable-next-line no-underscore-dangle - expect(compilation.assets['test3.js']._value).toEqual(expect.stringContaining('/**')); - }); - }); - }); - }); - }); - - it('matches snapshot', () => { - const compiler = createCompiler(); - new UglifyJsPlugin().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'); - - for (const file in stats.compilation.assets) { - if (Object.prototype.hasOwnProperty.call(stats.compilation.assets, file)) { - expect(stats.compilation.assets[file].source()).toMatchSnapshot(file); - } - } - }); - }); - }); - - it('should contains error when uglify has unknown option', () => { + it('should works (without options)', () => { const compiler = createCompiler(); - new UglifyJsPlugin({ - uglifyOptions: { - output: { - unknown: true, - }, - }, - }).apply(compiler); + + new UglifyJsPlugin().apply(compiler); return compile(compiler).then((stats) => { const errors = stats.compilation.errors.map(cleanErrorStack); diff --git a/test/__snapshots__/UglifyJsPlugin.test.js.snap b/test/__snapshots__/UglifyJsPlugin.test.js.snap index 76635886..30005016 100644 --- a/test/__snapshots__/UglifyJsPlugin.test.js.snap +++ b/test/__snapshots__/UglifyJsPlugin.test.js.snap @@ -1,144 +1,9 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`UglifyJsPlugin should contains error when uglify has unknown option: errors 1`] = ` -Array [ - "Error: main.0c220ec66316af2c1b24.js from UglifyJs -DefaultsError: \`unknown\` is not a supported option", - "Error: manifest.d6857f782c13a99b5917.js from UglifyJs -DefaultsError: \`unknown\` is not a supported option", -] -`; +exports[`UglifyJsPlugin should works (without options): errors 1`] = `Array []`; -exports[`UglifyJsPlugin should contains error when uglify has unknown option: main.0c220ec66316af2c1b24.js 1`] = ` -"webpackJsonp([0],[ -/* 0 */ -/***/ (function(module, exports) { +exports[`UglifyJsPlugin should works (without options): main.0c220ec66316af2c1b24.js 1`] = `"webpackJsonp([0],[function(o,n){o.exports=function(){console.log(7)}}],[0]);"`; -// foo -/* @preserve*/ -// bar -const a = 2 + 2; +exports[`UglifyJsPlugin should works (without options): manifest.d6857f782c13a99b5917.js 1`] = `"!function(r){var n=window.webpackJsonp;window.webpackJsonp=function(e,u,c){for(var f,i,p,a=0,l=[];a { }); }); + it('matches snapshot for `unknown` option', () => { + const compiler = createCompiler(); + new UglifyJsPlugin({ + uglifyOptions: { + output: { + unknown: true, + }, + }, + }).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'); + + for (const file in stats.compilation.assets) { + if (Object.prototype.hasOwnProperty.call(stats.compilation.assets, file)) { + expect(stats.compilation.assets[file].source()).toMatchSnapshot(file); + } + } + }); + }); + it('disable inline optimization by default (have a lot of problems)', () => { const compiler = createCompiler({ entry: `${__dirname}/fixtures/inline-optimization.js`, From a34d62f62c42f9c3cd32397718afde135cabfbbc Mon Sep 17 00:00:00 2001 From: evilebottnawi Date: Tue, 31 Jul 2018 22:04:28 +0300 Subject: [PATCH 10/17] refactor: more tests --- src/index.js | 34 ++--- test/UglifyJsPlugin.test.js | 124 +++++++++++++++--- .../__snapshots__/UglifyJsPlugin.test.js.snap | 70 ++++++++++ .../uglifyOptions-option.test.js.snap | 4 +- .../warningsFilter-option.test.js.snap | 8 +- 5 files changed, 202 insertions(+), 38 deletions(-) diff --git a/src/index.js b/src/index.js index 68bf5878..ec888959 100644 --- a/src/index.js +++ b/src/index.js @@ -80,9 +80,10 @@ class UglifyJsPlugin { column: err.col, }); - if (original && original.source) { + if (original && original.source && requestShortener) { return new Error(`${file} from UglifyJs\n${err.message} [${requestShortener.shorten(original.source)}:${original.line},${original.column}][${file}:${err.line},${err.col}]`); } + return new Error(`${file} from UglifyJs\n${err.message} [${file}:${err.line},${err.col}]`); } else if (err.stack) { return new Error(`${file} from UglifyJs\n${err.stack}`); @@ -93,25 +94,28 @@ class UglifyJsPlugin { static buildWarning(warning, file, sourceMap, warningsFilter, requestShortener) { if (!file || !sourceMap) { - return warning; + return `UglifyJs Plugin: ${warning}`; } + let warningMessage = warning; + const match = warningRegex.exec(warning); - const line = +match[1]; - const column = +match[2]; - const original = sourceMap.originalPositionFor({ - line, - column, - }); - - if (!warningsFilter(original.source)) { - return null; - } - let warningMessage = warning.replace(warningRegex, ''); + if (match) { + const line = +match[1]; + const column = +match[2]; + const original = sourceMap.originalPositionFor({ + line, + column, + }); + + if (warningsFilter && !warningsFilter(original.source)) { + return null; + } - if (original && original.source && original.source !== file) { - warningMessage += `[${requestShortener.shorten(original.source)}:${original.line},${original.column}]`; + if (original && original.source && original.source !== file && requestShortener) { + warningMessage = `${warningMessage.replace(warningRegex, '')}[${requestShortener.shorten(original.source)}:${original.line},${original.column}]`; + } } return `UglifyJs Plugin: ${warningMessage} in ${file}`; diff --git a/test/UglifyJsPlugin.test.js b/test/UglifyJsPlugin.test.js index 1153de90..4894c87d 100644 --- a/test/UglifyJsPlugin.test.js +++ b/test/UglifyJsPlugin.test.js @@ -1,10 +1,21 @@ +import RequestShortener from 'webpack/lib/RequestShortener'; import UglifyJsPlugin from '../src/index'; import { cleanErrorStack, compile, createCompiler } from './helpers'; describe('UglifyJsPlugin', () => { - it('should exported as function', () => { - expect(typeof new UglifyJsPlugin().apply).toBe('function'); - }); + const rawSourceMap = { + version: 3, + file: 'test.js', + names: ['bar', 'baz', 'n'], + sources: ['one.js', 'two.js'], + sourceRoot: 'http://example.com/www/js/', + mappings: 'CAAC,IAAI,IAAM,SAAUA,GAClB,OAAOC,IAAID;CCDb,IAAI,IAAM,SAAUE,GAClB,OAAOA', + }; + const emptyRawSourceMap = { + version: 3, + sources: [], + mappings: '', + }; it('should works (without options)', () => { const compiler = createCompiler(); @@ -27,20 +38,6 @@ describe('UglifyJsPlugin', () => { }); it('isSourceMap method', () => { - const rawSourceMap = { - version: 3, - file: 'min.js', - names: ['bar', 'baz', 'n'], - sources: ['one.js', 'two.js'], - sourceRoot: 'http://example.com/www/js/', - mappings: 'CAAC,IAAI,IAAM,SAAUA,GAClB,OAAOC,IAAID;CCDb,IAAI,IAAM,SAAUE,GAClB,OAAOA', - }; - const emptyRawSourceMap = { - version: 3, - sources: [], - mappings: '', - }; - expect(UglifyJsPlugin.isSourceMap(null)).toBe(false); expect(UglifyJsPlugin.isSourceMap()).toBe(false); expect(UglifyJsPlugin.isSourceMap({})).toBe(false); @@ -56,4 +53,97 @@ describe('UglifyJsPlugin', () => { expect(UglifyJsPlugin.isSourceMap(rawSourceMap)).toBe(true); expect(UglifyJsPlugin.isSourceMap(emptyRawSourceMap)).toBe(true); }); + + it('buildSourceMap method', () => { + expect(UglifyJsPlugin.buildSourceMap()).toBe(null); + expect(UglifyJsPlugin.buildSourceMap('invalid')).toBe(null); + expect(UglifyJsPlugin.buildSourceMap({})).toBe(null); + expect(UglifyJsPlugin.buildSourceMap(rawSourceMap)).toMatchSnapshot(); + }); + + it('buildError method', () => { + const error = new Error('Message'); + + error.stack = null; + + expect(UglifyJsPlugin.buildError(error, 'test.js')).toMatchSnapshot(); + + const errorWithLineAndCol = new Error('Message'); + + errorWithLineAndCol.stack = null; + errorWithLineAndCol.line = 1; + errorWithLineAndCol.col = 1; + + expect( + UglifyJsPlugin.buildError( + errorWithLineAndCol, + 'test.js', + UglifyJsPlugin.buildSourceMap(rawSourceMap), + ), + ).toMatchSnapshot(); + + const otherErrorWithLineAndCol = new Error('Message'); + + otherErrorWithLineAndCol.stack = null; + otherErrorWithLineAndCol.line = 1; + otherErrorWithLineAndCol.col = 1; + + expect( + UglifyJsPlugin.buildError( + otherErrorWithLineAndCol, + 'test.js', + UglifyJsPlugin.buildSourceMap(rawSourceMap), + new RequestShortener('http://example.com/www/js/'), + ), + ).toMatchSnapshot(); + + const errorWithStack = new Error('Message'); + + errorWithStack.stack = 'Stack'; + + expect(UglifyJsPlugin.buildError(errorWithStack, 'test.js')).toMatchSnapshot(); + }); + + it('buildWarning method', () => { + expect(UglifyJsPlugin.buildWarning('Warning[foo:1,1]')).toMatchSnapshot(); + expect(UglifyJsPlugin.buildWarning('Warning[foo:1,1]', 'test.js')).toMatchSnapshot(); + expect( + UglifyJsPlugin.buildWarning( + 'Warning[foo:1,1]', + 'test.js', + UglifyJsPlugin.buildSourceMap(rawSourceMap), + ), + ).toMatchSnapshot(); + expect( + UglifyJsPlugin.buildWarning( + 'Warning[foo:1,1]', 'test.js', + UglifyJsPlugin.buildSourceMap(rawSourceMap), + ), + ).toMatchSnapshot(); + expect( + UglifyJsPlugin.buildWarning( + 'Warning[foo:1,1]', + 'test.js', + UglifyJsPlugin.buildSourceMap(rawSourceMap), + () => true, + ), + ).toMatchSnapshot(); + expect( + UglifyJsPlugin.buildWarning( + 'Warning[foo:1,1]', + 'test.js', + UglifyJsPlugin.buildSourceMap(rawSourceMap), + () => false, + ), + ).toMatchSnapshot(); + expect( + UglifyJsPlugin.buildWarning( + 'Warning[foo:1,1]', + 'test.js', + UglifyJsPlugin.buildSourceMap(rawSourceMap), + () => true, + new RequestShortener('http://example.com/www/js/'), + ), + ).toMatchSnapshot(); + }); }); diff --git a/test/__snapshots__/UglifyJsPlugin.test.js.snap b/test/__snapshots__/UglifyJsPlugin.test.js.snap index 30005016..ed4afc1d 100644 --- a/test/__snapshots__/UglifyJsPlugin.test.js.snap +++ b/test/__snapshots__/UglifyJsPlugin.test.js.snap @@ -1,5 +1,75 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP +exports[`UglifyJsPlugin buildError method 1`] = ` +[Error: test.js from UglifyJs +Message] +`; + +exports[`UglifyJsPlugin buildError method 2`] = ` +[Error: test.js from UglifyJs +Message [test.js:1,1]] +`; + +exports[`UglifyJsPlugin buildError method 3`] = ` +[Error: test.js from UglifyJs +Message [./one.js:1,1][test.js:1,1]] +`; + +exports[`UglifyJsPlugin buildError method 4`] = ` +[Error: test.js from UglifyJs +Stack] +`; + +exports[`UglifyJsPlugin buildSourceMap method 1`] = ` +SourceMapConsumer { + "_absoluteSources": Array [ + "http://example.com/www/js/one.js", + "http://example.com/www/js/two.js", + ], + "_mappings": "CAAC,IAAI,IAAM,SAAUA,GAClB,OAAOC,IAAID;CCDb,IAAI,IAAM,SAAUE,GAClB,OAAOA", + "_names": ArraySet { + "_array": Array [ + "bar", + "baz", + "n", + ], + "_set": Map { + "bar" => 0, + "baz" => 1, + "n" => 2, + }, + }, + "_sourceMapURL": undefined, + "_sources": ArraySet { + "_array": Array [ + "one.js", + "two.js", + ], + "_set": Map { + "one.js" => 0, + "two.js" => 1, + }, + }, + "file": "test.js", + "sourceRoot": "http://example.com/www/js/", + "sourcesContent": null, +} +`; + +exports[`UglifyJsPlugin buildWarning method 1`] = `"UglifyJs Plugin: Warning[foo:1,1]"`; + +exports[`UglifyJsPlugin buildWarning method 2`] = `"UglifyJs Plugin: Warning[foo:1,1]"`; + +exports[`UglifyJsPlugin buildWarning method 3`] = `"UglifyJs Plugin: Warning[foo:1,1] in test.js"`; + +exports[`UglifyJsPlugin buildWarning method 4`] = `"UglifyJs Plugin: Warning[foo:1,1] in test.js"`; + +exports[`UglifyJsPlugin buildWarning method 5`] = `"UglifyJs Plugin: Warning[foo:1,1] in test.js"`; + +exports[`UglifyJsPlugin buildWarning method 6`] = `null`; + +exports[`UglifyJsPlugin buildWarning method 7`] = `"UglifyJs Plugin: Warning[./one.js:1,1] in test.js"`; + exports[`UglifyJsPlugin should works (without options): errors 1`] = `Array []`; exports[`UglifyJsPlugin should works (without options): main.0c220ec66316af2c1b24.js 1`] = `"webpackJsonp([0],[function(o,n){o.exports=function(){console.log(7)}}],[0]);"`; diff --git a/test/__snapshots__/uglifyOptions-option.test.js.snap b/test/__snapshots__/uglifyOptions-option.test.js.snap index 1de2d8f7..366fdd21 100644 --- a/test/__snapshots__/uglifyOptions-option.test.js.snap +++ b/test/__snapshots__/uglifyOptions-option.test.js.snap @@ -747,7 +747,7 @@ exports[`when applied with uglifyOptions options matches snapshot for \`warnings exports[`when applied with uglifyOptions options matches snapshot for \`warnings\` option (boolean \`true\` value): warnings 1`] = ` Array [ - "Dropping unreachable code [main.b30dcc7a86bd9929c922.js:5,41]", - "Dropping unused function foo [main.b30dcc7a86bd9929c922.js:5,9]", + "UglifyJs Plugin: Dropping unreachable code [main.b30dcc7a86bd9929c922.js:5,41]", + "UglifyJs Plugin: Dropping unused function foo [main.b30dcc7a86bd9929c922.js:5,9]", ] `; diff --git a/test/__snapshots__/warningsFilter-option.test.js.snap b/test/__snapshots__/warningsFilter-option.test.js.snap index 5b005be9..bfffb73c 100644 --- a/test/__snapshots__/warningsFilter-option.test.js.snap +++ b/test/__snapshots__/warningsFilter-option.test.js.snap @@ -10,10 +10,10 @@ exports[`when applied with \`warningsFilter\` option matches snapshot for a \`fu exports[`when applied with \`warningsFilter\` option matches snapshot for a \`function\` value and \`sourceMap\` is \`false\`: warnings 1`] = ` Array [ - "Dropping unreachable code [one.d321aed3a325448435a0.js:5,41]", - "Dropping unused function foo [one.d321aed3a325448435a0.js:5,9]", - "Dropping unreachable code [two.da1b0e3de955e7df6b6e.js:6,41]", - "Dropping unused function foo [two.da1b0e3de955e7df6b6e.js:6,9]", + "UglifyJs Plugin: Dropping unreachable code [one.d321aed3a325448435a0.js:5,41]", + "UglifyJs Plugin: Dropping unused function foo [one.d321aed3a325448435a0.js:5,9]", + "UglifyJs Plugin: Dropping unreachable code [two.da1b0e3de955e7df6b6e.js:6,41]", + "UglifyJs Plugin: Dropping unused function foo [two.da1b0e3de955e7df6b6e.js:6,9]", ] `; From a6c8ac265041f92423da97d8c669b9e4ca815a08 Mon Sep 17 00:00:00 2001 From: evilebottnawi Date: Tue, 31 Jul 2018 22:09:39 +0300 Subject: [PATCH 11/17] refactor: more tests --- test/__snapshots__/minify-option.test.js.snap | 151 +++++++++++++++++- test/minify-option.test.js | 34 +++- 2 files changed, 180 insertions(+), 5 deletions(-) diff --git a/test/__snapshots__/minify-option.test.js.snap b/test/__snapshots__/minify-option.test.js.snap index aa9799aa..f19f08d8 100644 --- a/test/__snapshots__/minify-option.test.js.snap +++ b/test/__snapshots__/minify-option.test.js.snap @@ -245,7 +245,7 @@ exports[`when applied with \`minify\` option matches snapshot for \`uglify-js\` exports[`when applied with \`minify\` option matches snapshot for \`uglify-js\` minifier: warnings 1`] = `Array []`; -exports[`when applied with \`minify\` option matches snapshot for errors in \`minify\` option: errors 1`] = ` +exports[`when applied with \`minify\` option matches snapshot for errors into \`minify\` option and \`parallel\` is \`true\`: errors 1`] = ` Array [ "Error: main.js from UglifyJs Error: Error", @@ -254,7 +254,7 @@ Error: Error", ] `; -exports[`when applied with \`minify\` option matches snapshot for errors in \`minify\` option: main.js 1`] = ` +exports[`when applied with \`minify\` option matches snapshot for errors into \`minify\` option and \`parallel\` is \`true\`: main.js 1`] = ` "webpackJsonp([0],[ /* 0 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { @@ -282,7 +282,7 @@ class Point { ],[0]);" `; -exports[`when applied with \`minify\` option matches snapshot for errors in \`minify\` option: manifest.js 1`] = ` +exports[`when applied with \`minify\` option matches snapshot for errors into \`minify\` option and \`parallel\` is \`true\`: manifest.js 1`] = ` "/******/ (function(modules) { // webpackBootstrap /******/ // install a JSONP callback for chunk loading /******/ var parentJsonpFunction = window[\\"webpackJsonp\\"]; @@ -386,4 +386,147 @@ exports[`when applied with \`minify\` option matches snapshot for errors in \`mi /******/ ([]);" `; -exports[`when applied with \`minify\` option matches snapshot for errors in \`minify\` option: warnings 1`] = `Array []`; +exports[`when applied with \`minify\` option matches snapshot for errors into \`minify\` option and \`parallel\` is \`true\`: warnings 1`] = `Array []`; + +exports[`when applied with \`minify\` option matches snapshot for errors into \`minify\` option: errors 1`] = ` +Array [ + "Error: main.js from UglifyJs +Error: Error", + "Error: manifest.js from UglifyJs +Error: Error", +] +`; + +exports[`when applied with \`minify\` option matches snapshot for errors into \`minify\` option: main.js 1`] = ` +"webpackJsonp([0],[ +/* 0 */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { + +\\"use strict\\"; +Object.defineProperty(__webpack_exports__, \\"__esModule\\", { value: true }); +class Point { + constructor(x, y) { + this.x = x; + this.y = y; + } + + static distance(a, b) { + const dx = a.x - b.x; + const dy = a.y - b.y; + + return Math.hypot(dx, dy); + } +} + +/* harmony default export */ __webpack_exports__[\\"default\\"] = (Point); + + +/***/ }) +],[0]);" +`; + +exports[`when applied with \`minify\` option matches snapshot for errors into \`minify\` option: manifest.js 1`] = ` +"/******/ (function(modules) { // webpackBootstrap +/******/ // install a JSONP callback for chunk loading +/******/ var parentJsonpFunction = window[\\"webpackJsonp\\"]; +/******/ window[\\"webpackJsonp\\"] = function webpackJsonpCallback(chunkIds, moreModules, executeModules) { +/******/ // add \\"moreModules\\" to the modules object, +/******/ // then flag all \\"chunkIds\\" as loaded and fire callback +/******/ var moduleId, chunkId, i = 0, resolves = [], result; +/******/ for(;i < chunkIds.length; i++) { +/******/ chunkId = chunkIds[i]; +/******/ if(installedChunks[chunkId]) { +/******/ resolves.push(installedChunks[chunkId][0]); +/******/ } +/******/ installedChunks[chunkId] = 0; +/******/ } +/******/ for(moduleId in moreModules) { +/******/ if(Object.prototype.hasOwnProperty.call(moreModules, moduleId)) { +/******/ modules[moduleId] = moreModules[moduleId]; +/******/ } +/******/ } +/******/ if(parentJsonpFunction) parentJsonpFunction(chunkIds, moreModules, executeModules); +/******/ while(resolves.length) { +/******/ resolves.shift()(); +/******/ } +/******/ if(executeModules) { +/******/ for(i=0; i < executeModules.length; i++) { +/******/ result = __webpack_require__(__webpack_require__.s = executeModules[i]); +/******/ } +/******/ } +/******/ return result; +/******/ }; +/******/ +/******/ // The module cache +/******/ var installedModules = {}; +/******/ +/******/ // objects to store loaded and loading chunks +/******/ var installedChunks = { +/******/ 1: 0 +/******/ }; +/******/ +/******/ // The require function +/******/ function __webpack_require__(moduleId) { +/******/ +/******/ // Check if module is in cache +/******/ if(installedModules[moduleId]) { +/******/ return installedModules[moduleId].exports; +/******/ } +/******/ // Create a new module (and put it into the cache) +/******/ var module = installedModules[moduleId] = { +/******/ i: moduleId, +/******/ l: false, +/******/ exports: {} +/******/ }; +/******/ +/******/ // Execute the module function +/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); +/******/ +/******/ // Flag the module as loaded +/******/ module.l = true; +/******/ +/******/ // Return the exports of the module +/******/ return module.exports; +/******/ } +/******/ +/******/ +/******/ // expose the modules object (__webpack_modules__) +/******/ __webpack_require__.m = modules; +/******/ +/******/ // expose the module cache +/******/ __webpack_require__.c = installedModules; +/******/ +/******/ // define getter function for harmony exports +/******/ __webpack_require__.d = function(exports, name, getter) { +/******/ if(!__webpack_require__.o(exports, name)) { +/******/ Object.defineProperty(exports, name, { +/******/ configurable: false, +/******/ enumerable: true, +/******/ get: getter +/******/ }); +/******/ } +/******/ }; +/******/ +/******/ // getDefaultExport function for compatibility with non-harmony modules +/******/ __webpack_require__.n = function(module) { +/******/ var getter = module && module.__esModule ? +/******/ function getDefault() { return module['default']; } : +/******/ function getModuleExports() { return module; }; +/******/ __webpack_require__.d(getter, 'a', getter); +/******/ return getter; +/******/ }; +/******/ +/******/ // Object.prototype.hasOwnProperty.call +/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; +/******/ +/******/ // __webpack_public_path__ +/******/ __webpack_require__.p = \\"\\"; +/******/ +/******/ // on error function for async loading +/******/ __webpack_require__.oe = function(err) { console.error(err); throw err; }; +/******/ }) +/************************************************************************/ +/******/ ([]);" +`; + +exports[`when applied with \`minify\` option matches snapshot for errors into \`minify\` option: warnings 1`] = `Array []`; diff --git a/test/minify-option.test.js b/test/minify-option.test.js index 092e49c4..951e6081 100644 --- a/test/minify-option.test.js +++ b/test/minify-option.test.js @@ -207,7 +207,39 @@ describe('when applied with `minify` option', () => { }); }); - it('matches snapshot for errors in `minify` option', () => { + it('matches snapshot for errors into `minify` option', () => { + const compiler = createCompiler({ + entry: `${__dirname}/fixtures/minify/es6.js`, + output: { + path: `${__dirname}/dist-terser`, + filename: '[name].js', + chunkFilename: '[id].[name].js', + }, + }); + + new UglifyJsPlugin({ + minify() { + throw Error('Error'); + }, + }).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'); + + for (const file in stats.compilation.assets) { + if (Object.prototype.hasOwnProperty.call(stats.compilation.assets, file)) { + expect(stats.compilation.assets[file].source()).toMatchSnapshot(file); + } + } + }); + }); + + it('matches snapshot for errors into `minify` option and `parallel` is `true`', () => { const compiler = createCompiler({ entry: `${__dirname}/fixtures/minify/es6.js`, output: { From db7cf18f05ed5e8b4e8afe158c05f5b772d60b6f Mon Sep 17 00:00:00 2001 From: evilebottnawi Date: Tue, 31 Jul 2018 22:12:47 +0300 Subject: [PATCH 12/17] refactor: tests --- .../sourceMap-option.test.js.snap | 24 +++++++++---------- test/sourceMap-option.test.js | 16 ++++--------- 2 files changed, 16 insertions(+), 24 deletions(-) diff --git a/test/__snapshots__/sourceMap-option.test.js.snap b/test/__snapshots__/sourceMap-option.test.js.snap index 1f174913..05228368 100644 --- a/test/__snapshots__/sourceMap-option.test.js.snap +++ b/test/__snapshots__/sourceMap-option.test.js.snap @@ -1,43 +1,43 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`when options.sourceMap matches snapshot for a single \`false\` value (\`devtool\` is \`false\`): entry.e16453731320636f520c.js 1`] = `"webpackJsonp([0],[function(o,n){o.exports=function(){console.log(7)}}],[0]);"`; - exports[`when options.sourceMap matches snapshot for a single \`false\` value (\`devtool\` is \`false\`): errors 1`] = `Array []`; +exports[`when options.sourceMap matches snapshot for a single \`false\` value (\`devtool\` is \`false\`): main.0c220ec66316af2c1b24.js 1`] = `"webpackJsonp([0],[function(o,n){o.exports=function(){console.log(7)}}],[0]);"`; + exports[`when options.sourceMap matches snapshot for a single \`false\` value (\`devtool\` is \`false\`): manifest.d6857f782c13a99b5917.js 1`] = `"!function(r){var n=window.webpackJsonp;window.webpackJsonp=function(e,u,c){for(var f,i,p,a=0,l=[];a { it('matches snapshot for a single `false` value (`devtool` is `source-map`)', () => { const compiler = createCompiler({ - entry: { - entry: `${__dirname}/fixtures/entry.js`, - }, + entry: `${__dirname}/fixtures/entry.js`, devtool: 'source-map', }); @@ -29,9 +27,7 @@ describe('when options.sourceMap', () => { it('matches snapshot for a single `false` value (`devtool` is `false`)', () => { const compiler = createCompiler({ - entry: { - entry: `${__dirname}/fixtures/entry.js`, - }, + entry: `${__dirname}/fixtures/entry.js`, devtool: false, }); @@ -54,9 +50,7 @@ describe('when options.sourceMap', () => { it('matches snapshot for a single `true` value (`devtool` is `source-map`)', () => { const compiler = createCompiler({ - entry: { - entry: `${__dirname}/fixtures/entry.js`, - }, + entry: `${__dirname}/fixtures/entry.js`, devtool: 'source-map', }); @@ -79,9 +73,7 @@ describe('when options.sourceMap', () => { it('matches snapshot for a single `true` value (`devtool` is `false`)', () => { const compiler = createCompiler({ - entry: { - entry: `${__dirname}/fixtures/entry.js`, - }, + entry: `${__dirname}/fixtures/entry.js`, devtool: false, }); From eac19338c2239079c8f14c91992ce43cb98405aa Mon Sep 17 00:00:00 2001 From: evilebottnawi Date: Tue, 31 Jul 2018 22:21:37 +0300 Subject: [PATCH 13/17] refactor: tests --- src/uglify/Runner.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/uglify/Runner.js b/src/uglify/Runner.js index e43549de..69ee09e9 100644 --- a/src/uglify/Runner.js +++ b/src/uglify/Runner.js @@ -20,6 +20,7 @@ export default class Runner { } runTasks(tasks, callback) { + /* istanbul ignore if */ if (!tasks.length) { callback(null, []); return; From ebe17e164dad205df578bc551b911e76aff15ae3 Mon Sep 17 00:00:00 2001 From: evilebottnawi Date: Tue, 31 Jul 2018 22:30:31 +0300 Subject: [PATCH 14/17] fix: missing snapshot --- test/__snapshots__/validation.test.js.snap | 91 ++++++++++++++++++++++ 1 file changed, 91 insertions(+) create mode 100644 test/__snapshots__/validation.test.js.snap diff --git a/test/__snapshots__/validation.test.js.snap b/test/__snapshots__/validation.test.js.snap new file mode 100644 index 00000000..ff3f4aed --- /dev/null +++ b/test/__snapshots__/validation.test.js.snap @@ -0,0 +1,91 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`validation 1`] = ` +"UglifyJs Plugin Invalid Options + +options['doesntExist'] is an invalid additional property +" +`; + +exports[`validation 2`] = ` +"UglifyJs Plugin Invalid Options + +options.cache should be boolean +options.cache should be string +options.cache should match exactly one schema in oneOf +" +`; + +exports[`validation 3`] = ` +"UglifyJs Plugin Invalid Options + +options.parallel should be boolean +options.parallel should be integer +options.parallel should match exactly one schema in oneOf +" +`; + +exports[`validation 4`] = ` +"UglifyJs Plugin Invalid Options + +options.parallel should be boolean +options.parallel should be integer +options.parallel should match exactly one schema in oneOf +" +`; + +exports[`validation 5`] = ` +"UglifyJs Plugin Invalid Options + +options.sourceMap should be boolean +" +`; + +exports[`validation 6`] = ` +"UglifyJs Plugin Invalid Options + +options.uglifyOptions should be object +" +`; + +exports[`validation 7`] = ` +"UglifyJs Plugin Invalid Options + +options.uglifyOptions.ie8 should be boolean +" +`; + +exports[`validation 8`] = ` +"UglifyJs Plugin Invalid Options + +options.uglifyOptions.ecma should be integer +" +`; + +exports[`validation 9`] = ` +"UglifyJs Plugin Invalid Options + +options.uglifyOptions.ecma should be integer +" +`; + +exports[`validation 10`] = ` +"UglifyJs Plugin Invalid Options + +options.uglifyOptions.ecma should be integer +" +`; + +exports[`validation 11`] = ` +"UglifyJs Plugin Invalid Options + +options.uglifyOptions.ecma should be >= 5 +" +`; + +exports[`validation 12`] = ` +"UglifyJs Plugin Invalid Options + +options.uglifyOptions.ecma should be <= 8 +" +`; From da58a4a874942f739cc67b2c136d50a450e64eab Mon Sep 17 00:00:00 2001 From: evilebottnawi Date: Wed, 1 Aug 2018 12:31:00 +0300 Subject: [PATCH 15/17] test: `error` in `cacheKeys` option --- test/__snapshots__/cache-option.test.js.snap | 145 +++++++++++++++++++ test/cache-option.test.js | 24 +++ 2 files changed, 169 insertions(+) diff --git a/test/__snapshots__/cache-option.test.js.snap b/test/__snapshots__/cache-option.test.js.snap index ad5e3d87..68582aa4 100644 --- a/test/__snapshots__/cache-option.test.js.snap +++ b/test/__snapshots__/cache-option.test.js.snap @@ -202,3 +202,148 @@ exports[`when applied with \`cache\` option matches snapshot for \`true\` value: exports[`when applied with \`cache\` option matches snapshot for \`true\` value: warnings 1`] = `Array []`; exports[`when applied with \`cache\` option matches snapshot for \`true\` value: warnings 2`] = `Array []`; + +exports[`when applied with \`cache\` option matches snapshot for errors into \`cacheKeys\` option: errors 1`] = ` +Array [ + "Error: one.91254a4178472993cf9f.js from UglifyJs +Error: message", + "Error: two.e9fc295fcef530d66dc5.js from UglifyJs +Error: message", + "Error: three.16209e63e6e5fb2ca2e3.js from UglifyJs +Error: message", + "Error: four.0741ac92c5e76ec45240.js from UglifyJs +Error: message", + "Error: manifest.f504b5c36c66d8aa6a74.js from UglifyJs +Error: message", +] +`; + +exports[`when applied with \`cache\` option matches snapshot for errors into \`cacheKeys\` option: four.0741ac92c5e76ec45240.js 1`] = `"webpackJsonp([3],[],[0]);"`; + +exports[`when applied with \`cache\` option matches snapshot for errors into \`cacheKeys\` option: manifest.f504b5c36c66d8aa6a74.js 1`] = ` +"/******/ (function(modules) { // webpackBootstrap +/******/ // install a JSONP callback for chunk loading +/******/ var parentJsonpFunction = window[\\"webpackJsonp\\"]; +/******/ window[\\"webpackJsonp\\"] = function webpackJsonpCallback(chunkIds, moreModules, executeModules) { +/******/ // add \\"moreModules\\" to the modules object, +/******/ // then flag all \\"chunkIds\\" as loaded and fire callback +/******/ var moduleId, chunkId, i = 0, resolves = [], result; +/******/ for(;i < chunkIds.length; i++) { +/******/ chunkId = chunkIds[i]; +/******/ if(installedChunks[chunkId]) { +/******/ resolves.push(installedChunks[chunkId][0]); +/******/ } +/******/ installedChunks[chunkId] = 0; +/******/ } +/******/ for(moduleId in moreModules) { +/******/ if(Object.prototype.hasOwnProperty.call(moreModules, moduleId)) { +/******/ modules[moduleId] = moreModules[moduleId]; +/******/ } +/******/ } +/******/ if(parentJsonpFunction) parentJsonpFunction(chunkIds, moreModules, executeModules); +/******/ while(resolves.length) { +/******/ resolves.shift()(); +/******/ } +/******/ if(executeModules) { +/******/ for(i=0; i < executeModules.length; i++) { +/******/ result = __webpack_require__(__webpack_require__.s = executeModules[i]); +/******/ } +/******/ } +/******/ return result; +/******/ }; +/******/ +/******/ // The module cache +/******/ var installedModules = {}; +/******/ +/******/ // objects to store loaded and loading chunks +/******/ var installedChunks = { +/******/ 4: 0 +/******/ }; +/******/ +/******/ // The require function +/******/ function __webpack_require__(moduleId) { +/******/ +/******/ // Check if module is in cache +/******/ if(installedModules[moduleId]) { +/******/ return installedModules[moduleId].exports; +/******/ } +/******/ // Create a new module (and put it into the cache) +/******/ var module = installedModules[moduleId] = { +/******/ i: moduleId, +/******/ l: false, +/******/ exports: {} +/******/ }; +/******/ +/******/ // Execute the module function +/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); +/******/ +/******/ // Flag the module as loaded +/******/ module.l = true; +/******/ +/******/ // Return the exports of the module +/******/ return module.exports; +/******/ } +/******/ +/******/ +/******/ // expose the modules object (__webpack_modules__) +/******/ __webpack_require__.m = modules; +/******/ +/******/ // expose the module cache +/******/ __webpack_require__.c = installedModules; +/******/ +/******/ // define getter function for harmony exports +/******/ __webpack_require__.d = function(exports, name, getter) { +/******/ if(!__webpack_require__.o(exports, name)) { +/******/ Object.defineProperty(exports, name, { +/******/ configurable: false, +/******/ enumerable: true, +/******/ get: getter +/******/ }); +/******/ } +/******/ }; +/******/ +/******/ // getDefaultExport function for compatibility with non-harmony modules +/******/ __webpack_require__.n = function(module) { +/******/ var getter = module && module.__esModule ? +/******/ function getDefault() { return module['default']; } : +/******/ function getModuleExports() { return module; }; +/******/ __webpack_require__.d(getter, 'a', getter); +/******/ return getter; +/******/ }; +/******/ +/******/ // Object.prototype.hasOwnProperty.call +/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; +/******/ +/******/ // __webpack_public_path__ +/******/ __webpack_require__.p = \\"\\"; +/******/ +/******/ // on error function for async loading +/******/ __webpack_require__.oe = function(err) { console.error(err); throw err; }; +/******/ }) +/************************************************************************/ +/******/ ([ +/* 0 */ +/***/ (function(module, exports) { + +// foo +/* @preserve*/ +// bar +const a = 2 + 2; + +module.exports = function Foo() { + const b = 2 + 2; + console.log(b + 1 + 2); +}; + + +/***/ }) +/******/ ]);" +`; + +exports[`when applied with \`cache\` option matches snapshot for errors into \`cacheKeys\` option: one.91254a4178472993cf9f.js 1`] = `"webpackJsonp([0],[],[0]);"`; + +exports[`when applied with \`cache\` option matches snapshot for errors into \`cacheKeys\` option: three.16209e63e6e5fb2ca2e3.js 1`] = `"webpackJsonp([2],[],[0]);"`; + +exports[`when applied with \`cache\` option matches snapshot for errors into \`cacheKeys\` option: two.e9fc295fcef530d66dc5.js 1`] = `"webpackJsonp([1],[],[0]);"`; + +exports[`when applied with \`cache\` option matches snapshot for errors into \`cacheKeys\` option: warnings 1`] = `Array []`; diff --git a/test/cache-option.test.js b/test/cache-option.test.js index fbac018d..2fc2a242 100644 --- a/test/cache-option.test.js +++ b/test/cache-option.test.js @@ -286,4 +286,28 @@ describe('when applied with `cache` option', () => { }); }); }); + + it('matches snapshot for errors into `cacheKeys` option', () => { + new UglifyJsPlugin({ + cache: true, + cacheKeys: () => { + throw new Error('message'); + }, + }).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'); + + for (const file in stats.compilation.assets) { + if (Object.prototype.hasOwnProperty.call(stats.compilation.assets, file)) { + expect(stats.compilation.assets[file].source()).toMatchSnapshot(file); + } + } + }); + }); }); From 39e505cd1387ebcf59c3467faa4bb35af36c5bea Mon Sep 17 00:00:00 2001 From: evilebottnawi Date: Wed, 1 Aug 2018 14:38:22 +0300 Subject: [PATCH 16/17] test: invalid source map --- .../sourceMap-option.test.js.snap | 22 ++++++++ test/sourceMap-option.test.js | 52 +++++++++++++++++++ 2 files changed, 74 insertions(+) diff --git a/test/__snapshots__/sourceMap-option.test.js.snap b/test/__snapshots__/sourceMap-option.test.js.snap index 05228368..46ffeaaa 100644 --- a/test/__snapshots__/sourceMap-option.test.js.snap +++ b/test/__snapshots__/sourceMap-option.test.js.snap @@ -24,6 +24,28 @@ exports[`when options.sourceMap matches snapshot for a single \`true\` value (\` exports[`when options.sourceMap matches snapshot for a single \`true\` value (\`devtool\` is \`false\`): warnings 1`] = `Array []`; +exports[`when options.sourceMap matches snapshot for a single \`true\` value (\`devtool\` is \`source-map\`) and source map invalid: broken-source-map.js 1`] = `"var test = 1;"`; + +exports[`when options.sourceMap matches snapshot for a single \`true\` value (\`devtool\` is \`source-map\`) and source map invalid: errors 1`] = ` +Array [ + "Error: broken-source-map.js from UglifyJs +Error: \\"version\\" is a required argument.", +] +`; + +exports[`when options.sourceMap matches snapshot for a single \`true\` value (\`devtool\` is \`source-map\`) and source map invalid: main.4dff64fd1192e906e901.js 1`] = ` +"!function(n){var t={};function e(r){if(t[r])return t[r].exports;var o=t[r]={i:r,l:!1,exports:{}};return n[r].call(o.exports,o,o.exports,e),o.l=!0,o.exports}e.m=n,e.c=t,e.d=function(n,t,r){e.o(n,t)||Object.defineProperty(n,t,{configurable:!1,enumerable:!0,get:r})},e.n=function(n){var t=n&&n.__esModule?function(){return n.default}:function(){return n};return e.d(t,\\"a\\",t),t},e.o=function(n,t){return Object.prototype.hasOwnProperty.call(n,t)},e.p=\\"\\",e(e.s=0)}([function(n,t){n.exports=function(){console.log(7)}}]); +//# sourceMappingURL=main.4dff64fd1192e906e901.js.map" +`; + +exports[`when options.sourceMap matches snapshot for a single \`true\` value (\`devtool\` is \`source-map\`) and source map invalid: main.4dff64fd1192e906e901.js.map 1`] = `"{\\"version\\":3,\\"sources\\":[\\"webpack:///webpack/bootstrap a5a00654339b12ca9959\\",\\"webpack:///./test/fixtures/entry.js\\"],\\"names\\":[\\"installedModules\\",\\"__webpack_require__\\",\\"moduleId\\",\\"exports\\",\\"module\\",\\"i\\",\\"l\\",\\"modules\\",\\"call\\",\\"m\\",\\"c\\",\\"d\\",\\"name\\",\\"getter\\",\\"o\\",\\"Object\\",\\"defineProperty\\",\\"configurable\\",\\"enumerable\\",\\"get\\",\\"n\\",\\"__esModule\\",\\"object\\",\\"property\\",\\"prototype\\",\\"hasOwnProperty\\",\\"p\\",\\"s\\",\\"console\\",\\"log\\",\\"b\\"],\\"mappings\\":\\"aACA,IAAAA,KAGA,SAAAC,EAAAC,GAGA,GAAAF,EAAAE,GACA,OAAAF,EAAAE,GAAAC,QAGA,IAAAC,EAAAJ,EAAAE,IACAG,EAAAH,EACAI,GAAA,EACAH,YAUA,OANAI,EAAAL,GAAAM,KAAAJ,EAAAD,QAAAC,IAAAD,QAAAF,GAGAG,EAAAE,GAAA,EAGAF,EAAAD,QAKAF,EAAAQ,EAAAF,EAGAN,EAAAS,EAAAV,EAGAC,EAAAU,EAAA,SAAAR,EAAAS,EAAAC,GACAZ,EAAAa,EAAAX,EAAAS,IACAG,OAAAC,eAAAb,EAAAS,GACAK,cAAA,EACAC,YAAA,EACAC,IAAAN,KAMAZ,EAAAmB,EAAA,SAAAhB,GACA,IAAAS,EAAAT,KAAAiB,WACA,WAA2B,OAAAjB,EAAA,SAC3B,WAAiC,OAAAA,GAEjC,OADAH,EAAAU,EAAAE,EAAA,IAAAA,GACAA,GAIAZ,EAAAa,EAAA,SAAAQ,EAAAC,GAAsD,OAAAR,OAAAS,UAAAC,eAAAjB,KAAAc,EAAAC,IAGtDtB,EAAAyB,EAAA,GAGAzB,IAAA0B,EAAA,mBCxDAvB,EAAAD,QAAA,WAEAyB,QAAAC,IAAAC\\",\\"file\\":\\"main.4dff64fd1192e906e901.js\\",\\"sourcesContent\\":[\\" \\\\t// The module cache\\\\n \\\\tvar installedModules = {};\\\\n\\\\n \\\\t// The require function\\\\n \\\\tfunction __webpack_require__(moduleId) {\\\\n\\\\n \\\\t\\\\t// Check if module is in cache\\\\n \\\\t\\\\tif(installedModules[moduleId]) {\\\\n \\\\t\\\\t\\\\treturn installedModules[moduleId].exports;\\\\n \\\\t\\\\t}\\\\n \\\\t\\\\t// Create a new module (and put it into the cache)\\\\n \\\\t\\\\tvar module = installedModules[moduleId] = {\\\\n \\\\t\\\\t\\\\ti: moduleId,\\\\n \\\\t\\\\t\\\\tl: false,\\\\n \\\\t\\\\t\\\\texports: {}\\\\n \\\\t\\\\t};\\\\n\\\\n \\\\t\\\\t// Execute the module function\\\\n \\\\t\\\\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\\\\n\\\\n \\\\t\\\\t// Flag the module as loaded\\\\n \\\\t\\\\tmodule.l = true;\\\\n\\\\n \\\\t\\\\t// Return the exports of the module\\\\n \\\\t\\\\treturn module.exports;\\\\n \\\\t}\\\\n\\\\n\\\\n \\\\t// expose the modules object (__webpack_modules__)\\\\n \\\\t__webpack_require__.m = modules;\\\\n\\\\n \\\\t// expose the module cache\\\\n \\\\t__webpack_require__.c = installedModules;\\\\n\\\\n \\\\t// define getter function for harmony exports\\\\n \\\\t__webpack_require__.d = function(exports, name, getter) {\\\\n \\\\t\\\\tif(!__webpack_require__.o(exports, name)) {\\\\n \\\\t\\\\t\\\\tObject.defineProperty(exports, name, {\\\\n \\\\t\\\\t\\\\t\\\\tconfigurable: false,\\\\n \\\\t\\\\t\\\\t\\\\tenumerable: true,\\\\n \\\\t\\\\t\\\\t\\\\tget: getter\\\\n \\\\t\\\\t\\\\t});\\\\n \\\\t\\\\t}\\\\n \\\\t};\\\\n\\\\n \\\\t// getDefaultExport function for compatibility with non-harmony modules\\\\n \\\\t__webpack_require__.n = function(module) {\\\\n \\\\t\\\\tvar getter = module && module.__esModule ?\\\\n \\\\t\\\\t\\\\tfunction getDefault() { return module['default']; } :\\\\n \\\\t\\\\t\\\\tfunction getModuleExports() { return module; };\\\\n \\\\t\\\\t__webpack_require__.d(getter, 'a', getter);\\\\n \\\\t\\\\treturn getter;\\\\n \\\\t};\\\\n\\\\n \\\\t// Object.prototype.hasOwnProperty.call\\\\n \\\\t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\\\\n\\\\n \\\\t// __webpack_public_path__\\\\n \\\\t__webpack_require__.p = \\\\\\"\\\\\\";\\\\n\\\\n \\\\t// Load entry module and return exports\\\\n \\\\treturn __webpack_require__(__webpack_require__.s = 0);\\\\n\\\\n\\\\n\\\\n// WEBPACK FOOTER //\\\\n// webpack/bootstrap a5a00654339b12ca9959\\",\\"// foo\\\\n/* @preserve*/\\\\n// bar\\\\nconst a = 2 + 2;\\\\n\\\\nmodule.exports = function Foo() {\\\\n const b = 2 + 2;\\\\n console.log(b + 1 + 2);\\\\n};\\\\n\\\\n\\\\n\\\\n//////////////////\\\\n// WEBPACK FOOTER\\\\n// ./test/fixtures/entry.js\\\\n// module id = 0\\\\n// module chunks = 0\\"],\\"sourceRoot\\":\\"\\"}"`; + +exports[`when options.sourceMap matches snapshot for a single \`true\` value (\`devtool\` is \`source-map\`) and source map invalid: warnings 1`] = ` +Array [ + "Error: broken-source-map.js contains invalid source map", +] +`; + exports[`when options.sourceMap matches snapshot for a single \`true\` value (\`devtool\` is \`source-map\`): errors 1`] = `Array []`; exports[`when options.sourceMap matches snapshot for a single \`true\` value (\`devtool\` is \`source-map\`): main.0c220ec66316af2c1b24.js 1`] = ` diff --git a/test/sourceMap-option.test.js b/test/sourceMap-option.test.js index 0f4e40ca..16dedb61 100644 --- a/test/sourceMap-option.test.js +++ b/test/sourceMap-option.test.js @@ -93,4 +93,56 @@ describe('when options.sourceMap', () => { } }); }); + + it('matches snapshot for a single `true` value (`devtool` is `source-map`) and source map invalid', () => { + const compiler = createCompiler({ + entry: `${__dirname}/fixtures/entry.js`, + devtool: 'source-map', + plugins: [ + { + apply(pluginCompiler) { + pluginCompiler.plugin('compilation', (compilation) => { + compilation.plugin('additional-chunk-assets', () => { + compilation.additionalChunkAssets.push('broken-source-map.js'); + + const assetContent = 'var test = 1;'; + + // eslint-disable-next-line no-param-reassign + compilation.assets['broken-source-map.js'] = { + size() { + return assetContent.length; + }, + source() { + return assetContent; + }, + sourceAndMap() { + return { + source: this.source(), + map: {}, + }; + }, + }; + }); + }); + }, + }, + ], + }); + + new UglifyJsPlugin({ sourceMap: true }).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'); + + for (const file in stats.compilation.assets) { + if (Object.prototype.hasOwnProperty.call(stats.compilation.assets, file)) { + expect(stats.compilation.assets[file].source()).toMatchSnapshot(file); + } + } + }); + }); }); From 605f6c7743a307c43aadf25c1f798e8cc24dd4b7 Mon Sep 17 00:00:00 2001 From: evilebottnawi Date: Wed, 1 Aug 2018 15:01:12 +0300 Subject: [PATCH 17/17] style: code --- src/index.js | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/index.js b/src/index.js index ec888959..08997a0c 100644 --- a/src/index.js +++ b/src/index.js @@ -275,7 +275,8 @@ class UglifyJsPlugin { if (banner) { outputSource = new ConcatSource( - `/*! ${banner} */\n`, outputSource, + `/*! ${banner} */\n`, + outputSource, ); } } @@ -289,7 +290,9 @@ class UglifyJsPlugin { compilation.assets[commentsFile].add(commentsSource); } else { compilation.assets[commentsFile] = new ConcatSource( - compilation.assets[commentsFile], '\n', commentsSource, + compilation.assets[commentsFile], + '\n', + commentsSource, ); } } else {