rename parsePathQueryFragment to parseResource and add caching
This commit is contained in:
parent
2cc3510f55
commit
5f4c4662dd
|
@ -875,7 +875,8 @@ class Compiler {
|
|||
context: this.options.context,
|
||||
fs: this.inputFileSystem,
|
||||
resolverFactory: this.resolverFactory,
|
||||
options: this.options.module || {}
|
||||
options: this.options.module || {},
|
||||
associatedObjectForCache: this.root
|
||||
});
|
||||
this.hooks.normalModuleFactory.call(normalModuleFactory);
|
||||
return normalModuleFactory;
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
const CachedConstDependency = require("./dependencies/CachedConstDependency");
|
||||
const ConstDependency = require("./dependencies/ConstDependency");
|
||||
const { evaluateToString } = require("./javascript/JavascriptParserHelpers");
|
||||
const { parsePathQueryFragment } = require("./util/identifier");
|
||||
const { parseResource } = require("./util/identifier");
|
||||
|
||||
/** @typedef {import("./Compiler")} Compiler */
|
||||
|
||||
|
@ -113,6 +113,7 @@ class ConstPlugin {
|
|||
* @returns {void}
|
||||
*/
|
||||
apply(compiler) {
|
||||
const cacheParseResource = parseResource.bindCache(compiler.root);
|
||||
compiler.hooks.compilation.tap(
|
||||
"ConstPlugin",
|
||||
(compilation, { normalModuleFactory }) => {
|
||||
|
@ -324,7 +325,7 @@ class ConstPlugin {
|
|||
if (parser.scope.isAsmJs) return;
|
||||
if (!parser.state.module) return;
|
||||
return evaluateToString(
|
||||
parsePathQueryFragment(parser.state.module.resource).query
|
||||
cacheParseResource(parser.state.module.resource).query
|
||||
)(expr);
|
||||
});
|
||||
parser.hooks.expression
|
||||
|
@ -334,7 +335,7 @@ class ConstPlugin {
|
|||
if (!parser.state.module) return;
|
||||
const dep = new CachedConstDependency(
|
||||
JSON.stringify(
|
||||
parsePathQueryFragment(parser.state.module.resource).query
|
||||
cacheParseResource(parser.state.module.resource).query
|
||||
),
|
||||
expr.range,
|
||||
"__resourceQuery"
|
||||
|
@ -350,7 +351,7 @@ class ConstPlugin {
|
|||
if (parser.scope.isAsmJs) return;
|
||||
if (!parser.state.module) return;
|
||||
return evaluateToString(
|
||||
parsePathQueryFragment(parser.state.module.resource).fragment
|
||||
cacheParseResource(parser.state.module.resource).fragment
|
||||
)(expr);
|
||||
});
|
||||
parser.hooks.expression
|
||||
|
@ -360,7 +361,7 @@ class ConstPlugin {
|
|||
if (!parser.state.module) return;
|
||||
const dep = new CachedConstDependency(
|
||||
JSON.stringify(
|
||||
parsePathQueryFragment(parser.state.module.resource).fragment
|
||||
cacheParseResource(parser.state.module.resource).fragment
|
||||
),
|
||||
expr.range,
|
||||
"__resourceFragment"
|
||||
|
|
|
@ -19,7 +19,7 @@ const {
|
|||
keepOriginalOrder
|
||||
} = require("./util/comparators");
|
||||
const { compareModulesById } = require("./util/comparators");
|
||||
const { contextify, parsePathQueryFragment } = require("./util/identifier");
|
||||
const { contextify, parseResource } = require("./util/identifier");
|
||||
const makeSerializable = require("./util/makeSerializable");
|
||||
|
||||
/** @typedef {import("webpack-sources").Source} Source */
|
||||
|
@ -87,7 +87,7 @@ class ContextModule extends Module {
|
|||
* @param {ContextModuleOptions} options options object
|
||||
*/
|
||||
constructor(resolveDependencies, options) {
|
||||
const parsed = parsePathQueryFragment(options.resource);
|
||||
const parsed = parseResource(options.resource);
|
||||
const resource = parsed.path;
|
||||
const resourceQuery = options.resourceQuery || parsed.query;
|
||||
const resourceFragment = options.resourceFragment || parsed.fragment;
|
||||
|
|
|
@ -25,7 +25,7 @@ const LazySet = require("./util/LazySet");
|
|||
const { getScheme } = require("./util/URLAbsoluteSpecifier");
|
||||
const { cachedCleverMerge, cachedSetProperty } = require("./util/cleverMerge");
|
||||
const { join } = require("./util/fs");
|
||||
const { parsePathQueryFragment } = require("./util/identifier");
|
||||
const { parseResource } = require("./util/identifier");
|
||||
|
||||
/** @typedef {import("../declarations/WebpackOptions").ModuleOptions} ModuleOptions */
|
||||
/** @typedef {import("./Generator")} Generator */
|
||||
|
@ -154,8 +154,15 @@ class NormalModuleFactory extends ModuleFactory {
|
|||
* @param {InputFileSystem} param.fs file system
|
||||
* @param {ResolverFactory} param.resolverFactory resolverFactory
|
||||
* @param {ModuleOptions} param.options options
|
||||
* @param {Object=} param.associatedObjectForCache an object to which the cache will be attached
|
||||
*/
|
||||
constructor({ context, fs, resolverFactory, options }) {
|
||||
constructor({
|
||||
context,
|
||||
fs,
|
||||
resolverFactory,
|
||||
options,
|
||||
associatedObjectForCache
|
||||
}) {
|
||||
super();
|
||||
this.hooks = Object.freeze({
|
||||
/** @type {AsyncSeriesBailHook<[ResolveData], TODO>} */
|
||||
|
@ -207,6 +214,11 @@ class NormalModuleFactory extends ModuleFactory {
|
|||
* @type {Map<string, WeakMap<Object, Generator>>}
|
||||
*/
|
||||
this.generatorCache = new Map();
|
||||
|
||||
const cacheParseResource = parseResource.bindCache(
|
||||
associatedObjectForCache
|
||||
);
|
||||
|
||||
this.hooks.factorize.tapAsync(
|
||||
{
|
||||
name: "NormalModuleFactory",
|
||||
|
@ -303,7 +315,7 @@ class NormalModuleFactory extends ModuleFactory {
|
|||
}
|
||||
matchResourceData = {
|
||||
resource: matchResource,
|
||||
...parsePathQueryFragment(matchResource)
|
||||
...cacheParseResource(matchResource)
|
||||
};
|
||||
requestWithoutMatchResource = request.substr(
|
||||
matchResourceMatch[0].length
|
||||
|
@ -529,7 +541,7 @@ class NormalModuleFactory extends ModuleFactory {
|
|||
resourceData = {
|
||||
resource: unresolvedResource,
|
||||
data: {},
|
||||
...parsePathQueryFragment(unresolvedResource)
|
||||
...cacheParseResource(unresolvedResource)
|
||||
};
|
||||
continueCallback();
|
||||
}
|
||||
|
@ -557,7 +569,7 @@ class NormalModuleFactory extends ModuleFactory {
|
|||
resourceData = {
|
||||
resource: resolvedResource,
|
||||
data: resolvedResourceResolveData,
|
||||
...parsePathQueryFragment(resolvedResource)
|
||||
...cacheParseResource(resolvedResource)
|
||||
};
|
||||
}
|
||||
continueCallback();
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
|
||||
"use strict";
|
||||
|
||||
const { parsePathQueryFragment } = require("../util/identifier");
|
||||
const { parseResource } = require("../util/identifier");
|
||||
|
||||
/** @typedef {import("../javascript/BasicEvaluatedExpression")} BasicEvaluatedExpression */
|
||||
/** @typedef {import("../javascript/JavascriptParser")} JavascriptParser */
|
||||
|
@ -59,8 +59,9 @@ exports.create = (Dep, range, param, expr, options, contextOptions, parser) => {
|
|||
|
||||
const valueRange = param.range;
|
||||
const { context, prefix } = splitContextFromPrefix(prefixRaw);
|
||||
const { path: postfix, query, fragment } = parsePathQueryFragment(
|
||||
postfixRaw
|
||||
const { path: postfix, query, fragment } = parseResource(
|
||||
postfixRaw,
|
||||
parser
|
||||
);
|
||||
|
||||
// When there are more than two quasis, the generated RegExp can be more precise
|
||||
|
@ -157,8 +158,9 @@ exports.create = (Dep, range, param, expr, options, contextOptions, parser) => {
|
|||
param.postfix && param.postfix.isString() ? param.postfix.range : null;
|
||||
const valueRange = param.range;
|
||||
const { context, prefix } = splitContextFromPrefix(prefixRaw);
|
||||
const { path: postfix, query, fragment } = parsePathQueryFragment(
|
||||
postfixRaw
|
||||
const { path: postfix, query, fragment } = parseResource(
|
||||
postfixRaw,
|
||||
parser
|
||||
);
|
||||
const regExp = new RegExp(
|
||||
`^${quoteMeta(prefix)}${options.wrappedContextRegExp.source}${quoteMeta(
|
||||
|
|
|
@ -246,16 +246,59 @@ exports.absolutify = absolutify;
|
|||
|
||||
const PATH_QUERY_FRAGMENT_REGEXP = /^([^?#]*)(\?[^#]*)?(#.*)?$/;
|
||||
|
||||
/** @typedef {{ resource: string, path: string, query: string, fragment: string }} ParsedResource */
|
||||
|
||||
/**
|
||||
* @param {string} str the path with query and fragment
|
||||
* @returns {{ path: string, query: string, fragment: string }} parsed parts
|
||||
* @returns {ParsedResource} parsed parts
|
||||
*/
|
||||
const parsePathQueryFragment = str => {
|
||||
const _parseResource = str => {
|
||||
const match = PATH_QUERY_FRAGMENT_REGEXP.exec(str);
|
||||
return {
|
||||
resource: str,
|
||||
path: match[1],
|
||||
query: match[2] || "",
|
||||
fragment: match[3] || ""
|
||||
};
|
||||
};
|
||||
exports.parsePathQueryFragment = parsePathQueryFragment;
|
||||
exports.parseResource = (realFn => {
|
||||
/** @type {WeakMap<object, Map<string, ParsedResource>>} */
|
||||
const cache = new WeakMap();
|
||||
|
||||
const getCache = associatedObjectForCache => {
|
||||
const entry = cache.get(associatedObjectForCache);
|
||||
if (entry !== undefined) return entry;
|
||||
/** @type {Map<string, ParsedResource>} */
|
||||
const map = new Map();
|
||||
cache.set(associatedObjectForCache, map);
|
||||
return map;
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {string} str the path with query and fragment
|
||||
* @param {Object=} associatedObjectForCache an object to which the cache will be attached
|
||||
* @returns {ParsedResource} parsed parts
|
||||
*/
|
||||
const fn = (str, associatedObjectForCache) => {
|
||||
if (!associatedObjectForCache) return realFn(str);
|
||||
const cache = getCache(associatedObjectForCache);
|
||||
const entry = cache.get(str);
|
||||
if (entry !== undefined) return entry;
|
||||
const result = realFn(str);
|
||||
cache.set(str, result);
|
||||
return result;
|
||||
};
|
||||
|
||||
fn.bindCache = associatedObjectForCache => {
|
||||
const cache = getCache(associatedObjectForCache);
|
||||
return str => {
|
||||
const entry = cache.get(str);
|
||||
if (entry !== undefined) return entry;
|
||||
const result = realFn(str);
|
||||
cache.set(str, result);
|
||||
return result;
|
||||
};
|
||||
};
|
||||
|
||||
return fn;
|
||||
})(_parseResource);
|
||||
|
|
Loading…
Reference in New Issue