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 | 7x 7x 7x 7x 7x 7x 24x 4x 20x 20x 3x 17x 20x 8x 12x 12x 12x 17x 1x 17x 11x 25x 11x 6x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 5x 5x 5x 12x 7x 44x 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') { 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 } |