Press n or j to go to the next uncovered block, b, p or k for the previous block.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 | 7x 7x 7x 7x 7x 7x 28x 4x 24x 24x 6x 18x 24x 11x 13x 13x 13x 18x 2x 2x 2x 18x 11x 25x 11x 6x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 5x 5x 5x 13x 7x 52x 11x 11x 11x 33x 22x 11x 8x 8x 8x 3x 3x 11x | import { parse, ParserPlugin } from '@babel/parser' import MagicString from 'magic-string' const defaultExportRE = /((?:^|\n|;)\s*)export(\s*)default/ const namedDefaultExportRE = /((?:^|\n|;)\s*)export(.+)(?:as)?(\s*)default/s const exportDefaultClassRE = /((?:^|\n|;)\s*)export\s+default\s+class\s+([\w$]+)/ /** * Utility for rewriting `export default` in a script block into a variable * declaration so that we can inject things into it */ export function rewriteDefault( input: string, as: string, parserPlugins?: ParserPlugin[] ): string { if (!hasDefaultExport(input)) { return input + `\nconst ${as} = {}` } let replaced: string | undefined const classMatch = input.match(exportDefaultClassRE) if (classMatch) { replaced = input.replace(exportDefaultClassRE, '$1class $2') + `\nconst ${as} = ${classMatch[2]}` } else { replaced = input.replace(defaultExportRE, `$1const ${as} =`) } if (!hasDefaultExport(replaced)) { return replaced } // if the script somehow still contains `default export`, it probably has // multi-line comments or template strings. fallback to a full parse. const s = new MagicString(input) const ast = parse(input, { sourceType: 'module', plugins: parserPlugins }).program.body ast.forEach(node => { if (node.type === 'ExportDefaultDeclaration') { if (node.declaration.type === 'ClassDeclaration') { s.overwrite(node.start!, node.declaration.id.start!, `class `) s.append(`\nconst ${as} = ${node.declaration.id.name}`) } else E{ s.overwrite(node.start!, node.declaration.start!, `const ${as} = `) } } if (node.type === 'ExportNamedDeclaration') { for (const specifier of node.specifiers) { if ( specifier.type === 'ExportSpecifier' && specifier.exported.type === 'Identifier' && specifier.exported.name === 'default' ) { if (node.source) { if (specifier.local.name === 'default') { const end = specifierEnd(input, specifier.local.end!, node.end) s.prepend( `import { default as __VUE_DEFAULT__ } from '${node.source.value}'\n` ) s.overwrite(specifier.start!, end, ``) s.append(`\nconst ${as} = __VUE_DEFAULT__`) continue } else { const end = specifierEnd(input, specifier.exported.end!, node.end) s.prepend( `import { ${input.slice( specifier.local.start!, specifier.local.end! )} } from '${node.source.value}'\n` ) s.overwrite(specifier.start!, end, ``) s.append(`\nconst ${as} = ${specifier.local.name}`) continue } } const end = specifierEnd(input, specifier.end!, node.end) s.overwrite(specifier.start!, end, ``) s.append(`\nconst ${as} = ${specifier.local.name}`) } } } }) return s.toString() } export function hasDefaultExport(input: string): boolean { return defaultExportRE.test(input) || namedDefaultExportRE.test(input) } function specifierEnd(input: string, end: number, nodeEnd: number | null) { // export { default , foo } ... let hasCommas = false let oldEnd = end while (end < nodeEnd!) { if (/\s/.test(input.charAt(end))) { end++ } else if (input.charAt(end) === ',') { end++ hasCommas = true break } else if (input.charAt(end) === '}') { break } } return hasCommas ? end : oldEnd } |