webpack/test/UglifyJsPlugin.test.js

668 lines
20 KiB
JavaScript
Raw Permalink Normal View History

2017-02-04 22:37:21 +08:00
/* globals describe, it, beforeEach*/
2017-01-29 00:32:56 +08:00
"use strict";
2017-02-04 22:37:21 +08:00
require("should");
2017-01-29 00:32:56 +08:00
const sinon = require("sinon");
2017-01-29 00:41:09 +08:00
const UglifyJsPlugin = require("../lib/optimize/UglifyJsPlugin");
2017-01-29 00:32:56 +08:00
const PluginEnvironment = require("./helpers/PluginEnvironment");
const SourceMapSource = require("webpack-sources").SourceMapSource;
const RawSource = require("webpack-sources").RawSource;
2017-01-29 00:41:09 +08:00
describe("UglifyJsPlugin", function() {
2017-01-29 00:32:56 +08:00
it("has apply function", function() {
2017-01-29 00:41:09 +08:00
(new UglifyJsPlugin()).apply.should.be.a.Function();
2017-01-29 00:32:56 +08:00
});
describe("when applied with no options", function() {
let eventBindings;
let eventBinding;
beforeEach(function() {
const pluginEnvironment = new PluginEnvironment();
const compilerEnv = pluginEnvironment.getEnvironmentStub();
compilerEnv.context = "";
2017-01-29 00:41:09 +08:00
const plugin = new UglifyJsPlugin();
2017-01-29 00:32:56 +08:00
plugin.apply(compilerEnv);
eventBindings = pluginEnvironment.getEventBindings();
});
it("binds one event handler", function() {
eventBindings.length.should.be.exactly(1);
});
describe("compilation handler", function() {
beforeEach(function() {
eventBinding = eventBindings[0];
});
it("binds to compilation event", function() {
eventBinding.name.should.be.exactly("compilation");
});
describe("when called", function() {
let chunkPluginEnvironment;
let compilationEventBindings;
let compilationEventBinding;
let compilation;
let callback;
beforeEach(function() {
chunkPluginEnvironment = new PluginEnvironment();
compilation = chunkPluginEnvironment.getEnvironmentStub();
compilation.assets = {
"test.js": {
__UglifyJsPlugin: {}
},
"test1.js": "",
"test2.js": {
source: function() {
return "invalid javascript";
}
},
"test3.js": {
source: function() {
return "/** @preserve Foo Bar */ function foo(longVariableName) { longVariableName = 1; }";
}
}
};
compilation.errors = [];
eventBinding.handler(compilation);
compilationEventBindings = chunkPluginEnvironment.getEventBindings();
});
it("binds one event handler", function() {
compilationEventBindings.length.should.be.exactly(1);
});
describe("optimize-chunk-assets handler", function() {
beforeEach(function() {
compilationEventBinding = compilationEventBindings[0];
});
it("binds to optimize-chunk-assets event", function() {
compilationEventBinding.name.should.be.exactly("optimize-chunk-assets");
});
it("only calls callback once", function() {
callback = sinon.spy();
compilationEventBinding.handler([""], callback);
callback.callCount.should.be.exactly(1);
});
it("default only parses filenames ending with .js", function() {
compilationEventBinding.handler([{
files: ["test", "test.js"]
}], function() {
Object.keys(compilation.assets).length.should.be.exactly(4);
});
});
it("early returns if private property is already set", function() {
compilationEventBinding.handler([{
files: ["test.js"]
}], function() {
compilation.assets["test.js"].should.deepEqual({});
});
});
it("outputs stack trace errors for invalid asset", function() {
compilationEventBinding.handler([{
files: ["test1.js"]
}], function() {
compilation.errors.length.should.be.exactly(1);
compilation.errors[0].should.be.an.Error;
compilation.errors[0].message.should.have.containEql("TypeError");
});
});
it("outputs parsing errors for invalid javascript", function() {
compilationEventBinding.handler([{
files: ["test2.js"]
}], function() {
compilation.errors.length.should.be.exactly(1);
compilation.errors[0].should.be.an.Error;
compilation.errors[0].message.should.have.containEql("Unexpected token");
2017-01-29 00:32:56 +08:00
compilation.errors[0].message.should.have.containEql("[test2.js:1,8]");
});
});
it("outputs no errors for valid javascript", function() {
compilationEventBinding.handler([{
files: ["test3.js"]
}], function() {
compilation.errors.length.should.be.exactly(0);
});
});
it("outputs RawSource for valid javascript", function() {
compilationEventBinding.handler([{
files: ["test3.js"]
}], function() {
compilation.assets["test3.js"].should.be.instanceof(RawSource);
});
});
it("outputs mangled javascript", function() {
compilationEventBinding.handler([{
files: ["test3.js"]
}], function() {
compilation.assets["test3.js"]._value.should.not.containEql("longVariableName");
});
});
it("compresses and does not output beautified javascript", function() {
compilationEventBinding.handler([{
files: ["test3.js"]
}], function() {
compilation.assets["test3.js"]._value.should.not.containEql("\n");
});
});
it("preserves comments", function() {
compilationEventBinding.handler([{
files: ["test3.js"]
}], function() {
compilation.assets["test3.js"]._value.should.containEql("/**");
});
});
});
});
});
});
describe("when applied with invalid options", function() {
it("outputs uglify errors", function() {
const pluginEnvironment = new PluginEnvironment();
const compilerEnv = pluginEnvironment.getEnvironmentStub();
compilerEnv.context = "";
2017-01-29 00:41:09 +08:00
const plugin = new UglifyJsPlugin({
2017-01-29 00:32:56 +08:00
output: {
"invalid-option": true
}
});
plugin.apply(compilerEnv);
const eventBinding = pluginEnvironment.getEventBindings()[0];
const chunkPluginEnvironment = new PluginEnvironment();
const compilation = chunkPluginEnvironment.getEnvironmentStub();
compilation.assets = {
"test.js": {
source: function() {
return "var foo = 1;";
}
}
};
compilation.errors = [];
eventBinding.handler(compilation);
const compilationEventBinding = chunkPluginEnvironment.getEventBindings()[0];
compilationEventBinding.handler([{
files: ["test.js"]
}], function() {
compilation.errors.length.should.be.exactly(1);
compilation.errors[0].message.should.have.containEql("supported option");
});
});
});
describe("when applied with all options", function() {
let eventBindings;
let eventBinding;
beforeEach(function() {
const pluginEnvironment = new PluginEnvironment();
const compilerEnv = pluginEnvironment.getEnvironmentStub();
compilerEnv.context = "";
2017-01-29 00:41:09 +08:00
const plugin = new UglifyJsPlugin({
2017-01-29 00:32:56 +08:00
sourceMap: true,
compress: {
warnings: true,
},
mangle: false,
beautify: true,
UglifyJsPlugin: extract comments to separate file License comments use up a lot of space, especially when using many small libraries with large license blocks. With this addition, you can extract all license comments to a separate file and remove them from the bundle files. A small banner points to the file containing all license information such that the user can find it if needed. We add a new option extractComments to the UglifyJsPlugin. It can be omitted, then the behavior does not change, or it can be: - true: All comments that normally would be preserved by the comments option will be moved to a separate file. If the original file is named foo.js, then the comments will be stored to foo.js.LICENSE - regular expression (given as RegExp or string) or a function (astNode, comment) -> boolean: All comments that match the given expression (resp. are evaluated to true by the function) will be extracted to the separate file. The comments option specifies whether the comment will be preserved, i.e. it is possible to preserve some comments (e.g. annotations) while extracting others or even preserving comments that have been extracted. - an object consisting of the following keys, all optional: - condition: regular expression or function (see previous point) - file: The file where the extracted comments will be stored. Can be either a string (filename) or function (string) -> string which will be given the original filename. Default is to append the suffix .LICENSE to the original filename. - banner: The banner text that points to the extracted file and will be added on top of the original file. will be added to the original file. Can be false (no banner), a string, or a function (string) -> string that will be called with the filename where extracted comments have been stored. Will be wrapped into comment. Default: /*! For license information please see foo.js.LICENSE */
2017-01-30 07:43:09 +08:00
comments: false,
extractComments: {
condition: 'should be extracted',
2017-02-11 06:16:20 +08:00
filename: function(file) {
UglifyJsPlugin: extract comments to separate file License comments use up a lot of space, especially when using many small libraries with large license blocks. With this addition, you can extract all license comments to a separate file and remove them from the bundle files. A small banner points to the file containing all license information such that the user can find it if needed. We add a new option extractComments to the UglifyJsPlugin. It can be omitted, then the behavior does not change, or it can be: - true: All comments that normally would be preserved by the comments option will be moved to a separate file. If the original file is named foo.js, then the comments will be stored to foo.js.LICENSE - regular expression (given as RegExp or string) or a function (astNode, comment) -> boolean: All comments that match the given expression (resp. are evaluated to true by the function) will be extracted to the separate file. The comments option specifies whether the comment will be preserved, i.e. it is possible to preserve some comments (e.g. annotations) while extracting others or even preserving comments that have been extracted. - an object consisting of the following keys, all optional: - condition: regular expression or function (see previous point) - file: The file where the extracted comments will be stored. Can be either a string (filename) or function (string) -> string which will be given the original filename. Default is to append the suffix .LICENSE to the original filename. - banner: The banner text that points to the extracted file and will be added on top of the original file. will be added to the original file. Can be false (no banner), a string, or a function (string) -> string that will be called with the filename where extracted comments have been stored. Will be wrapped into comment. Default: /*! For license information please see foo.js.LICENSE */
2017-01-30 07:43:09 +08:00
return file.replace(/(\.\w+)$/, '.license$1');
},
banner: function(licenseFile) {
return 'License information can be found in ' + licenseFile;
}
}
2017-01-29 00:32:56 +08:00
});
plugin.apply(compilerEnv);
eventBindings = pluginEnvironment.getEventBindings();
});
it("binds one event handler", function() {
eventBindings.length.should.be.exactly(1);
});
describe("compilation handler", function() {
beforeEach(function() {
eventBinding = eventBindings[0];
});
it("binds to compilation event", function() {
eventBinding.name.should.be.exactly("compilation");
});
describe("when called", function() {
let chunkPluginEnvironment;
let compilationEventBindings;
let compilationEventBinding;
let compilation;
beforeEach(function() {
chunkPluginEnvironment = new PluginEnvironment();
compilation = chunkPluginEnvironment.getEnvironmentStub();
compilation.assets = {
"test.js": {
source: function() {
return "/** @preserve Foo Bar */ function foo(longVariableName) { longVariableName = 1; }";
},
map: function() {
return {
version: 3,
sources: ["test.js"],
names: ["foo", "longVariableName"],
mappings: "AAAA,QAASA,KAAIC,kBACTA,iBAAmB"
};
}
},
"test1.js": {
source: function() {
return "invalid javascript";
},
map: function() {
return {
version: 3,
sources: ["test1.js"],
names: [""],
mappings: "AAAA"
};
}
},
"test2.js": {
source: function() {
return "function foo(x) { if (x) { return bar(); not_called1(); } }";
},
map: function() {
return {
version: 3,
sources: ["test1.js"],
names: ["foo", "x", "bar", "not_called1"],
mappings: "AAAA,QAASA,KAAIC,GACT,GAAIA,EAAG,CACH,MAAOC,MACPC"
};
}
},
"test3.js": {
sourceAndMap: function() {
return {
source: "/** @preserve Foo Bar */ function foo(longVariableName) { longVariableName = 1; }",
map: {
version: 3,
sources: ["test.js"],
names: ["foo", "longVariableName"],
mappings: "AAAA,QAASA,KAAIC,kBACTA,iBAAmB"
}
};
},
},
UglifyJsPlugin: extract comments to separate file License comments use up a lot of space, especially when using many small libraries with large license blocks. With this addition, you can extract all license comments to a separate file and remove them from the bundle files. A small banner points to the file containing all license information such that the user can find it if needed. We add a new option extractComments to the UglifyJsPlugin. It can be omitted, then the behavior does not change, or it can be: - true: All comments that normally would be preserved by the comments option will be moved to a separate file. If the original file is named foo.js, then the comments will be stored to foo.js.LICENSE - regular expression (given as RegExp or string) or a function (astNode, comment) -> boolean: All comments that match the given expression (resp. are evaluated to true by the function) will be extracted to the separate file. The comments option specifies whether the comment will be preserved, i.e. it is possible to preserve some comments (e.g. annotations) while extracting others or even preserving comments that have been extracted. - an object consisting of the following keys, all optional: - condition: regular expression or function (see previous point) - file: The file where the extracted comments will be stored. Can be either a string (filename) or function (string) -> string which will be given the original filename. Default is to append the suffix .LICENSE to the original filename. - banner: The banner text that points to the extracted file and will be added on top of the original file. will be added to the original file. Can be false (no banner), a string, or a function (string) -> string that will be called with the filename where extracted comments have been stored. Will be wrapped into comment. Default: /*! For license information please see foo.js.LICENSE */
2017-01-30 07:43:09 +08:00
"test4.js": {
source: function() {
return "/*! this comment should be extracted */ function foo(longVariableName) { /* this will not be extracted */ longVariableName = 1; } // another comment that should be extracted to a separate file\n function foo2(bar) { return bar; }";
},
map: function() {
return {
version: 3,
sources: ["test.js"],
names: ["foo", "longVariableName"],
mappings: "AAAA,QAASA,KAAIC,kBACTA,iBAAmB"
};
}
},
2017-01-29 00:32:56 +08:00
};
compilation.errors = [];
compilation.warnings = [];
eventBinding.handler(compilation);
compilationEventBindings = chunkPluginEnvironment.getEventBindings();
});
it("binds two event handler", function() {
compilationEventBindings.length.should.be.exactly(2);
});
describe("build-module handler", function() {
beforeEach(function() {
compilationEventBinding = compilationEventBindings[0];
});
it("binds to build-module event", function() {
compilationEventBinding.name.should.be.exactly("build-module");
});
it("sets the useSourceMap flag", function() {
const obj = {};
compilationEventBinding.handler(obj);
obj.useSourceMap.should.be.equal(true);
});
});
describe("optimize-chunk-assets handler", function() {
beforeEach(function() {
compilationEventBinding = compilationEventBindings[1];
});
it("binds to optimize-chunk-assets event", function() {
compilationEventBinding.name.should.be.exactly("optimize-chunk-assets");
});
it("outputs no errors for valid javascript", function() {
compilationEventBinding.handler([{
files: ["test.js"]
}], function() {
compilation.errors.length.should.be.exactly(0);
});
});
it("outputs SourceMapSource for valid javascript", function() {
compilationEventBinding.handler([{
files: ["test.js"]
}], function() {
compilation.assets["test.js"].should.be.instanceof(SourceMapSource);
});
});
it("does not output mangled javascript", function() {
compilationEventBinding.handler([{
files: ["test.js"]
}], function() {
compilation.assets["test.js"]._value.should.containEql("longVariableName");
});
});
it("outputs beautified javascript", function() {
compilationEventBinding.handler([{
files: ["test.js"]
}], function() {
compilation.assets["test.js"]._value.should.containEql("\n");
});
});
it("does not preserve comments", function() {
compilationEventBinding.handler([{
files: ["test.js"]
}], function() {
compilation.assets["test.js"]._value.should.not.containEql("/**");
});
});
it("outputs parsing errors", function() {
compilationEventBinding.handler([{
files: ["test1.js"]
}], function() {
compilation.errors.length.should.be.exactly(1);
compilation.errors[0].should.be.an.Error;
compilation.errors[0].message.should.containEql("[test1.js:1,0][test1.js:1,8]");
});
});
it("outputs warnings for unreachable code", function() {
compilationEventBinding.handler([{
files: ["test2.js"]
}], function() {
compilation.warnings.length.should.be.exactly(1);
compilation.warnings[0].should.be.an.Error;
compilation.warnings[0].message.should.containEql("Dropping unreachable code");
});
});
it("works with sourceAndMap assets as well", function() {
compilationEventBinding.handler([{
files: ["test3.js"]
}], function() {
compilation.errors.length.should.be.exactly(0);
compilation.assets["test3.js"].should.be.instanceof(SourceMapSource);
});
});
2017-02-04 22:37:21 +08:00
describe("with warningsFilter set", function() {
let compilationEventBindings, compilation;
describe("and the filter returns true", function() {
beforeEach(function() {
const pluginEnvironment = new PluginEnvironment();
const compilerEnv = pluginEnvironment.getEnvironmentStub();
compilerEnv.context = "";
const plugin = new UglifyJsPlugin({
warningsFilter: function() {
return true;
},
sourceMap: true,
compress: {
warnings: true,
},
mangle: false,
beautify: true,
comments: false
});
plugin.apply(compilerEnv);
const eventBindings = pluginEnvironment.getEventBindings();
const chunkPluginEnvironment = new PluginEnvironment();
compilation = chunkPluginEnvironment.getEnvironmentStub();
compilation.assets = {
"test2.js": {
source: function() {
return "function foo(x) { if (x) { return bar(); not_called1(); } }";
},
map: function() {
return {
version: 3,
sources: ["test1.js"],
names: ["foo", "x", "bar", "not_called1"],
mappings: "AAAA,QAASA,KAAIC,GACT,GAAIA,EAAG,CACH,MAAOC,MACPC"
};
}
},
};
compilation.errors = [];
compilation.warnings = [];
eventBindings[0].handler(compilation);
compilationEventBindings = chunkPluginEnvironment.getEventBindings();
});
it("should get all warnings", function() {
compilationEventBindings[1].handler([{
files: ["test2.js"]
}], function() {
compilation.warnings.length.should.be.exactly(1);
compilation.warnings[0].should.be.an.Error;
compilation.warnings[0].message.should.containEql("Dropping unreachable code");
});
});
});
describe("and the filter returns false", function() {
beforeEach(function() {
const pluginEnvironment = new PluginEnvironment();
const compilerEnv = pluginEnvironment.getEnvironmentStub();
compilerEnv.context = "";
const plugin = new UglifyJsPlugin({
warningsFilter: function() {
return false;
},
sourceMap: true,
compress: {
warnings: true,
},
mangle: false,
beautify: true,
comments: false
});
plugin.apply(compilerEnv);
const eventBindings = pluginEnvironment.getEventBindings();
const chunkPluginEnvironment = new PluginEnvironment();
compilation = chunkPluginEnvironment.getEnvironmentStub();
compilation.assets = {
"test2.js": {
source: function() {
return "function foo(x) { if (x) { return bar(); not_called1(); } }";
},
map: function() {
return {
version: 3,
sources: ["test1.js"],
names: ["foo", "x", "bar", "not_called1"],
mappings: "AAAA,QAASA,KAAIC,GACT,GAAIA,EAAG,CACH,MAAOC,MACPC"
};
}
},
};
compilation.errors = [];
compilation.warnings = [];
eventBindings[0].handler(compilation);
compilationEventBindings = chunkPluginEnvironment.getEventBindings();
});
it("should get no warnings", function() {
compilationEventBindings[1].handler([{
files: ["test2.js"]
}], function() {
compilation.warnings.length.should.be.exactly(0);
});
});
});
});
UglifyJsPlugin: extract comments to separate file License comments use up a lot of space, especially when using many small libraries with large license blocks. With this addition, you can extract all license comments to a separate file and remove them from the bundle files. A small banner points to the file containing all license information such that the user can find it if needed. We add a new option extractComments to the UglifyJsPlugin. It can be omitted, then the behavior does not change, or it can be: - true: All comments that normally would be preserved by the comments option will be moved to a separate file. If the original file is named foo.js, then the comments will be stored to foo.js.LICENSE - regular expression (given as RegExp or string) or a function (astNode, comment) -> boolean: All comments that match the given expression (resp. are evaluated to true by the function) will be extracted to the separate file. The comments option specifies whether the comment will be preserved, i.e. it is possible to preserve some comments (e.g. annotations) while extracting others or even preserving comments that have been extracted. - an object consisting of the following keys, all optional: - condition: regular expression or function (see previous point) - file: The file where the extracted comments will be stored. Can be either a string (filename) or function (string) -> string which will be given the original filename. Default is to append the suffix .LICENSE to the original filename. - banner: The banner text that points to the extracted file and will be added on top of the original file. will be added to the original file. Can be false (no banner), a string, or a function (string) -> string that will be called with the filename where extracted comments have been stored. Will be wrapped into comment. Default: /*! For license information please see foo.js.LICENSE */
2017-01-30 07:43:09 +08:00
it("extracts license information to separate file", function() {
compilationEventBinding.handler([{
files: ["test4.js"]
}], function() {
compilation.errors.length.should.be.exactly(0);
compilation.assets["test4.license.js"]._value.should.containEql("/*! this comment should be extracted */");
compilation.assets["test4.license.js"]._value.should.containEql("// another comment that should be extracted to a separate file");
compilation.assets["test4.license.js"]._value.should.not.containEql("/* this will not be extracted */");
});
});
});
});
});
});
describe("when applied with extract option set to a single file", function() {
let eventBindings;
let eventBinding;
beforeEach(function() {
const pluginEnvironment = new PluginEnvironment();
const compilerEnv = pluginEnvironment.getEnvironmentStub();
compilerEnv.context = "";
const plugin = new UglifyJsPlugin({
comments: "all",
extractComments: {
condition: /.*/,
2017-02-11 06:16:20 +08:00
filename: "extracted-comments.js"
UglifyJsPlugin: extract comments to separate file License comments use up a lot of space, especially when using many small libraries with large license blocks. With this addition, you can extract all license comments to a separate file and remove them from the bundle files. A small banner points to the file containing all license information such that the user can find it if needed. We add a new option extractComments to the UglifyJsPlugin. It can be omitted, then the behavior does not change, or it can be: - true: All comments that normally would be preserved by the comments option will be moved to a separate file. If the original file is named foo.js, then the comments will be stored to foo.js.LICENSE - regular expression (given as RegExp or string) or a function (astNode, comment) -> boolean: All comments that match the given expression (resp. are evaluated to true by the function) will be extracted to the separate file. The comments option specifies whether the comment will be preserved, i.e. it is possible to preserve some comments (e.g. annotations) while extracting others or even preserving comments that have been extracted. - an object consisting of the following keys, all optional: - condition: regular expression or function (see previous point) - file: The file where the extracted comments will be stored. Can be either a string (filename) or function (string) -> string which will be given the original filename. Default is to append the suffix .LICENSE to the original filename. - banner: The banner text that points to the extracted file and will be added on top of the original file. will be added to the original file. Can be false (no banner), a string, or a function (string) -> string that will be called with the filename where extracted comments have been stored. Will be wrapped into comment. Default: /*! For license information please see foo.js.LICENSE */
2017-01-30 07:43:09 +08:00
}
});
plugin.apply(compilerEnv);
eventBindings = pluginEnvironment.getEventBindings();
});
it("binds one event handler", function() {
eventBindings.length.should.be.exactly(1);
});
describe("compilation handler", function() {
beforeEach(function() {
eventBinding = eventBindings[0];
});
it("binds to compilation event", function() {
eventBinding.name.should.be.exactly("compilation");
});
describe("when called", function() {
let chunkPluginEnvironment;
let compilationEventBindings;
let compilationEventBinding;
let compilation;
beforeEach(function() {
chunkPluginEnvironment = new PluginEnvironment();
compilation = chunkPluginEnvironment.getEnvironmentStub();
compilation.assets = {
"test.js": {
source: function() {
return "/* This is a comment from test.js */ function foo(bar) { return bar; }";
}
},
"test2.js": {
source: function() {
return "// This is a comment from test2.js\nfunction foo2(bar) { return bar; }";
}
},
"test3.js": {
source: function() {
return "/* 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", function() {
compilationEventBindings.length.should.be.exactly(1);
});
describe("optimize-chunk-assets handler", function() {
beforeEach(function() {
compilationEventBinding = compilationEventBindings[0];
});
it("preserves comments", function() {
compilationEventBinding.handler([{
files: ["test.js", "test2.js", "test3.js"]
}], function() {
compilation.assets["test.js"].source().should.containEql("/*");
compilation.assets["test2.js"].source().should.containEql("//");
compilation.assets["test3.js"].source().should.containEql("/*");
compilation.assets["test3.js"].source().should.containEql("//");
});
});
it("extracts comments to specified file", function() {
compilationEventBinding.handler([{
files: ["test.js", "test2.js", "test3.js"]
}], function() {
compilation.errors.length.should.be.exactly(0);
compilation.assets["extracted-comments.js"].source().should.containEql("/* This is a comment from test.js */");
compilation.assets["extracted-comments.js"].source().should.containEql("// This is a comment from test2.js");
compilation.assets["extracted-comments.js"].source().should.containEql("/* This is a comment from test3.js */");
compilation.assets["extracted-comments.js"].source().should.containEql("// This is another comment from test3.js");
compilation.assets["extracted-comments.js"].source().should.not.containEql("function");
});
});
2017-01-29 00:32:56 +08:00
});
});
});
});
});