mirror of https://github.com/webpack/webpack.git
Smaller performance improvements in NormalModuleFactory
This commit is contained in:
parent
526bc7a788
commit
90baf475af
|
|
@ -808,6 +808,12 @@ class Compilation {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (sortedDependencies.length === 0) {
|
||||||
|
callback();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
process.nextTick(() => {
|
||||||
// This is nested so we need to allow one additional task
|
// This is nested so we need to allow one additional task
|
||||||
this.processDependenciesQueue.increaseParallelism();
|
this.processDependenciesQueue.increaseParallelism();
|
||||||
|
|
||||||
|
|
@ -839,6 +845,7 @@ class Compilation {
|
||||||
return callback(err);
|
return callback(err);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -566,6 +566,7 @@ class Compiler {
|
||||||
this.hooks.make.callAsync(compilation, err => {
|
this.hooks.make.callAsync(compilation, err => {
|
||||||
if (err) return callback(err);
|
if (err) return callback(err);
|
||||||
|
|
||||||
|
process.nextTick(() => {
|
||||||
compilation.finish(err => {
|
compilation.finish(err => {
|
||||||
if (err) return callback(err);
|
if (err) return callback(err);
|
||||||
|
|
||||||
|
|
@ -581,6 +582,7 @@ class Compiler {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -58,6 +58,14 @@ const loaderToIdent = data => {
|
||||||
return data.loader + "?" + JSON.stringify(data.options);
|
return data.loader + "?" + JSON.stringify(data.options);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const stringifyLoadersAndResource = (loaders, resource) => {
|
||||||
|
let str = "";
|
||||||
|
for (const loader of loaders) {
|
||||||
|
str += loaderToIdent(loader) + "!";
|
||||||
|
}
|
||||||
|
return str + resource;
|
||||||
|
};
|
||||||
|
|
||||||
const identToLoaderRequest = resultString => {
|
const identToLoaderRequest = resultString => {
|
||||||
const idx = resultString.indexOf("?");
|
const idx = resultString.indexOf("?");
|
||||||
if (idx >= 0) {
|
if (idx >= 0) {
|
||||||
|
|
@ -75,6 +83,18 @@ const identToLoaderRequest = resultString => {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const needCalls = (times, callback) => {
|
||||||
|
return err => {
|
||||||
|
if (--times === 0) {
|
||||||
|
return callback(err);
|
||||||
|
}
|
||||||
|
if (err && times > 0) {
|
||||||
|
times = NaN;
|
||||||
|
return callback(err);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
// TODO webpack 6 remove
|
// TODO webpack 6 remove
|
||||||
const deprecationChangedHookMessage = name =>
|
const deprecationChangedHookMessage = name =>
|
||||||
`NormalModuleFactory.${name} is no longer a waterfall hook, but a bailing hook instead. ` +
|
`NormalModuleFactory.${name} is no longer a waterfall hook, but a bailing hook instead. ` +
|
||||||
|
|
@ -196,25 +216,33 @@ class NormalModuleFactory extends ModuleFactory {
|
||||||
const matchResourceMatch = MATCH_RESOURCE_REGEX.exec(request);
|
const matchResourceMatch = MATCH_RESOURCE_REGEX.exec(request);
|
||||||
if (matchResourceMatch) {
|
if (matchResourceMatch) {
|
||||||
matchResource = matchResourceMatch[1];
|
matchResource = matchResourceMatch[1];
|
||||||
if (/^\.\.?\//.test(matchResource)) {
|
if (matchResource.charCodeAt(0) === 46) {
|
||||||
|
// 46 === ".", 47 === "/"
|
||||||
|
const secondChar = matchResource.charCodeAt(1);
|
||||||
|
if (
|
||||||
|
secondChar === 47 ||
|
||||||
|
(secondChar === 46 && matchResource.charCodeAt(2) === 47)
|
||||||
|
) {
|
||||||
|
// if matchResources startsWith ../ or ./
|
||||||
matchResource = path.join(context, matchResource);
|
matchResource = path.join(context, matchResource);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
requestWithoutMatchResource = request.substr(
|
requestWithoutMatchResource = request.substr(
|
||||||
matchResourceMatch[0].length
|
matchResourceMatch[0].length
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const noPreAutoLoaders = requestWithoutMatchResource.startsWith("-!");
|
const firstChar = requestWithoutMatchResource.charCodeAt(0);
|
||||||
const noAutoLoaders =
|
const secondChar = requestWithoutMatchResource.charCodeAt(1);
|
||||||
noPreAutoLoaders || requestWithoutMatchResource.startsWith("!");
|
const noPreAutoLoaders = firstChar === 45 && secondChar === 33; // startsWith "-!"
|
||||||
const noPrePostAutoLoaders = requestWithoutMatchResource.startsWith(
|
const noAutoLoaders = noPreAutoLoaders || firstChar === 33; // startsWith "!"
|
||||||
"!!"
|
const noPrePostAutoLoaders = firstChar === 33 && secondChar === 33; // startsWith "!!";
|
||||||
);
|
|
||||||
const rawElements = requestWithoutMatchResource
|
const rawElements = requestWithoutMatchResource
|
||||||
.replace(/^-?!+/, "")
|
.slice(
|
||||||
.replace(/!!+/g, "!")
|
noPreAutoLoaders || noPrePostAutoLoaders ? 2 : noAutoLoaders ? 1 : 0
|
||||||
.split("!");
|
)
|
||||||
const resource = rawElements.pop();
|
.split(/!+/);
|
||||||
|
const unresolvedResource = rawElements.pop();
|
||||||
const elements = rawElements.map(identToLoaderRequest);
|
const elements = rawElements.map(identToLoaderRequest);
|
||||||
|
|
||||||
const resolveContext = {
|
const resolveContext = {
|
||||||
|
|
@ -224,58 +252,18 @@ class NormalModuleFactory extends ModuleFactory {
|
||||||
contextDependencies
|
contextDependencies
|
||||||
};
|
};
|
||||||
|
|
||||||
asyncLib.parallel(
|
/** @type {string | false} */
|
||||||
[
|
let resource;
|
||||||
callback =>
|
let resourceResolveData;
|
||||||
this.resolveRequestArray(
|
let loaders;
|
||||||
contextInfo,
|
|
||||||
context,
|
|
||||||
elements,
|
|
||||||
loaderResolver,
|
|
||||||
resolveContext,
|
|
||||||
callback
|
|
||||||
),
|
|
||||||
callback => {
|
|
||||||
if (resource === "" || resource[0] === "?") {
|
|
||||||
return callback(null, {
|
|
||||||
resource
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
normalResolver.resolve(
|
const continueCallback = needCalls(2, err => {
|
||||||
contextInfo,
|
|
||||||
context,
|
|
||||||
resource,
|
|
||||||
resolveContext,
|
|
||||||
(err, resource, resourceResolveData) => {
|
|
||||||
if (err) return callback(err);
|
if (err) return callback(err);
|
||||||
|
|
||||||
// TODO remove this when enhanced-resolve supports fileDependencies
|
|
||||||
if (resource) {
|
|
||||||
fileDependencies.add(resource);
|
|
||||||
}
|
|
||||||
|
|
||||||
callback(null, {
|
|
||||||
resourceResolveData,
|
|
||||||
resource
|
|
||||||
});
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
],
|
|
||||||
(err, results) => {
|
|
||||||
if (err) return callback(err);
|
|
||||||
let loaders = results[0];
|
|
||||||
const resourceResolveData = results[1].resourceResolveData;
|
|
||||||
const resource = results[1].resource;
|
|
||||||
|
|
||||||
// translate option idents
|
// translate option idents
|
||||||
try {
|
try {
|
||||||
for (const item of loaders) {
|
for (const item of loaders) {
|
||||||
if (
|
if (typeof item.options === "string" && item.options[0] === "?") {
|
||||||
typeof item.options === "string" &&
|
|
||||||
item.options[0] === "?"
|
|
||||||
) {
|
|
||||||
const ident = item.options.substr(1);
|
const ident = item.options.substr(1);
|
||||||
item.options = this.ruleSet.findOptionsByIdent(ident);
|
item.options = this.ruleSet.findOptionsByIdent(ident);
|
||||||
item.ident = ident;
|
item.ident = ident;
|
||||||
|
|
@ -299,10 +287,7 @@ class NormalModuleFactory extends ModuleFactory {
|
||||||
|
|
||||||
const userRequest =
|
const userRequest =
|
||||||
(matchResource !== undefined ? `${matchResource}!=!` : "") +
|
(matchResource !== undefined ? `${matchResource}!=!` : "") +
|
||||||
loaders
|
stringifyLoadersAndResource(loaders, resource);
|
||||||
.map(loaderToIdent)
|
|
||||||
.concat([resource])
|
|
||||||
.join("!");
|
|
||||||
|
|
||||||
let resourcePath =
|
let resourcePath =
|
||||||
matchResource !== undefined ? matchResource : resource;
|
matchResource !== undefined ? matchResource : resource;
|
||||||
|
|
@ -355,48 +340,24 @@ class NormalModuleFactory extends ModuleFactory {
|
||||||
settings[r.type] = r.value;
|
settings[r.type] = r.value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
asyncLib.parallel(
|
|
||||||
[
|
let postLoaders, normalLoaders, preLoaders;
|
||||||
this.resolveRequestArray.bind(
|
|
||||||
this,
|
const continueCallback = needCalls(3, err => {
|
||||||
contextInfo,
|
|
||||||
this.context,
|
|
||||||
useLoadersPost,
|
|
||||||
loaderResolver,
|
|
||||||
resolveContext
|
|
||||||
),
|
|
||||||
this.resolveRequestArray.bind(
|
|
||||||
this,
|
|
||||||
contextInfo,
|
|
||||||
this.context,
|
|
||||||
useLoaders,
|
|
||||||
loaderResolver,
|
|
||||||
resolveContext
|
|
||||||
),
|
|
||||||
this.resolveRequestArray.bind(
|
|
||||||
this,
|
|
||||||
contextInfo,
|
|
||||||
this.context,
|
|
||||||
useLoadersPre,
|
|
||||||
loaderResolver,
|
|
||||||
resolveContext
|
|
||||||
)
|
|
||||||
],
|
|
||||||
(err, results) => {
|
|
||||||
if (err) {
|
if (err) {
|
||||||
return callback(err);
|
return callback(err);
|
||||||
}
|
}
|
||||||
loaders = results[0].concat(loaders, results[1], results[2]);
|
const allLoaders = postLoaders;
|
||||||
|
for (const loader of loaders) allLoaders.push(loader);
|
||||||
|
for (const loader of normalLoaders) allLoaders.push(loader);
|
||||||
|
for (const loader of preLoaders) allLoaders.push(loader);
|
||||||
const type = settings.type;
|
const type = settings.type;
|
||||||
const resolveOptions = settings.resolve;
|
const resolveOptions = settings.resolve;
|
||||||
Object.assign(data.createData, {
|
Object.assign(data.createData, {
|
||||||
request: loaders
|
request: stringifyLoadersAndResource(allLoaders, resource),
|
||||||
.map(loaderToIdent)
|
|
||||||
.concat([resource])
|
|
||||||
.join("!"),
|
|
||||||
userRequest,
|
userRequest,
|
||||||
rawRequest: request,
|
rawRequest: request,
|
||||||
loaders,
|
loaders: allLoaders,
|
||||||
resource,
|
resource,
|
||||||
matchResource,
|
matchResource,
|
||||||
resourceResolveData,
|
resourceResolveData,
|
||||||
|
|
@ -407,8 +368,80 @@ class NormalModuleFactory extends ModuleFactory {
|
||||||
resolveOptions
|
resolveOptions
|
||||||
});
|
});
|
||||||
callback();
|
callback();
|
||||||
|
});
|
||||||
|
this.resolveRequestArray(
|
||||||
|
contextInfo,
|
||||||
|
this.context,
|
||||||
|
useLoadersPost,
|
||||||
|
loaderResolver,
|
||||||
|
resolveContext,
|
||||||
|
(err, result) => {
|
||||||
|
postLoaders = result;
|
||||||
|
continueCallback(err);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
this.resolveRequestArray(
|
||||||
|
contextInfo,
|
||||||
|
this.context,
|
||||||
|
useLoaders,
|
||||||
|
loaderResolver,
|
||||||
|
resolveContext,
|
||||||
|
(err, result) => {
|
||||||
|
normalLoaders = result;
|
||||||
|
continueCallback(err);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
this.resolveRequestArray(
|
||||||
|
contextInfo,
|
||||||
|
this.context,
|
||||||
|
useLoadersPre,
|
||||||
|
loaderResolver,
|
||||||
|
resolveContext,
|
||||||
|
(err, result) => {
|
||||||
|
preLoaders = result;
|
||||||
|
continueCallback(err);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
this.resolveRequestArray(
|
||||||
|
contextInfo,
|
||||||
|
context,
|
||||||
|
elements,
|
||||||
|
loaderResolver,
|
||||||
|
resolveContext,
|
||||||
|
(err, result) => {
|
||||||
|
if (err) return continueCallback(err);
|
||||||
|
loaders = result;
|
||||||
|
continueCallback();
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
if (
|
||||||
|
unresolvedResource === "" ||
|
||||||
|
unresolvedResource.charCodeAt(0) === 63
|
||||||
|
) {
|
||||||
|
// 63 === "?"
|
||||||
|
resource = unresolvedResource;
|
||||||
|
return continueCallback();
|
||||||
|
}
|
||||||
|
|
||||||
|
normalResolver.resolve(
|
||||||
|
contextInfo,
|
||||||
|
context,
|
||||||
|
unresolvedResource,
|
||||||
|
resolveContext,
|
||||||
|
(err, resolvedResource, resolvedResourceResolveData) => {
|
||||||
|
if (err) return continueCallback(err);
|
||||||
|
|
||||||
|
// TODO remove this when enhanced-resolve supports fileDependencies
|
||||||
|
if (resolvedResource) {
|
||||||
|
fileDependencies.add(resolvedResource);
|
||||||
|
}
|
||||||
|
|
||||||
|
resource = resolvedResource;
|
||||||
|
resourceResolveData = resolvedResourceResolveData;
|
||||||
|
continueCallback();
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
@ -484,7 +517,7 @@ class NormalModuleFactory extends ModuleFactory {
|
||||||
resolveContext,
|
resolveContext,
|
||||||
callback
|
callback
|
||||||
) {
|
) {
|
||||||
if (array.length === 0) return callback(null, []);
|
if (array.length === 0) return callback(null, array);
|
||||||
asyncLib.map(
|
asyncLib.map(
|
||||||
array,
|
array,
|
||||||
(item, callback) => {
|
(item, callback) => {
|
||||||
|
|
@ -503,7 +536,7 @@ class NormalModuleFactory extends ModuleFactory {
|
||||||
contextInfo,
|
contextInfo,
|
||||||
context,
|
context,
|
||||||
item.loader + "-loader",
|
item.loader + "-loader",
|
||||||
{},
|
resolveContext,
|
||||||
err2 => {
|
err2 => {
|
||||||
if (!err2) {
|
if (!err2) {
|
||||||
err.message =
|
err.message =
|
||||||
|
|
@ -521,18 +554,15 @@ class NormalModuleFactory extends ModuleFactory {
|
||||||
}
|
}
|
||||||
if (err) return callback(err);
|
if (err) return callback(err);
|
||||||
|
|
||||||
const optionsOnly = item.options
|
const parsedResult = identToLoaderRequest(result);
|
||||||
? {
|
const resolved = {
|
||||||
options: item.options
|
loader: parsedResult.loader,
|
||||||
}
|
options:
|
||||||
: undefined;
|
item.options === undefined
|
||||||
|
? parsedResult.options
|
||||||
const resolved = Object.assign(
|
: item.options,
|
||||||
{},
|
ident: item.options === undefined ? undefined : item.ident
|
||||||
item,
|
};
|
||||||
identToLoaderRequest(result),
|
|
||||||
optionsOnly
|
|
||||||
);
|
|
||||||
|
|
||||||
// TODO remove this when enhanced-resolve supports fileDependencies
|
// TODO remove this when enhanced-resolve supports fileDependencies
|
||||||
if (resolved.loader) {
|
if (resolved.loader) {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue