Skip to content

Commit

Permalink
perf: optimize module resolution (#1183)
Browse files Browse the repository at this point in the history
For LWC mono repo, we went from 8 seconds to 500ms.
Still room for improvement.
Fixes #1162 (at least partially)
  • Loading branch information
diervo authored Apr 19, 2019
1 parent 0168622 commit 81ffabf
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 27 deletions.
1 change: 0 additions & 1 deletion packages/@lwc/jest-resolver/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ const WHITELISTED_LWC_PACKAGES = {
'wire-service': '@lwc/wire-service',
'wire-service-jest-util': 'lwc-wire-service-jest-util',
};

const lwcMap = lwcNpmResolver.resolveLwcNpmModules();

// This logic is somewhat the same in the compiler resolution system
Expand Down
2 changes: 1 addition & 1 deletion packages/@lwc/module-resolver/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
},
"license": "MIT",
"dependencies": {
"glob": "^7.1.2"
"fast-glob": "~2.2.6"
},
"publishConfig": {
"access": "public"
Expand Down
65 changes: 40 additions & 25 deletions packages/@lwc/module-resolver/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,13 @@
*/
/* eslint-env node */

import glob from 'glob';
import glob from 'fast-glob';
import path from 'path';
import fs from 'fs';
import nodeModulePaths from './node-modules-paths';

const DEFAULT_IGNORE = ['**/node_modules/**', '**/__tests__/**'];
const PACKAGE_PATTERN = `**/*/package.json`;
const PACKAGE_PATTERN = ['*/*/package.json', '*/package.json'];
const MODULE_ENTRY_PATTERN = `**/*.[jt]s`;
const LWC_CONFIG_FILE = '.lwcrc';

Expand All @@ -28,6 +28,10 @@ export interface ModuleResolverConfig {
rootDir: string;
}

interface FlatEntry {
path: string;
}

function createRegistryEntry(entry, moduleSpecifier, moduleName, moduleNamespace): RegistryEntry {
return { entry, moduleSpecifier, moduleName, moduleNamespace };
}
Expand All @@ -50,27 +54,33 @@ function loadLwcConfig(modulePath) {
}

export function resolveModulesInDir(absPath: string): { [name: string]: RegistryEntry } {
return glob.sync(MODULE_ENTRY_PATTERN, { cwd: absPath }).reduce((mappings, file) => {
const ext = path.extname(file);
const fileName = path.basename(file, ext);
const rootDir = path.dirname(file);
const rootParts = rootDir.split('/'); // the glob library normalizes paths to forward slashes only - https://github.com/isaacs/node-glob#windows
const entry = path.join(absPath, file);

const dirModuleName = rootParts.pop();
const dirModuleNamespace = rootParts.pop();
if (dirModuleNamespace && dirModuleName === fileName) {
const registryNode = createRegistryEntry(
entry,
`${dirModuleNamespace}/${fileName}`,
fileName,
dirModuleNamespace.toLowerCase()
);
mappings[registryNode.moduleSpecifier] = registryNode;
}

return mappings;
}, {});
return glob
.sync<FlatEntry>(MODULE_ENTRY_PATTERN, {
cwd: absPath,
transform: entry =>
typeof entry === 'string' ? { path: entry } : { path: entry.path },
})
.reduce((mappings, { path: file }) => {
const ext = path.extname(file);
const fileName = path.basename(file, ext);
const rootDir = path.dirname(file);
const rootParts = rootDir.split('/'); // the glob library normalizes paths to forward slashes only - https://github.com/isaacs/node-glob#windows
const entry = path.join(absPath, file);

const dirModuleName = rootParts.pop();
const dirModuleNamespace = rootParts.pop();
if (dirModuleNamespace && dirModuleName === fileName) {
const registryNode = createRegistryEntry(
entry,
`${dirModuleNamespace}/${fileName}`,
fileName,
dirModuleNamespace.toLowerCase()
);
mappings[registryNode.moduleSpecifier] = registryNode;
}

return mappings;
}, {});
}

function hasModuleBeenVisited(module, visited) {
Expand Down Expand Up @@ -123,8 +133,13 @@ export function resolveLwcNpmModules(options: Partial<ModuleResolverConfig> = {}
const modulePaths = expandModuleDirectories(options);
return modulePaths.reduce((m, nodeModulesDir) => {
return glob
.sync(PACKAGE_PATTERN, { cwd: nodeModulesDir, ignore: DEFAULT_IGNORE })
.reduce((mappings, file) => {
.sync<FlatEntry>(PACKAGE_PATTERN, {
cwd: nodeModulesDir,
ignore: DEFAULT_IGNORE,
transform: entry =>
typeof entry === 'string' ? { path: entry } : { path: entry.path },
})
.reduce((mappings, { path: file }) => {
const moduleRoot = path.dirname(path.join(nodeModulesDir, file));
const lwcConfig = loadLwcConfig(moduleRoot);

Expand Down

0 comments on commit 81ffabf

Please sign in to comment.