From ca9983aac2dabb00175cfc87623500aadd0a4e09 Mon Sep 17 00:00:00 2001 From: nieyuyao Date: Sat, 4 Jun 2022 16:48:54 +0800 Subject: [PATCH 1/2] fix: show full name for external mod at graph --- packages/ui/client/composables/module-graph.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/ui/client/composables/module-graph.ts b/packages/ui/client/composables/module-graph.ts index 24868a2685a5..0ba87599045a 100644 --- a/packages/ui/client/composables/module-graph.ts +++ b/packages/ui/client/composables/module-graph.ts @@ -12,7 +12,7 @@ export type ModuleGraphConfig = GraphConfig function defineExternalModuleNode(module: string): ModuleNode { let label = module if (label.includes('/node_modules/')) - label = label.split(/\/node_modules\//g).pop()!.split(/\//g).shift()! + label = label.split(/\/node_modules\//g).pop()! else label = label.split(/\//g).pop()! From 1d0a97b6aee13510fc600795a193a391c6ab2953 Mon Sep 17 00:00:00 2001 From: nieyuyao Date: Sat, 11 Jun 2022 14:11:17 +0800 Subject: [PATCH 2/2] fix: calculate label of external mod --- .../ui/client/composables/module-graph.ts | 103 +++++++++++++++--- test/core/test/module-label.test.ts | 50 +++++++++ 2 files changed, 137 insertions(+), 16 deletions(-) create mode 100644 test/core/test/module-label.test.ts diff --git a/packages/ui/client/composables/module-graph.ts b/packages/ui/client/composables/module-graph.ts index 0ba87599045a..5c2ce2145c67 100644 --- a/packages/ui/client/composables/module-graph.ts +++ b/packages/ui/client/composables/module-graph.ts @@ -9,23 +9,94 @@ export type ModuleGraph = Graph export type ModuleGraphController = GraphController export type ModuleGraphConfig = GraphConfig -function defineExternalModuleNode(module: string): ModuleNode { - let label = module - if (label.includes('/node_modules/')) - label = label.split(/\/node_modules\//g).pop()! - else - label = label.split(/\//g).pop()! +export interface ModuleLabelItem { + id: string + raw: string + splits: string[] + candidate: string + finished: boolean +} - return defineNode({ - color: 'var(--color-node-external)', - label: { - color: 'var(--color-node-external)', - fontSize: '0.875rem', - text: label, - }, - isFocused: false, +export function calcExternalLabels(labels: ModuleLabelItem[]): Map { + const result: Map = new Map() + const splitMap: Map = new Map() + const firsts: number[] = [] + while (true) { + let finishedCount = 0 + labels.forEach((label, i) => { + const { splits, finished } = label + // record the candidate as final label text when label is marked finished + if (finished) { + finishedCount++ + const { raw, candidate } = label + result.set(raw, candidate) + return + } + if (splits.length === 0) { + label.finished = true + return + } + const head = splits[0] + if (splitMap.has(head)) { + label.candidate += label.candidate === '' ? head : `/${head}` + splitMap.get(head)?.push(i) + splits.shift() + // eslint-disable-next-line @typescript-eslint/brace-style + } else { + splitMap.set(head, [i]) + // record the index of the label where the head first appears + firsts.push(i) + } + }) + // update candidate of label which index appears in first array + firsts.forEach((i) => { + const label = labels[i] + const head = label.splits.shift() + label.candidate += label.candidate === '' ? head : `/${head}` + }) + splitMap.forEach((value) => { + if (value.length === 1) { + const index = value[0] + labels[index].finished = true + } + }) + splitMap.clear() + firsts.length = 0 + if (finishedCount === labels.length) + break + } + return result +} + +export function createModuleLabelItem(module: string): ModuleLabelItem { + let raw = module + if (raw.includes('/node_modules/')) + raw = module.split(/\/node_modules\//g).pop()! + const splits = raw.split(/\//g) + return { + raw, + splits, + candidate: '', + finished: false, id: module, - type: 'external', + } +} + +function defineExternalModuleNodes(modules: string[]): ModuleNode[] { + const labels: ModuleLabelItem[] = modules.map(module => createModuleLabelItem(module)) + const map = calcExternalLabels(labels) + return labels.map(({ raw, id }) => { + return defineNode({ + color: 'var(--color-node-external)', + label: { + color: 'var(--color-node-external)', + fontSize: '0.875rem', + text: map.get(raw) ?? '', + }, + isFocused: false, + id, + type: 'external', + }) }) } @@ -47,7 +118,7 @@ export function getModuleGraph(data: ModuleGraphData, rootPath: string | undefin if (!data) return defineGraph({}) - const externalizedNodes = data.externalized.map(module => defineExternalModuleNode(module)) ?? [] + const externalizedNodes = defineExternalModuleNodes(data.externalized) const inlinedNodes = data.inlined.map(module => defineInlineModuleNode(module, module === rootPath)) ?? [] const nodes = [...externalizedNodes, ...inlinedNodes] const nodeMap = Object.fromEntries(nodes.map(node => [node.id, node])) diff --git a/test/core/test/module-label.test.ts b/test/core/test/module-label.test.ts new file mode 100644 index 000000000000..ca495530fc32 --- /dev/null +++ b/test/core/test/module-label.test.ts @@ -0,0 +1,50 @@ +import { expect, test } from 'vitest' +import { calcExternalLabels, createModuleLabelItem } from '../../../packages/ui/client/composables/module-graph' + +const getExternalLabelsObj = (modules: string[]) => { + const labels = modules.map(module => createModuleLabelItem(module)) + return Object.fromEntries(calcExternalLabels(labels)) +} + +test('calculate label of external module', () => { + const modules1: string[] = [] + expect(getExternalLabelsObj(modules1)).toEqual({}) + const modules2 = [''] + expect(getExternalLabelsObj(modules2)).toEqual({ '': '' }) + const modules3 = [ + 'org/testA', + 'org/testB', + ] + expect(getExternalLabelsObj(modules3)).toEqual({ + 'org/testA': 'org/testA', + 'org/testB': 'org/testB', + }) + const modules4 = [...modules3, 'org/testC'] + expect(getExternalLabelsObj(modules4)).toEqual({ + 'org/testA': 'org/testA', + 'org/testB': 'org/testB', + 'org/testC': 'org/testC', + }) + const modules5 = [ + 'orgA', + 'orgB', + ] + expect(getExternalLabelsObj(modules5)).toEqual({ + orgA: 'orgA', + orgB: 'orgB', + }) + const modules6 = ['orgA', 'orgB', 'orgA/dist'] + expect(getExternalLabelsObj(modules6)).toEqual({ + 'orgA': 'orgA', + 'orgB': 'orgB', + 'orgA/dist': 'orgA/dist', + }) + const modules7 = [ + '@testing-library/jest-dom/dist/index.js', + '@testing-library/react/dist/index.js', + ] + expect(getExternalLabelsObj(modules7)).toEqual({ + '@testing-library/jest-dom/dist/index.js': '@testing-library/jest-dom', + '@testing-library/react/dist/index.js': '@testing-library/react', + }) +})