perf: move import attributes to own dependencies (#19892)

This commit is contained in:
Alexander Akait 2025-09-18 15:37:40 +03:00 committed by GitHub
parent 4fabb754de
commit c90f405abd
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
9 changed files with 67 additions and 35 deletions

View File

@ -157,7 +157,7 @@ class ExternalModuleFactoryPlugin {
: undefined;
dependencyMeta = {
attributes: dependency.assertions,
attributes: dependency.attributes,
externalType
};
} else if (dependency instanceof CssImportDependency) {

View File

@ -1959,6 +1959,7 @@ class FileSystemInfo {
this.fs.readFile(path, (err, content) => {
if (err) return callback(err);
try {
const added = new Set();
const context = dirname(this.fs, path);
const source = /** @type {Buffer} */ (content).toString();
const [imports] = lexer.parse(source);
@ -1979,7 +1980,9 @@ class FileSystemInfo {
continue;
}
// we should not track Node.js build dependencies
// Avoid extra jobs for the same import
if (added.has(dependency)) continue;
// We should not track Node.js build dependencies
if (dependency.startsWith("node:")) continue;
if (builtinModules.has(dependency)) continue;
@ -1990,6 +1993,7 @@ class FileSystemInfo {
expected: imp.d > -1 ? false : undefined,
issuer: job
});
added.add(dependency);
} catch (err1) {
logger.warn(
`Parsing of ${path} for build dependencies failed at 'import(${source.slice(

View File

@ -70,7 +70,7 @@ const {
* @property {ModuleFactoryCreateData["resolveOptions"]} resolveOptions
* @property {string} context
* @property {string} request
* @property {ImportAttributes | undefined} assertions
* @property {ImportAttributes | undefined} attributes
* @property {ModuleDependency[]} dependencies
* @property {string} dependencyType
* @property {CreateData} createData
@ -242,7 +242,7 @@ const ruleSetCompiler = new RuleSetCompiler([
new BasicMatcherRulePlugin("issuer"),
new BasicMatcherRulePlugin("compiler"),
new BasicMatcherRulePlugin("issuerLayer"),
new ObjectMatcherRulePlugin("assert", "assertions", (value) => {
new ObjectMatcherRulePlugin("assert", "attributes", (value) => {
if (value) {
return (
/** @type {ImportAttributes} */ (value)._isLegacyAssert !== undefined
@ -251,7 +251,7 @@ const ruleSetCompiler = new RuleSetCompiler([
return false;
}),
new ObjectMatcherRulePlugin("with", "assertions", (value) => {
new ObjectMatcherRulePlugin("with", "attributes", (value) => {
if (value) {
return !(/** @type {ImportAttributes} */ (value)._isLegacyAssert);
}
@ -444,7 +444,7 @@ class NormalModuleFactory extends ModuleFactory {
dependencies,
dependencyType,
request,
assertions,
attributes,
resolveOptions,
fileDependencies,
missingDependencies,
@ -615,7 +615,7 @@ class NormalModuleFactory extends ModuleFactory {
resourceQuery: resourceDataForRules.query,
resourceFragment: resourceDataForRules.fragment,
scheme,
assertions,
attributes,
mimetype: matchResourceData
? ""
: resourceData.data.mimetype || "",
@ -896,7 +896,9 @@ class NormalModuleFactory extends ModuleFactory {
const resolveOptions = data.resolveOptions || EMPTY_RESOLVE_OPTIONS;
const dependency = dependencies[0];
const request = dependency.request;
const assertions = dependency.assertions;
const attributes =
/** @type {ModuleDependency & { attributes: ImportAttributes }} */
(dependency).attributes;
const dependencyType = dependency.category || "";
const contextInfo = data.contextInfo;
const fileDependencies = new LazySet();
@ -908,7 +910,7 @@ class NormalModuleFactory extends ModuleFactory {
resolveOptions,
context,
request,
assertions,
attributes,
dependencies,
dependencyType,
fileDependencies,

View File

@ -39,16 +39,16 @@ class ContextElementDependency extends ModuleDependency {
attributes
) {
super(request);
this.referencedExports = referencedExports;
this._typePrefix = typePrefix;
this._category = category;
this._context = context || undefined;
if (userRequest) {
this.userRequest = userRequest;
}
this.assertions = attributes;
this._typePrefix = typePrefix;
this._category = category;
this.referencedExports = referencedExports;
this._context = context || undefined;
this.attributes = attributes;
}
get type() {
@ -63,6 +63,17 @@ class ContextElementDependency extends ModuleDependency {
return this._category;
}
/**
* @returns {string | null} an identifier to merge equal requests
*/
getResourceIdentifier() {
let str = super.getResourceIdentifier();
if (this.attributes !== undefined) {
str += JSON.stringify(this.attributes);
}
return str;
}
/**
* Returns list of exports referenced by this dependency
* @param {ModuleGraph} moduleGraph module graph
@ -110,7 +121,7 @@ class ContextElementDependency extends ModuleDependency {
write(this._typePrefix);
write(this._category);
write(this.referencedExports);
write(this.assertions);
write(this.attributes);
super.serialize(context);
}
@ -122,7 +133,7 @@ class ContextElementDependency extends ModuleDependency {
this._typePrefix = read();
this._category = read();
this.referencedExports = read();
this.assertions = read();
this.attributes = read();
super.deserialize(context);
}
}

View File

@ -66,7 +66,7 @@ class HarmonyImportDependency extends ModuleDependency {
constructor(request, sourceOrder, attributes, defer) {
super(request);
this.sourceOrder = sourceOrder;
this.assertions = attributes;
this.attributes = attributes;
this.defer = defer;
}
@ -74,6 +74,17 @@ class HarmonyImportDependency extends ModuleDependency {
return "esm";
}
/**
* @returns {string | null} an identifier to merge equal requests
*/
getResourceIdentifier() {
let str = super.getResourceIdentifier();
if (this.attributes !== undefined) {
str += JSON.stringify(this.attributes);
}
return str;
}
/**
* Returns list of exports referenced by this dependency
* @param {ModuleGraph} moduleGraph module graph
@ -276,7 +287,7 @@ class HarmonyImportDependency extends ModuleDependency {
serialize(context) {
const { write } = context;
write(this.sourceOrder);
write(this.assertions);
write(this.attributes);
write(this.defer);
super.serialize(context);
}
@ -287,7 +298,7 @@ class HarmonyImportDependency extends ModuleDependency {
deserialize(context) {
const { read } = context;
this.sourceOrder = read();
this.assertions = read();
this.attributes = read();
this.defer = read();
super.deserialize(context);
}

View File

@ -34,7 +34,7 @@ class ImportDependency extends ModuleDependency {
super(request);
this.range = range;
this.referencedExports = referencedExports;
this.assertions = attributes;
this.attributes = attributes;
}
get type() {
@ -45,6 +45,17 @@ class ImportDependency extends ModuleDependency {
return "esm";
}
/**
* @returns {string | null} an identifier to merge equal requests
*/
getResourceIdentifier() {
let str = super.getResourceIdentifier();
if (this.attributes !== undefined) {
str += JSON.stringify(this.attributes);
}
return str;
}
/**
* Returns list of exports referenced by this dependency
* @param {ModuleGraph} moduleGraph module graph
@ -88,7 +99,7 @@ class ImportDependency extends ModuleDependency {
serialize(context) {
context.write(this.range);
context.write(this.referencedExports);
context.write(this.assertions);
context.write(this.attributes);
super.serialize(context);
}
@ -98,7 +109,7 @@ class ImportDependency extends ModuleDependency {
deserialize(context) {
this.range = context.read();
this.referencedExports = context.read();
this.assertions = context.read();
this.attributes = context.read();
super.deserialize(context);
}
}

View File

@ -25,10 +25,6 @@ class ModuleDependency extends Dependency {
this.userRequest = request;
/** @type {Range | undefined} */
this.range = undefined;
// TODO move it to subclasses and rename
// assertions must be serialized by subclasses that use it
/** @type {ImportAttributes | undefined} */
this.assertions = undefined;
this._context = undefined;
}
@ -43,11 +39,7 @@ class ModuleDependency extends Dependency {
* @returns {string | null} an identifier to merge equal requests
*/
getResourceIdentifier() {
let str = `context${this._context || ""}|module${this.request}`;
if (this.assertions !== undefined) {
str += JSON.stringify(this.assertions);
}
return str;
return `context${this._context || ""}|module${this.request}`;
}
/**

View File

@ -38,7 +38,7 @@ const { SyncHook } = require("tapable");
* @property {string=} resourceQuery
* @property {string=} resourceFragment
* @property {string=} scheme
* @property {ImportAttributes=} assertions
* @property {ImportAttributes=} attributes
* @property {string=} mimetype
* @property {string} dependency
* @property {ResolveRequest["descriptionFileData"]=} descriptionData

7
types.d.ts vendored
View File

@ -3347,6 +3347,7 @@ declare abstract class ContextDependency extends Dependency {
type ContextDependencyOptions = ContextOptions & { request: string };
declare abstract class ContextElementDependency extends ModuleDependency {
referencedExports?: null | string[][];
attributes?: ImportAttributes;
}
declare class ContextExclusionPlugin {
constructor(negativeMatcher: RegExp);
@ -4355,7 +4356,7 @@ declare interface EffectData {
resourceQuery?: string;
resourceFragment?: string;
scheme?: string;
assertions?: ImportAttributes;
attributes?: ImportAttributes;
mimetype?: string;
dependency: string;
descriptionData?: JsonObjectTypes;
@ -6104,6 +6105,7 @@ declare class HarmonyImportDependency extends ModuleDependency {
defer?: boolean
);
sourceOrder: number;
attributes?: ImportAttributes;
defer?: boolean;
getImportVar(moduleGraph: ModuleGraph): string;
getModuleExports(__0: DependencyTemplateContext): string;
@ -10099,7 +10101,6 @@ declare class ModuleDependency extends Dependency {
request: string;
userRequest: string;
range?: [number, number];
assertions?: ImportAttributes;
static Template: typeof DependencyTemplate;
static NO_EXPORTS_REFERENCED: string[][];
static EXPORTS_OBJECT_REFERENCED: string[][];
@ -14372,7 +14373,7 @@ declare interface ResolveData {
resolveOptions?: ResolveOptions;
context: string;
request: string;
assertions?: ImportAttributes;
attributes?: ImportAttributes;
dependencies: ModuleDependency[];
dependencyType: string;
createData: Partial<NormalModuleCreateData & { settings: ModuleSettings }>;