mirror of https://github.com/webpack/webpack.git
Merge branch 'master' into feature/main-template-type-support
This commit is contained in:
commit
4d614981b4
|
|
@ -0,0 +1,9 @@
|
|||
# Reporting Security Issues
|
||||
|
||||
If you discover a security issue in webpack, please report it by sending an
|
||||
email to [webpack@opencollective.com](mailto:webpack@opencollective.com).
|
||||
|
||||
This will allow us to assess the risk, and make a fix available before we add a
|
||||
bug report to the GitHub repository.
|
||||
|
||||
Thanks for helping make webpack safe for everyone.
|
||||
|
|
@ -9,25 +9,23 @@ declare namespace NodeJS {
|
|||
}
|
||||
|
||||
// There are no typings for chrome-trace-event
|
||||
declare module 'chrome-trace-event' {
|
||||
declare module "chrome-trace-event" {
|
||||
interface Event {
|
||||
name: string
|
||||
id?: number
|
||||
cat: string[]
|
||||
args?: Object
|
||||
name: string;
|
||||
id?: number;
|
||||
cat: string[];
|
||||
args?: Object;
|
||||
}
|
||||
|
||||
export class Tracer {
|
||||
constructor(options: {
|
||||
noStream: boolean
|
||||
})
|
||||
pipe(stream: NodeJS.WritableStream) : void
|
||||
instantEvent(event: Event) : void
|
||||
counter: number
|
||||
constructor(options: { noStream: boolean });
|
||||
pipe(stream: NodeJS.WritableStream): void;
|
||||
instantEvent(event: Event): void;
|
||||
counter: number;
|
||||
trace: {
|
||||
begin(event: Event) : void
|
||||
end(event: Event) : void
|
||||
}
|
||||
begin(event: Event): void;
|
||||
end(event: Event): void;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
77
lib/Stats.js
77
lib/Stats.js
|
|
@ -100,7 +100,9 @@ class Stats {
|
|||
const optionOrLocalFallback = (v, def) =>
|
||||
typeof v !== "undefined"
|
||||
? v
|
||||
: typeof options.all !== "undefined" ? options.all : def;
|
||||
: typeof options.all !== "undefined"
|
||||
? options.all
|
||||
: def;
|
||||
|
||||
const testAgainstGivenOption = item => {
|
||||
if (typeof item === "string") {
|
||||
|
|
@ -135,6 +137,10 @@ class Stats {
|
|||
const showBuiltAt = optionOrLocalFallback(options.builtAt, true);
|
||||
const showAssets = optionOrLocalFallback(options.assets, true);
|
||||
const showEntrypoints = optionOrLocalFallback(options.entrypoints, true);
|
||||
const showChunkGroups = optionOrLocalFallback(
|
||||
options.chunkGroups,
|
||||
!forToString
|
||||
);
|
||||
const showChunks = optionOrLocalFallback(options.chunks, !forToString);
|
||||
const showChunkModules = optionOrLocalFallback(options.chunkModules, true);
|
||||
const showChunkOrigins = optionOrLocalFallback(
|
||||
|
|
@ -262,7 +268,9 @@ class Stats {
|
|||
text += `chunk ${e.chunk.name || e.chunk.id}${
|
||||
e.chunk.hasRuntime()
|
||||
? " [entry]"
|
||||
: e.chunk.canBeInitial() ? " [initial]" : ""
|
||||
: e.chunk.canBeInitial()
|
||||
? " [initial]"
|
||||
: ""
|
||||
}\n`;
|
||||
}
|
||||
if (e.file) {
|
||||
|
|
@ -396,15 +404,15 @@ class Stats {
|
|||
obj.assets.sort(sortByField(sortAssets));
|
||||
}
|
||||
|
||||
if (showEntrypoints) {
|
||||
obj.entrypoints = {};
|
||||
for (const keyValuePair of compilation.entrypoints) {
|
||||
const fnChunkGroup = groupMap => {
|
||||
const obj = {};
|
||||
for (const keyValuePair of groupMap) {
|
||||
const name = keyValuePair[0];
|
||||
const ep = keyValuePair[1];
|
||||
const children = ep.getChildrenByOrders();
|
||||
obj.entrypoints[name] = {
|
||||
chunks: ep.chunks.map(c => c.id),
|
||||
assets: ep.chunks.reduce(
|
||||
const cg = keyValuePair[1];
|
||||
const children = cg.getChildrenByOrders();
|
||||
obj[name] = {
|
||||
chunks: cg.chunks.map(c => c.id),
|
||||
assets: cg.chunks.reduce(
|
||||
(array, c) => array.concat(c.files || []),
|
||||
[]
|
||||
),
|
||||
|
|
@ -436,9 +444,19 @@ class Stats {
|
|||
}, Object.create(null))
|
||||
};
|
||||
if (showPerformance) {
|
||||
obj.entrypoints[name].isOverSizeLimit = ep.isOverSizeLimit;
|
||||
obj[name].isOverSizeLimit = cg.isOverSizeLimit;
|
||||
}
|
||||
}
|
||||
|
||||
return obj;
|
||||
};
|
||||
|
||||
if (showEntrypoints) {
|
||||
obj.entrypoints = fnChunkGroup(compilation.entrypoints);
|
||||
}
|
||||
|
||||
if (showChunkGroups) {
|
||||
obj.namedChunkGroups = fnChunkGroup(compilation.namedChunkGroups);
|
||||
}
|
||||
|
||||
const fnModule = module => {
|
||||
|
|
@ -866,22 +884,23 @@ class Stats {
|
|||
colors.normal(obj.filteredAssets !== 1 ? " assets" : " asset");
|
||||
newline();
|
||||
}
|
||||
if (obj.entrypoints) {
|
||||
for (const name of Object.keys(obj.entrypoints)) {
|
||||
const ep = obj.entrypoints[name];
|
||||
colors.normal("Entrypoint ");
|
||||
|
||||
const processChunkGroups = (namedGroups, prefix) => {
|
||||
for (const name of Object.keys(namedGroups)) {
|
||||
const cg = namedGroups[name];
|
||||
colors.normal(`${prefix} `);
|
||||
colors.bold(name);
|
||||
if (ep.isOverSizeLimit) {
|
||||
if (cg.isOverSizeLimit) {
|
||||
colors.normal(" ");
|
||||
colors.yellow("[big]");
|
||||
}
|
||||
colors.normal(" =");
|
||||
for (const asset of ep.assets) {
|
||||
for (const asset of cg.assets) {
|
||||
colors.normal(" ");
|
||||
colors.green(asset);
|
||||
}
|
||||
for (const name of Object.keys(ep.childAssets)) {
|
||||
const assets = ep.childAssets[name];
|
||||
for (const name of Object.keys(cg.childAssets)) {
|
||||
const assets = cg.childAssets[name];
|
||||
if (assets && assets.length > 0) {
|
||||
colors.normal(" ");
|
||||
colors.magenta(`(${name}:`);
|
||||
|
|
@ -894,7 +913,25 @@ class Stats {
|
|||
}
|
||||
newline();
|
||||
}
|
||||
};
|
||||
|
||||
if (obj.entrypoints) {
|
||||
processChunkGroups(obj.entrypoints, "Entrypoint");
|
||||
}
|
||||
|
||||
if (obj.namedChunkGroups) {
|
||||
let outputChunkGroups = obj.namedChunkGroups;
|
||||
if (obj.entrypoints) {
|
||||
outputChunkGroups = Object.keys(outputChunkGroups)
|
||||
.filter(name => !obj.entrypoints[name])
|
||||
.reduce((result, name) => {
|
||||
result[name] = obj.namedChunkGroups[name];
|
||||
return result;
|
||||
}, {});
|
||||
}
|
||||
processChunkGroups(outputChunkGroups, "Chunk Group");
|
||||
}
|
||||
|
||||
const modulesByIdentifier = {};
|
||||
if (obj.modules) {
|
||||
for (const module of obj.modules) {
|
||||
|
|
@ -1260,6 +1297,7 @@ class Stats {
|
|||
case "verbose":
|
||||
return {
|
||||
entrypoints: true,
|
||||
chunkGroups: true,
|
||||
modules: false,
|
||||
chunks: true,
|
||||
chunkModules: true,
|
||||
|
|
@ -1278,6 +1316,7 @@ class Stats {
|
|||
case "detailed":
|
||||
return {
|
||||
entrypoints: true,
|
||||
chunkGroups: true,
|
||||
chunks: true,
|
||||
chunkModules: false,
|
||||
chunkOrigins: true,
|
||||
|
|
|
|||
|
|
@ -235,7 +235,9 @@ class WebpackOptionsApply extends OptionsApply {
|
|||
"MappingURL=[url]\n*/"
|
||||
: legacy
|
||||
? "\n/*\n//@ source" + "MappingURL=[url]\n*/"
|
||||
: modern ? "\n//# source" + "MappingURL=[url]" : null;
|
||||
: modern
|
||||
? "\n//# source" + "MappingURL=[url]"
|
||||
: null;
|
||||
let Plugin = evalWrapped
|
||||
? EvalSourceMapDevToolPlugin
|
||||
: SourceMapDevToolPlugin;
|
||||
|
|
@ -259,7 +261,9 @@ class WebpackOptionsApply extends OptionsApply {
|
|||
? "\n//@ sourceURL=[url]\n//# sourceURL=[url]"
|
||||
: legacy
|
||||
? "\n//@ sourceURL=[url]"
|
||||
: modern ? "\n//# sourceURL=[url]" : null;
|
||||
: modern
|
||||
? "\n//# sourceURL=[url]"
|
||||
: null;
|
||||
new EvalDevToolModulePlugin({
|
||||
sourceUrlComment: comment,
|
||||
moduleFilenameTemplate: options.output.devtoolModuleFilenameTemplate,
|
||||
|
|
|
|||
|
|
@ -33,6 +33,23 @@ class ImportParserPlugin {
|
|||
|
||||
const importOptions = parser.getCommentOptions(expr.range);
|
||||
if (importOptions) {
|
||||
if (typeof importOptions.webpackIgnore !== "undefined") {
|
||||
if (typeof importOptions.webpackIgnore !== "boolean") {
|
||||
parser.state.module.warnings.push(
|
||||
new UnsupportedFeatureWarning(
|
||||
parser.state.module,
|
||||
`\`webpackIgnore\` expected a boolean, but received: ${
|
||||
importOptions.webpackIgnore
|
||||
}.`
|
||||
)
|
||||
);
|
||||
} else {
|
||||
// Do not instrument `import()` is `webpackIgnore` is `true`
|
||||
if (importOptions.webpackIgnore) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (typeof importOptions.webpackChunkName !== "undefined") {
|
||||
if (typeof importOptions.webpackChunkName !== "string") {
|
||||
parser.state.module.warnings.push(
|
||||
|
|
|
|||
|
|
@ -291,11 +291,15 @@ module.exports = class SplitChunksPlugin {
|
|||
minSize:
|
||||
cacheGroupSource.minSize !== undefined
|
||||
? cacheGroupSource.minSize
|
||||
: cacheGroupSource.enforce ? 0 : this.options.minSize,
|
||||
: cacheGroupSource.enforce
|
||||
? 0
|
||||
: this.options.minSize,
|
||||
minChunks:
|
||||
cacheGroupSource.minChunks !== undefined
|
||||
? cacheGroupSource.minChunks
|
||||
: cacheGroupSource.enforce ? 1 : this.options.minChunks,
|
||||
: cacheGroupSource.enforce
|
||||
? 1
|
||||
: this.options.minChunks,
|
||||
maxAsyncRequests:
|
||||
cacheGroupSource.maxAsyncRequests !== undefined
|
||||
? cacheGroupSource.maxAsyncRequests
|
||||
|
|
|
|||
|
|
@ -88,7 +88,8 @@
|
|||
"buildin/",
|
||||
"hot/",
|
||||
"web_modules/",
|
||||
"schemas/"
|
||||
"schemas/",
|
||||
"SECURITY.md"
|
||||
],
|
||||
"scripts": {
|
||||
"setup": "node ./setup/setup.js",
|
||||
|
|
|
|||
|
|
@ -1853,6 +1853,10 @@
|
|||
"type": "boolean",
|
||||
"description": "Display the entry points with the corresponding bundles"
|
||||
},
|
||||
"chunkGroups": {
|
||||
"type": "boolean",
|
||||
"description": "Display all chunk groups with the corresponding bundles"
|
||||
},
|
||||
"errorDetails": {
|
||||
"type": "boolean",
|
||||
"description": "add details to errors (like resolving log)"
|
||||
|
|
|
|||
|
|
@ -8,9 +8,8 @@ const Chunk = require("../lib/Chunk");
|
|||
describe("Chunk", () => {
|
||||
let ChunkInstance;
|
||||
|
||||
beforeEach(
|
||||
() => (ChunkInstance = new Chunk("chunk-test", "module-test", "loc-test"))
|
||||
);
|
||||
beforeEach(() =>
|
||||
(ChunkInstance = new Chunk("chunk-test", "module-test", "loc-test")));
|
||||
|
||||
it("should have debugId more than 999", () =>
|
||||
should(ChunkInstance.debugId).be.above(999));
|
||||
|
|
|
|||
|
|
@ -33,9 +33,8 @@ describe("NullDependency", () => {
|
|||
it("is a function", () => NullDependency.Template.should.be.a.Function());
|
||||
|
||||
describe("when created", () => {
|
||||
beforeEach(
|
||||
() => (env.nullDependencyTemplate = new NullDependency.Template())
|
||||
);
|
||||
beforeEach(() =>
|
||||
(env.nullDependencyTemplate = new NullDependency.Template()));
|
||||
|
||||
it("has apply function", () =>
|
||||
env.nullDependencyTemplate.apply.should.be.Function());
|
||||
|
|
|
|||
|
|
@ -11,32 +11,28 @@ describe("SourceMapDevToolModuleOptionsPlugin", () => {
|
|||
beforeEach(() => (eventBindings = undefined));
|
||||
|
||||
describe("with module false and line-to-line false", () => {
|
||||
beforeEach(
|
||||
() =>
|
||||
(eventBindings = applyPluginWithOptions(
|
||||
SourceMapDevToolModuleOptionsPlugin,
|
||||
{
|
||||
module: false,
|
||||
lineToLine: false
|
||||
}
|
||||
))
|
||||
);
|
||||
beforeEach(() =>
|
||||
(eventBindings = applyPluginWithOptions(
|
||||
SourceMapDevToolModuleOptionsPlugin,
|
||||
{
|
||||
module: false,
|
||||
lineToLine: false
|
||||
}
|
||||
)));
|
||||
|
||||
it("does not bind any event handlers", () =>
|
||||
eventBindings.length.should.be.exactly(0));
|
||||
});
|
||||
|
||||
describe("with module true", () => {
|
||||
beforeEach(
|
||||
() =>
|
||||
(eventBindings = applyPluginWithOptions(
|
||||
SourceMapDevToolModuleOptionsPlugin,
|
||||
{
|
||||
module: true,
|
||||
lineToLine: false
|
||||
}
|
||||
))
|
||||
);
|
||||
beforeEach(() =>
|
||||
(eventBindings = applyPluginWithOptions(
|
||||
SourceMapDevToolModuleOptionsPlugin,
|
||||
{
|
||||
module: true,
|
||||
lineToLine: false
|
||||
}
|
||||
)));
|
||||
|
||||
it("binds one event handler", () =>
|
||||
eventBindings.length.should.be.exactly(1));
|
||||
|
|
@ -56,16 +52,14 @@ describe("SourceMapDevToolModuleOptionsPlugin", () => {
|
|||
});
|
||||
|
||||
describe("with line-to-line true", () => {
|
||||
beforeEach(
|
||||
() =>
|
||||
(eventBindings = applyPluginWithOptions(
|
||||
SourceMapDevToolModuleOptionsPlugin,
|
||||
{
|
||||
module: false,
|
||||
lineToLine: true
|
||||
}
|
||||
))
|
||||
);
|
||||
beforeEach(() =>
|
||||
(eventBindings = applyPluginWithOptions(
|
||||
SourceMapDevToolModuleOptionsPlugin,
|
||||
{
|
||||
module: false,
|
||||
lineToLine: true
|
||||
}
|
||||
)));
|
||||
|
||||
it("binds one event handler", () =>
|
||||
eventBindings.length.should.be.exactly(1));
|
||||
|
|
@ -85,16 +79,14 @@ describe("SourceMapDevToolModuleOptionsPlugin", () => {
|
|||
});
|
||||
|
||||
describe("with line-to-line object", () => {
|
||||
beforeEach(
|
||||
() =>
|
||||
(eventBindings = applyPluginWithOptions(
|
||||
SourceMapDevToolModuleOptionsPlugin,
|
||||
{
|
||||
module: false,
|
||||
lineToLine: {}
|
||||
}
|
||||
))
|
||||
);
|
||||
beforeEach(() =>
|
||||
(eventBindings = applyPluginWithOptions(
|
||||
SourceMapDevToolModuleOptionsPlugin,
|
||||
{
|
||||
module: false,
|
||||
lineToLine: {}
|
||||
}
|
||||
)));
|
||||
|
||||
it("binds one event handler", () =>
|
||||
eventBindings.length.should.be.exactly(1));
|
||||
|
|
|
|||
|
|
@ -116,6 +116,7 @@ describe(
|
|||
warnings: [],
|
||||
assets: [],
|
||||
entrypoints: new Map(),
|
||||
namedChunkGroups: new Map(),
|
||||
chunks: [],
|
||||
modules: [],
|
||||
children: [],
|
||||
|
|
@ -142,6 +143,7 @@ describe(
|
|||
assets: [],
|
||||
entrypoints: new Map(),
|
||||
chunks: [],
|
||||
namedChunkGroups: new Map(),
|
||||
modules: [],
|
||||
children: [],
|
||||
hash: "1234",
|
||||
|
|
@ -162,6 +164,7 @@ describe(
|
|||
children: [],
|
||||
chunks: [],
|
||||
entrypoints: {},
|
||||
namedChunkGroups: {},
|
||||
filteredAssets: 0,
|
||||
filteredModules: 0,
|
||||
errors: [],
|
||||
|
|
|
|||
|
|
@ -0,0 +1,9 @@
|
|||
const fs = require("fs");
|
||||
const path = require("path");
|
||||
const should = require("should");
|
||||
|
||||
it("should be able to ignore import()", () => {
|
||||
const source = fs.readFileSync(path.join(__dirname, "bundle1.js"), "utf-8");
|
||||
should(source).containEql(`import(/* webpackIgnore: true */ "./other2.js")`);
|
||||
should(source).not.containEql(`import(/* webpackIgnore: false */ "./other3.js")`);
|
||||
});
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
import(/* webpackIgnore: true */ "./other2.js");
|
||||
import(/* webpackIgnore: false */ "./other3.js");
|
||||
|
|
@ -0,0 +1 @@
|
|||
export default "other2";
|
||||
|
|
@ -0,0 +1 @@
|
|||
export default "other3";
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
module.exports = {
|
||||
entry: {
|
||||
bundle0: "./index.js",
|
||||
bundle1: "./other.js"
|
||||
},
|
||||
output: {
|
||||
filename: "[name].js"
|
||||
},
|
||||
node: {
|
||||
__dirname: false
|
||||
}
|
||||
};
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
import "./shared";
|
||||
|
||||
export default "a";
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
import "./shared";
|
||||
|
||||
export default "b";
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
import "x";
|
||||
import "y";
|
||||
|
||||
export default "c";
|
||||
|
|
@ -0,0 +1,50 @@
|
|||
Child
|
||||
Chunk Group main = main.js
|
||||
Chunk Group async-a = async-a~async-b.js async-a.js
|
||||
Chunk Group async-b = async-a~async-b.js async-b.js
|
||||
Chunk Group async-c = vendors.js async-c.js
|
||||
chunk {0} async-a~async-b.js (async-a~async-b) 133 bytes <{5}> ={1}= ={2}= [rendered] split chunk (cache group: default) (name: async-a~async-b)
|
||||
> ./a [6] ./index.js 1:0-47
|
||||
> ./b [6] ./index.js 2:0-47
|
||||
[0] ./shared.js 133 bytes {0} [built]
|
||||
chunk {1} async-a.js (async-a) 40 bytes <{5}> ={0}= [rendered]
|
||||
> ./a [6] ./index.js 1:0-47
|
||||
[3] ./a.js 40 bytes {1} [built]
|
||||
chunk {2} async-b.js (async-b) 40 bytes <{5}> ={0}= [rendered]
|
||||
> ./b [6] ./index.js 2:0-47
|
||||
[4] ./b.js 40 bytes {2} [built]
|
||||
chunk {3} async-c.js (async-c) 45 bytes <{5}> ={4}= [rendered]
|
||||
> ./c [6] ./index.js 3:0-47
|
||||
[5] ./c.js 45 bytes {3} [built]
|
||||
chunk {4} vendors.js (vendors) 40 bytes <{5}> ={3}= [rendered] split chunk (cache group: vendors) (name: vendors)
|
||||
> ./c [6] ./index.js 3:0-47
|
||||
[1] ./node_modules/x.js 20 bytes {4} [built]
|
||||
[2] ./node_modules/y.js 20 bytes {4} [built]
|
||||
chunk {5} main.js (main) 146 bytes >{0}< >{1}< >{2}< >{3}< >{4}< [entry] [rendered]
|
||||
> ./ main
|
||||
[6] ./index.js 146 bytes {5} [built]
|
||||
Child
|
||||
Entrypoint main = main.js
|
||||
Chunk Group async-a = async-a~async-b.js async-a.js
|
||||
Chunk Group async-b = async-a~async-b.js async-b.js
|
||||
Chunk Group async-c = vendors.js async-c.js
|
||||
chunk {0} async-a~async-b.js (async-a~async-b) 133 bytes <{5}> ={1}= ={2}= [rendered] split chunk (cache group: default) (name: async-a~async-b)
|
||||
> ./a [6] ./index.js 1:0-47
|
||||
> ./b [6] ./index.js 2:0-47
|
||||
[0] ./shared.js 133 bytes {0} [built]
|
||||
chunk {1} async-a.js (async-a) 40 bytes <{5}> ={0}= [rendered]
|
||||
> ./a [6] ./index.js 1:0-47
|
||||
[3] ./a.js 40 bytes {1} [built]
|
||||
chunk {2} async-b.js (async-b) 40 bytes <{5}> ={0}= [rendered]
|
||||
> ./b [6] ./index.js 2:0-47
|
||||
[4] ./b.js 40 bytes {2} [built]
|
||||
chunk {3} async-c.js (async-c) 45 bytes <{5}> ={4}= [rendered]
|
||||
> ./c [6] ./index.js 3:0-47
|
||||
[5] ./c.js 45 bytes {3} [built]
|
||||
chunk {4} vendors.js (vendors) 40 bytes <{5}> ={3}= [rendered] split chunk (cache group: vendors) (name: vendors)
|
||||
> ./c [6] ./index.js 3:0-47
|
||||
[1] ./node_modules/x.js 20 bytes {4} [built]
|
||||
[2] ./node_modules/y.js 20 bytes {4} [built]
|
||||
chunk {5} main.js (main) 146 bytes >{0}< >{1}< >{2}< >{3}< >{4}< [entry] [rendered]
|
||||
> ./ main
|
||||
[6] ./index.js 146 bytes {5} [built]
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
import(/* webpackChunkName: "async-a" */ "./a");
|
||||
import(/* webpackChunkName: "async-b" */ "./b");
|
||||
import(/* webpackChunkName: "async-c" */ "./c");
|
||||
|
|
@ -0,0 +1 @@
|
|||
export default "x";
|
||||
|
|
@ -0,0 +1 @@
|
|||
export default "y";
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
// content content content content content content content content
|
||||
// content content content content content content content content
|
||||
|
|
@ -0,0 +1,47 @@
|
|||
const stats = {
|
||||
hash: false,
|
||||
timings: false,
|
||||
builtAt: false,
|
||||
assets: false,
|
||||
chunks: true,
|
||||
chunkOrigins: true,
|
||||
modules: false
|
||||
};
|
||||
|
||||
const config = {
|
||||
mode: "production",
|
||||
entry: {
|
||||
main: "./"
|
||||
},
|
||||
output: {
|
||||
filename: "[name].js"
|
||||
},
|
||||
optimization: {
|
||||
splitChunks: {
|
||||
minSize: 100,
|
||||
cacheGroups: {
|
||||
vendors: {
|
||||
test: /[\\/]node_modules[\\/]/,
|
||||
chunks: "async",
|
||||
enforce: true,
|
||||
name: "vendors"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
module.exports = [
|
||||
Object.assign(
|
||||
{
|
||||
stats: Object.assign({ entrypoints: false, chunkGroups: true }, stats)
|
||||
},
|
||||
config
|
||||
),
|
||||
Object.assign(
|
||||
{
|
||||
stats: Object.assign({ entrypoints: true, chunkGroups: true }, stats)
|
||||
},
|
||||
config
|
||||
)
|
||||
];
|
||||
Loading…
Reference in New Issue