feat(core): optimize project graph file mapping (#13249)
This commit is contained in:
parent
ab93817d44
commit
de44bf86b1
@ -21,7 +21,7 @@ import {
|
||||
stripIndents,
|
||||
workspaceRoot,
|
||||
} from '@nrwl/devkit';
|
||||
import { mapProjectGraphFiles } from 'nx/src/utils/target-project-locator';
|
||||
import { createProjectFileMappings } from 'nx/src/utils/target-project-locator';
|
||||
import { lstatSync, mkdirSync, writeFileSync } from 'fs';
|
||||
import { dirname, join, relative } from 'path';
|
||||
import type { BrowserBuilderSchema } from '../src/builders/webpack-browser/webpack-browser.impl';
|
||||
@ -279,14 +279,16 @@ function withSchemaDefaults(options: any): BrowserBuilderSchema {
|
||||
* this file should get cleaned up via the cypress executor
|
||||
*/
|
||||
function getTempStylesForTailwind(ctExecutorContext: ExecutorContext) {
|
||||
const mappedGraph = mapProjectGraphFiles(ctExecutorContext.projectGraph);
|
||||
const mappedGraphFiles = createProjectFileMappings(
|
||||
ctExecutorContext.projectGraph
|
||||
);
|
||||
const ctProjectConfig = ctExecutorContext.projectGraph.nodes[
|
||||
ctExecutorContext.projectName
|
||||
].data as ProjectConfiguration;
|
||||
// angular only supports `tailwind.config.{js,cjs}`
|
||||
const ctProjectTailwindConfig = join(ctProjectConfig.root, 'tailwind.config');
|
||||
const isTailWindInCtProject = !!mappedGraph.allFiles[ctProjectTailwindConfig];
|
||||
const isTailWindInRoot = !!mappedGraph.allFiles['tailwind.config'];
|
||||
const isTailWindInCtProject = !!mappedGraphFiles[ctProjectTailwindConfig];
|
||||
const isTailWindInRoot = !!mappedGraphFiles['tailwind.config'];
|
||||
|
||||
if (isTailWindInRoot || isTailWindInCtProject) {
|
||||
const pathToStyle = getTempTailwindPath(ctExecutorContext);
|
||||
|
||||
@ -9,7 +9,7 @@ import {
|
||||
workspaceRoot,
|
||||
} from '@nrwl/devkit';
|
||||
import { readProjectsConfigurationFromProjectGraph } from 'nx/src/project-graph/project-graph';
|
||||
import { mapProjectGraphFiles } from 'nx/src/utils/target-project-locator';
|
||||
import { createProjectFileMappings } from 'nx/src/utils/target-project-locator';
|
||||
import { dirname, extname, join, relative } from 'path';
|
||||
import { lstatSync } from 'fs';
|
||||
|
||||
@ -90,9 +90,9 @@ export function getProjectConfigByPath(
|
||||
: configFileFromWorkspaceRoot
|
||||
);
|
||||
|
||||
const mappedGraph = mapProjectGraphFiles(graph);
|
||||
const mappedGraphFiles = createProjectFileMappings(graph);
|
||||
const componentTestingProjectName =
|
||||
mappedGraph.allFiles[normalizedPathFromWorkspaceRoot];
|
||||
mappedGraphFiles[normalizedPathFromWorkspaceRoot];
|
||||
if (
|
||||
!componentTestingProjectName ||
|
||||
!graph.nodes[componentTestingProjectName]?.data
|
||||
|
||||
@ -5,7 +5,7 @@ import { TSESLint } from '@typescript-eslint/utils';
|
||||
import { vol } from 'memfs';
|
||||
import {
|
||||
TargetProjectLocator,
|
||||
mapProjectGraphFiles,
|
||||
createProjectFileMappings,
|
||||
} from 'nx/src/utils/target-project-locator';
|
||||
import enforceModuleBoundaries, {
|
||||
RULE_NAME as enforceModuleBoundariesRuleName,
|
||||
@ -1885,7 +1885,9 @@ function runRule(
|
||||
projectGraph: ProjectGraph
|
||||
): TSESLint.Linter.LintMessage[] {
|
||||
(global as any).projectPath = `${process.cwd()}/proj`;
|
||||
(global as any).projectGraph = mapProjectGraphFiles(projectGraph);
|
||||
(global as any).projectGraph = projectGraph;
|
||||
(global as any).projectGraphFileMappings =
|
||||
createProjectFileMappings(projectGraph);
|
||||
(global as any).targetProjectLocator = new TargetProjectLocator(
|
||||
projectGraph.nodes,
|
||||
projectGraph.externalNodes
|
||||
|
||||
@ -154,7 +154,8 @@ export default createESLintRule<Options, MessageIds>({
|
||||
);
|
||||
const fileName = normalizePath(context.getFilename());
|
||||
|
||||
const projectGraph = readProjectGraph(RULE_NAME);
|
||||
const { projectGraph, projectGraphFileMappings } =
|
||||
readProjectGraph(RULE_NAME);
|
||||
|
||||
if (!projectGraph) {
|
||||
return {};
|
||||
@ -198,7 +199,11 @@ export default createESLintRule<Options, MessageIds>({
|
||||
|
||||
const sourceFilePath = getSourceFilePath(fileName, projectPath);
|
||||
|
||||
const sourceProject = findSourceProject(projectGraph, sourceFilePath);
|
||||
const sourceProject = findSourceProject(
|
||||
projectGraph,
|
||||
projectGraphFileMappings,
|
||||
sourceFilePath
|
||||
);
|
||||
// If source is not part of an nx workspace, return.
|
||||
if (!sourceProject) {
|
||||
return;
|
||||
@ -210,12 +215,17 @@ export default createESLintRule<Options, MessageIds>({
|
||||
let targetProject: ProjectGraphProjectNode | ProjectGraphExternalNode;
|
||||
|
||||
if (isAbsoluteImportIntoAnotherProj) {
|
||||
targetProject = findTargetProject(projectGraph, imp);
|
||||
targetProject = findTargetProject(
|
||||
projectGraph,
|
||||
projectGraphFileMappings,
|
||||
imp
|
||||
);
|
||||
} else {
|
||||
targetProject = getTargetProjectBasedOnRelativeImport(
|
||||
imp,
|
||||
projectPath,
|
||||
projectGraph,
|
||||
projectGraphFileMappings,
|
||||
sourceFilePath
|
||||
);
|
||||
}
|
||||
|
||||
@ -87,14 +87,19 @@ export default createESLintRule<Options, MessageIds>({
|
||||
return {};
|
||||
}
|
||||
|
||||
const projectGraph = readProjectGraph(RULE_NAME);
|
||||
const { projectGraph, projectGraphFileMappings } =
|
||||
readProjectGraph(RULE_NAME);
|
||||
|
||||
const sourceFilePath = getSourceFilePath(
|
||||
context.getFilename(),
|
||||
workspaceRoot
|
||||
);
|
||||
|
||||
const sourceProject = findSourceProject(projectGraph, sourceFilePath);
|
||||
const sourceProject = findSourceProject(
|
||||
projectGraph,
|
||||
projectGraphFileMappings,
|
||||
sourceFilePath
|
||||
);
|
||||
// If source is not part of an nx workspace, return.
|
||||
if (!sourceProject) {
|
||||
return {};
|
||||
|
||||
@ -1,8 +1,5 @@
|
||||
import { readCachedProjectGraph, readNxJson } from '@nrwl/devkit';
|
||||
import {
|
||||
mapProjectGraphFiles,
|
||||
MappedProjectGraph,
|
||||
} from 'nx/src/utils/target-project-locator';
|
||||
import { ProjectGraph, readCachedProjectGraph, readNxJson } from '@nrwl/devkit';
|
||||
import { createProjectFileMappings } from 'nx/src/utils/target-project-locator';
|
||||
import { isTerminalRun } from './runtime-lint-utils';
|
||||
import * as chalk from 'chalk';
|
||||
|
||||
@ -11,7 +8,11 @@ export function ensureGlobalProjectGraph(ruleName: string) {
|
||||
* Only reuse graph when running from terminal
|
||||
* Enforce every IDE change to get a fresh nxdeps.json
|
||||
*/
|
||||
if (!(global as any).projectGraph || !isTerminalRun()) {
|
||||
if (
|
||||
!(global as any).projectGraph ||
|
||||
!(global as any).projectGraphFileMappings ||
|
||||
!isTerminalRun()
|
||||
) {
|
||||
const nxJson = readNxJson();
|
||||
(global as any).workspaceLayout = nxJson.workspaceLayout;
|
||||
|
||||
@ -20,8 +21,9 @@ export function ensureGlobalProjectGraph(ruleName: string) {
|
||||
* the ProjectGraph may or may not exist by the time the lint rule is invoked for the first time.
|
||||
*/
|
||||
try {
|
||||
(global as any).projectGraph = mapProjectGraphFiles(
|
||||
readCachedProjectGraph()
|
||||
(global as any).projectGraph = readCachedProjectGraph();
|
||||
(global as any).projectGraphFileMappings = createProjectFileMappings(
|
||||
(global as any).projectGraph
|
||||
);
|
||||
} catch {
|
||||
const WARNING_PREFIX = `${chalk.reset.keyword('orange')('warning')}`;
|
||||
@ -34,7 +36,13 @@ export function ensureGlobalProjectGraph(ruleName: string) {
|
||||
}
|
||||
}
|
||||
|
||||
export function readProjectGraph(ruleName: string) {
|
||||
export function readProjectGraph(ruleName: string): {
|
||||
projectGraph: ProjectGraph;
|
||||
projectGraphFileMappings: Record<string, string>;
|
||||
} {
|
||||
ensureGlobalProjectGraph(ruleName);
|
||||
return (global as any).projectGraph as MappedProjectGraph;
|
||||
return {
|
||||
projectGraph: (global as any).projectGraph,
|
||||
projectGraphFileMappings: (global as any).projectGraphFileMappings,
|
||||
};
|
||||
}
|
||||
|
||||
@ -16,7 +16,6 @@ import { existsSync } from 'fs';
|
||||
import { readFileIfExisting } from 'nx/src/project-graph/file-utils';
|
||||
import {
|
||||
TargetProjectLocator,
|
||||
MappedProjectGraph,
|
||||
removeExt,
|
||||
} from 'nx/src/utils/target-project-locator';
|
||||
|
||||
@ -99,7 +98,8 @@ export function isRelative(s: string) {
|
||||
export function getTargetProjectBasedOnRelativeImport(
|
||||
imp: string,
|
||||
projectPath: string,
|
||||
projectGraph: MappedProjectGraph,
|
||||
projectGraph: ProjectGraph,
|
||||
projectGraphFileMappings: Record<string, string>,
|
||||
sourceFilePath: string
|
||||
): ProjectGraphProjectNode<any> | undefined {
|
||||
if (!isRelative(imp)) {
|
||||
@ -111,38 +111,51 @@ export function getTargetProjectBasedOnRelativeImport(
|
||||
projectPath.length + 1
|
||||
);
|
||||
|
||||
return findTargetProject(projectGraph, targetFile);
|
||||
return findTargetProject(projectGraph, projectGraphFileMappings, targetFile);
|
||||
}
|
||||
|
||||
export function findProjectUsingFile<T>(
|
||||
projectGraph: MappedProjectGraph<T>,
|
||||
function findProjectUsingFile(
|
||||
projectGraph: ProjectGraph,
|
||||
projectGraphFileMappings: Record<string, string>,
|
||||
file: string
|
||||
): ProjectGraphProjectNode {
|
||||
return projectGraph.nodes[projectGraph.allFiles[file]];
|
||||
return projectGraph.nodes[projectGraphFileMappings[file]];
|
||||
}
|
||||
|
||||
export function findSourceProject(
|
||||
projectGraph: MappedProjectGraph,
|
||||
projectGraph: ProjectGraph,
|
||||
projectGraphFileMappings: Record<string, string>,
|
||||
sourceFilePath: string
|
||||
) {
|
||||
const targetFile = removeExt(sourceFilePath);
|
||||
return findProjectUsingFile(projectGraph, targetFile);
|
||||
return findProjectUsingFile(
|
||||
projectGraph,
|
||||
projectGraphFileMappings,
|
||||
targetFile
|
||||
);
|
||||
}
|
||||
|
||||
export function findTargetProject(
|
||||
projectGraph: MappedProjectGraph,
|
||||
projectGraph: ProjectGraph,
|
||||
projectGraphFileMappings: Record<string, string>,
|
||||
targetFile: string
|
||||
) {
|
||||
let targetProject = findProjectUsingFile(projectGraph, targetFile);
|
||||
let targetProject = findProjectUsingFile(
|
||||
projectGraph,
|
||||
projectGraphFileMappings,
|
||||
targetFile
|
||||
);
|
||||
if (!targetProject) {
|
||||
targetProject = findProjectUsingFile(
|
||||
projectGraph,
|
||||
projectGraphFileMappings,
|
||||
normalizePath(path.join(targetFile, 'index'))
|
||||
);
|
||||
}
|
||||
if (!targetProject) {
|
||||
targetProject = findProjectUsingFile(
|
||||
projectGraph,
|
||||
projectGraphFileMappings,
|
||||
normalizePath(path.join(targetFile, 'src', 'index'))
|
||||
);
|
||||
}
|
||||
@ -162,7 +175,7 @@ export function isAbsoluteImportIntoAnotherProject(
|
||||
}
|
||||
|
||||
export function findProjectUsingImport(
|
||||
projectGraph: MappedProjectGraph,
|
||||
projectGraph: ProjectGraph,
|
||||
targetProjectLocator: TargetProjectLocator,
|
||||
filePath: string,
|
||||
imp: string
|
||||
|
||||
@ -206,7 +206,7 @@ function filterRootExternalDependencies(
|
||||
*/
|
||||
export function createProjectRootMappings(
|
||||
nodes: Record<string, ProjectGraphProjectNode>
|
||||
) {
|
||||
): Map<string, string> {
|
||||
const projectRootMappings = new Map<string, string>();
|
||||
for (const projectName of Object.keys(nodes)) {
|
||||
const root = nodes[projectName].data.root;
|
||||
@ -218,10 +218,6 @@ export function createProjectRootMappings(
|
||||
return projectRootMappings;
|
||||
}
|
||||
|
||||
export type MappedProjectGraph<T = any> = ProjectGraph<T> & {
|
||||
allFiles: Record<string, string>;
|
||||
};
|
||||
|
||||
/**
|
||||
* Strips the file extension from the file path
|
||||
* @param file
|
||||
@ -237,26 +233,20 @@ export function removeExt(file: string): string {
|
||||
* @param projectGraph
|
||||
* @returns
|
||||
*/
|
||||
export function mapProjectGraphFiles<T>(
|
||||
projectGraph: ProjectGraph<T>
|
||||
): MappedProjectGraph | null {
|
||||
if (!projectGraph) {
|
||||
return null;
|
||||
}
|
||||
const allFiles: Record<string, string> = {};
|
||||
export function createProjectFileMappings(
|
||||
projectGraph: ProjectGraph
|
||||
): Record<string, string> {
|
||||
const result: Record<string, string> = {};
|
||||
Object.entries(
|
||||
projectGraph.nodes as Record<string, ProjectGraphProjectNode>
|
||||
).forEach(([name, node]) => {
|
||||
node.data.files.forEach(({ file }) => {
|
||||
const fileName = removeExt(file);
|
||||
allFiles[fileName] = name;
|
||||
result[fileName] = name;
|
||||
});
|
||||
});
|
||||
|
||||
return {
|
||||
...projectGraph,
|
||||
allFiles,
|
||||
};
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user