Skip to content

Commit 89ee52c

Browse files
refactor: use fs.promises in resolve id, Part 4 (#4386)
* refactor: use fs.promises in resolve id * Make chunk variable names deterministic, sort watchfiles in tests * Fix order of mixed export warnings * Make tests Node 10 compatible * remove test generated file Co-authored-by: Lukas Taegert-Atkinson <[email protected]> Co-authored-by: Lukas Taegert-Atkinson <[email protected]>
1 parent 33a4278 commit 89ee52c

48 files changed

Lines changed: 312 additions & 293 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

cli/run/batchWarnings.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,7 @@ const deferredHandlers: {
142142
title('Mixing named and default exports');
143143
info(`https://rollupjs.org/guide/en/#outputexports`);
144144
stderr(bold('The following entry modules are using named and default exports together:'));
145+
warnings.sort((a, b) => (a.id! < b.id! ? -1 : 1));
145146
const displayedWarnings = warnings.length > 5 ? warnings.slice(0, 3) : warnings;
146147
for (const warning of displayedWarnings) {
147148
stderr(relativeId(warning.id!));

src/Chunk.ts

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -329,9 +329,14 @@ export default class Chunk {
329329
}
330330
}
331331
for (const module of entryModules) {
332-
const requiredFacades: FacadeName[] = Array.from(module.userChunkNames, name => ({
333-
name
334-
}));
332+
const requiredFacades: FacadeName[] = Array.from(
333+
new Set(
334+
module.chunkNames.filter(({ isUserDefined }) => isUserDefined).map(({ name }) => name)
335+
),
336+
name => ({
337+
name
338+
})
339+
);
335340
if (requiredFacades.length === 0 && module.isUserDefinedEntryPoint) {
336341
requiredFacades.push({});
337342
}
@@ -959,7 +964,7 @@ export default class Chunk {
959964
this.dynamicEntryModules[0] ||
960965
this.orderedModules[this.orderedModules.length - 1];
961966
if (moduleForNaming) {
962-
return moduleForNaming.chunkName || getAliasName(moduleForNaming.id);
967+
return getChunkNameFromModule(moduleForNaming);
963968
}
964969
return 'chunk';
965970
}
@@ -1398,7 +1403,11 @@ export default class Chunk {
13981403
}
13991404

14001405
function getChunkNameFromModule(module: Module): string {
1401-
return module.chunkName || getAliasName(module.id);
1406+
return (
1407+
module.chunkNames.find(({ isUserDefined }) => isUserDefined)?.name ??
1408+
module.chunkNames[0]?.name ??
1409+
getAliasName(module.id)
1410+
);
14021411
}
14031412

14041413
const QUERY_HASH_REGEX = /[?#]/;

src/Module.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -189,7 +189,11 @@ export default class Module {
189189
readonly alternativeReexportModules = new Map<Variable, Module>();
190190
ast: Program | null = null;
191191
readonly chunkFileNames = new Set<string>();
192-
chunkName: string | null = null;
192+
chunkNames: {
193+
isUserDefined: boolean;
194+
name: string;
195+
priority: number;
196+
}[] = [];
193197
readonly cycles = new Set<symbol>();
194198
readonly dependencies = new Set<Module | ExternalModule>();
195199
readonly dynamicDependencies = new Set<Module | ExternalModule>();
@@ -222,7 +226,6 @@ export default class Module {
222226
declare sourcemapChain: DecodedSourceMapOrMissing[];
223227
readonly sources = new Set<string>();
224228
declare transformFiles?: EmittedFile[];
225-
readonly userChunkNames = new Set<string>();
226229
usesTopLevelAwait = false;
227230

228231
private allExportNames: Set<string> | null = null;

src/ModuleLoader.ts

Lines changed: 25 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ export class ModuleLoader {
7070
private latestLoadModulesPromise: Promise<unknown> = Promise.resolve();
7171
private readonly moduleLoadPromises = new Map<Module, LoadModulePromise>();
7272
private readonly modulesWithLoadedDependencies = new Set<Module>();
73+
private nextChunkNamePriority = 0;
7374
private nextEntryModuleIndex = 0;
7475
private readonly readQueue: Queue<LoadResult>;
7576

@@ -104,27 +105,38 @@ export class ModuleLoader {
104105
}> {
105106
const firstEntryModuleIndex = this.nextEntryModuleIndex;
106107
this.nextEntryModuleIndex += unresolvedEntryModules.length;
108+
const firstChunkNamePriority = this.nextChunkNamePriority;
109+
this.nextChunkNamePriority += unresolvedEntryModules.length;
107110
const newEntryModules = await this.extendLoadModulesPromise(
108111
Promise.all(
109112
unresolvedEntryModules.map(({ id, importer }) =>
110113
this.loadEntryModule(id, true, importer, null)
111114
)
112115
).then(entryModules => {
113-
let moduleIndex = firstEntryModuleIndex;
114116
for (let index = 0; index < entryModules.length; index++) {
115117
const entryModule = entryModules[index];
116118
entryModule.isUserDefinedEntryPoint =
117119
entryModule.isUserDefinedEntryPoint || isUserDefined;
118-
addChunkNamesToModule(entryModule, unresolvedEntryModules[index], isUserDefined);
120+
addChunkNamesToModule(
121+
entryModule,
122+
unresolvedEntryModules[index],
123+
isUserDefined,
124+
firstChunkNamePriority + index
125+
);
119126
const existingIndexedModule = this.indexedEntryModules.find(
120127
indexedModule => indexedModule.module === entryModule
121128
);
122129
if (!existingIndexedModule) {
123-
this.indexedEntryModules.push({ index: moduleIndex, module: entryModule });
130+
this.indexedEntryModules.push({
131+
index: firstEntryModuleIndex + index,
132+
module: entryModule
133+
});
124134
} else {
125-
existingIndexedModule.index = Math.min(existingIndexedModule.index, moduleIndex);
135+
existingIndexedModule.index = Math.min(
136+
existingIndexedModule.index,
137+
firstEntryModuleIndex + index
138+
);
126139
}
127-
moduleIndex++;
128140
}
129141
this.indexedEntryModules.sort(({ index: indexA }, { index: indexB }) =>
130142
indexA > indexB ? 1 : -1
@@ -207,10 +219,11 @@ export class ModuleLoader {
207219
unresolvedModule: UnresolvedModule,
208220
implicitlyLoadedAfter: readonly string[]
209221
): Promise<Module> {
222+
const chunkNamePriority = this.nextChunkNamePriority++;
210223
return this.extendLoadModulesPromise(
211224
this.loadEntryModule(unresolvedModule.id, false, unresolvedModule.importer, null).then(
212225
async entryModule => {
213-
addChunkNamesToModule(entryModule, unresolvedModule, false);
226+
addChunkNamesToModule(entryModule, unresolvedModule, false, chunkNamePriority);
214227
if (!entryModule.info.isEntry) {
215228
this.implicitEntryModules.add(entryModule);
216229
const implicitlyLoadedAfterModules = await Promise.all(
@@ -688,17 +701,16 @@ function normalizeRelativeExternalId(source: string, importer: string | undefine
688701
function addChunkNamesToModule(
689702
module: Module,
690703
{ fileName, name }: UnresolvedModule,
691-
isUserDefined: boolean
704+
isUserDefined: boolean,
705+
priority: number
692706
): void {
693707
if (fileName !== null) {
694708
module.chunkFileNames.add(fileName);
695709
} else if (name !== null) {
696-
if (module.chunkName === null) {
697-
module.chunkName = name;
698-
}
699-
if (isUserDefined) {
700-
module.userChunkNames.add(name);
701-
}
710+
// Always keep chunkNames sorted by priority
711+
let namePosition = 0;
712+
while (module.chunkNames[namePosition]?.priority < priority) namePosition++;
713+
module.chunkNames.splice(namePosition, 0, { isUserDefined, name, priority });
702714
}
703715
}
704716

src/utils/resolveId.ts

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import type { CustomPluginOptions, Plugin, ResolvedId, ResolveIdResult } from '../rollup/types';
22
import type { PluginDriver } from './PluginDriver';
3-
import { lstatSync, readdirSync, realpathSync } from './fs';
3+
import { promises as fs } from './fs';
44
import { basename, dirname, isAbsolute, resolve } from './path';
55
import { resolveIdViaPlugins } from './resolveIdViaPlugins';
66

@@ -45,23 +45,26 @@ export async function resolveId(
4545
);
4646
}
4747

48-
function addJsExtensionIfNecessary(file: string, preserveSymlinks: boolean): string | undefined {
48+
async function addJsExtensionIfNecessary(
49+
file: string,
50+
preserveSymlinks: boolean
51+
): Promise<string | undefined> {
4952
return (
50-
findFile(file, preserveSymlinks) ??
51-
findFile(file + '.mjs', preserveSymlinks) ??
52-
findFile(file + '.js', preserveSymlinks)
53+
(await findFile(file, preserveSymlinks)) ??
54+
(await findFile(file + '.mjs', preserveSymlinks)) ??
55+
(await findFile(file + '.js', preserveSymlinks))
5356
);
5457
}
5558

56-
function findFile(file: string, preserveSymlinks: boolean): string | undefined {
59+
async function findFile(file: string, preserveSymlinks: boolean): Promise<string | undefined> {
5760
try {
58-
const stats = lstatSync(file);
61+
const stats = await fs.lstat(file);
5962
if (!preserveSymlinks && stats.isSymbolicLink())
60-
return findFile(realpathSync(file), preserveSymlinks);
63+
return await findFile(await fs.realpath(file), preserveSymlinks);
6164
if ((preserveSymlinks && stats.isSymbolicLink()) || stats.isFile()) {
6265
// check case
6366
const name = basename(file);
64-
const files = readdirSync(dirname(file));
67+
const files = await fs.readdir(dirname(file));
6568

6669
if (files.includes(name)) return file;
6770
}

test/chunking-form/samples/emit-file/emit-chunk-name-conflict/_expected/amd/generated-secondName.js renamed to test/chunking-form/samples/emit-file/emit-chunk-name-conflict/_expected/amd/generated-firstName.js

File renamed without changes.
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
define(['./generated-name', './generated-secondName', './generated-name2'], (function (name, secondName, name$1) { 'use strict';
1+
define(['./generated-name', './generated-firstName', './generated-name2'], (function (name, firstName, name$1) { 'use strict';
22

3-
console.log('main', name, secondName, name$1);
3+
console.log('main', name, firstName, name$1);
44

55
}));

test/chunking-form/samples/emit-file/emit-chunk-name-conflict/_expected/amd/other.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
define(['./generated-name', './generated-secondName', './generated-name2', './mainChunk'], (function (name, secondName, name$1, mainChunk) { 'use strict';
1+
define(['./generated-name', './generated-firstName', './generated-name2', './mainChunk'], (function (name, firstName, name$1, mainChunk) { 'use strict';
22

33

44

test/chunking-form/samples/emit-file/emit-chunk-name-conflict/_expected/cjs/generated-secondName.js renamed to test/chunking-form/samples/emit-file/emit-chunk-name-conflict/_expected/cjs/generated-firstName.js

File renamed without changes.
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
'use strict';
22

33
var name = require('./generated-name.js');
4-
var secondName = require('./generated-secondName.js');
4+
var firstName = require('./generated-firstName.js');
55
var name$1 = require('./generated-name2.js');
66

7-
console.log('main', name, secondName, name$1);
7+
console.log('main', name, firstName, name$1);

0 commit comments

Comments
 (0)