Repository: rollup/rollup
File: src/ExternalModule.ts (TypeScript)

Code before:
	private readonly declarations = new Map<string, ExternalVariable>();
	private mostCommonSuggestion = 0;
	private readonly nameSuggestions = new Map<string, number>();

	constructor(
		private readonly options: NormalizedInputOptions,
		public readonly id: string,
		moduleSideEffects: boolean | 'no-treeshake',
		meta: CustomPluginOptions,
		public readonly renormalizeRenderPath: boolean,
		assertions: Record<string, string>
	) {
		this.suggestedVariableName = makeLegal(id.split(/[/\\]/).pop()!);

		const { importers, dynamicImporters } = this;
		const info: ModuleInfo = (this.info = {
			assertions,
			ast: null,
			code: null,
			dynamicallyImportedIdResolutions: EMPTY_ARRAY,
			dynamicallyImportedIds: EMPTY_ARRAY,
			get dynamicImporters() {
				return dynamicImporters.sort();
			},
			exportedBindings: {},
			exports: [],
			hasDefaultExport: null,
			get hasModuleSideEffects() {
				warnDeprecation(
					'Accessing ModuleInfo.hasModuleSideEffects from plugins is deprecated. Please use ModuleInfo.moduleSideEffects instead.',
					true,
					options
				);
				return info.moduleSideEffects;
			},
			id,
			implicitlyLoadedAfterOneOf: EMPTY_ARRAY,
			implicitlyLoadedBefore: EMPTY_ARRAY,
			importedIdResolutions: EMPTY_ARRAY,
			importedIds: EMPTY_ARRAY,
			get importers() {
				return importers.sort();
			},
			isEntry: false,
			isExternal: true,
			isIncluded: null,
			meta,
			moduleSideEffects,
			syntheticNamedExports: false
		});
		// Hide the deprecated key so that it only warns when accessed explicitly

Review comment (suggestion):
I wonder if we could rather do this lazily with getters rather than imperatively. The thinking here is that the current solution requires us to remember that whenever we do something with `exports`, `reexportDescriptions` or `exportAllModules`, we need to remember to also update the fields on info. Also, we do not expect this information to be needed regularly.
Instead if this information is derived just in time from the `exports`, `reexportDescriptions` and `exportAllModules` we would have a single source of truth of sorts. And the information would also be protected from being overwritten.

Code after:
	private readonly declarations = new Map<string, ExternalVariable>();
	private mostCommonSuggestion = 0;
	private readonly nameSuggestions = new Map<string, number>();

	constructor(
		private readonly options: NormalizedInputOptions,
		public readonly id: string,
		moduleSideEffects: boolean | 'no-treeshake',
		meta: CustomPluginOptions,
		public readonly renormalizeRenderPath: boolean,
		assertions: Record<string, string>
	) {
		this.suggestedVariableName = makeLegal(id.split(/[/\\]/).pop()!);

		const { importers, dynamicImporters } = this;
		const info: ModuleInfo = (this.info = {
			assertions,
			ast: null,
			code: null,
			dynamicallyImportedIdResolutions: EMPTY_ARRAY,
			dynamicallyImportedIds: EMPTY_ARRAY,
			get dynamicImporters() {
				return dynamicImporters.sort();
			},
			exportedBindings: null,
			exports: null,
			hasDefaultExport: null,
			get hasModuleSideEffects() {
				warnDeprecation(
					'Accessing ModuleInfo.hasModuleSideEffects from plugins is deprecated. Please use ModuleInfo.moduleSideEffects instead.',
					true,
					options
				);
				return info.moduleSideEffects;
			},
			id,
			implicitlyLoadedAfterOneOf: EMPTY_ARRAY,
			implicitlyLoadedBefore: EMPTY_ARRAY,
			importedIdResolutions: EMPTY_ARRAY,
			importedIds: EMPTY_ARRAY,
			get importers() {
				return importers.sort();
			},
			isEntry: false,
			isExternal: true,
			isIncluded: null,
			meta,
			moduleSideEffects,
			syntheticNamedExports: false
		});
		// Hide the deprecated key so that it only warns when accessed explicitly