MCPcopy
hub / github.com/nuxt/nuxt / handler

Function handler

packages/nuxt/src/components/plugins/tree-shake.ts:29–105  ·  view source on GitHub ↗
(code, id)

Source from the content-addressed store, hash-verified

27 id: { include: VUE_ID_RE },
28 },
29 handler (code, id) {
30 const components = options.getComponents()
31
32 if (!regexpMap.has(components)) {
33 const serverPlaceholderPath = resolve(distDir, 'app/components/server-placeholder')
34 const clientOnlyComponents = components
35 .filter(c => c.mode === 'client' && !components.some(other => other.mode !== 'client' && other.pascalName === c.pascalName && !other.filePath.startsWith(serverPlaceholderPath)))
36 .flatMap(c => [c.pascalName, c.kebabName.replaceAll('-', '_')])
37 .concat(['ClientOnly', 'client_only'])
38
39 regexpMap.set(components, [new RegExp(`(${clientOnlyComponents.join('|')})`), new RegExp(`^(${clientOnlyComponents.map(c => `(?:(?:_unref\\()?(?:_component_)?(?:Lazy|lazy_)?${c}\\)?)`).join('|')})$`), clientOnlyComponents])
40 }
41
42 const s = new MagicString(code)
43
44 const [COMPONENTS_RE, COMPONENTS_IDENTIFIERS_RE] = regexpMap.get(components)!
45 if (!COMPONENTS_RE.test(code)) { return }
46
47 const componentsToRemoveSet = new Set<string>()
48
49 // remove client only components or components called in ClientOnly default slot
50 const { program: ast } = parseAndWalk(code, id, (node) => {
51 if (!isSsrRender(node)) {
52 return
53 }
54
55 const [componentCall, _, children] = node.arguments
56 if (!componentCall) { return }
57
58 if (componentCall.type === 'Identifier' || componentCall.type === 'MemberExpression' || componentCall.type === 'CallExpression') {
59 const componentName = getComponentName(node)
60 if (!componentName || !COMPONENTS_IDENTIFIERS_RE.test(componentName) || children?.type !== 'ObjectExpression') { return }
61
62 const isClientOnlyComponent = CLIENT_ONLY_NAME_RE.test(componentName)
63 const slotsToRemove = isClientOnlyComponent ? children.properties.filter(prop => prop.type === 'Property' && prop.key.type === 'Identifier' && !PLACEHOLDER_EXACT_RE.test(prop.key.name)) : children.properties
64
65 for (const slot of slotsToRemove) {
66 s.remove(slot.start, slot.end + 1)
67 const removedCode = `({${code.slice(slot.start, slot.end + 1)}})`
68 const currentState = s.toString()
69
70 parseAndWalk(removedCode, id, (node) => {
71 if (!isSsrRender(node)) { return }
72 const name = getComponentName(node)
73 if (!name) { return }
74
75 // detect if the component is called else where
76 const nameToRemove = isComponentNotCalledInSetup(currentState, id, name)
77 if (nameToRemove) {
78 componentsToRemoveSet.add(nameToRemove)
79 }
80 })
81 }
82 }
83 })
84
85 const componentsToRemove = [...componentsToRemoveSet]
86 const removedNodes = new WeakSet<Node>()

Callers

nothing calls this directly

Calls 10

isSsrRenderFunction · 0.85
getComponentNameFunction · 0.85
removeImportDeclarationFunction · 0.85
removeVariableDeclaratorFunction · 0.85
removeFromSetupReturnFunction · 0.85
setMethod · 0.80
getMethod · 0.80
toStringMethod · 0.80
getComponentsMethod · 0.65

Tested by

no test coverage detected

Used in the wild real call sites across dependent graphs

searching dependent graphs…