From cbd08422b0e837a8b0b659bd77f128aa6c367981 Mon Sep 17 00:00:00 2001 From: Alec Larson <1925840+aleclarson@users.noreply.github.com> Date: Tue, 15 Nov 2022 15:20:42 -0500 Subject: [PATCH] fix: support `export type` rewrites --- packages/vite/scripts/emitCjsTypes.ts | 49 +++++++++++++++++++++++++-- 1 file changed, 47 insertions(+), 2 deletions(-) diff --git a/packages/vite/scripts/emitCjsTypes.ts b/packages/vite/scripts/emitCjsTypes.ts index ed7bec34c72411..448071c5943c32 100644 --- a/packages/vite/scripts/emitCjsTypes.ts +++ b/packages/vite/scripts/emitCjsTypes.ts @@ -14,9 +14,14 @@ async function main() { let text = fs.readFileSync(file, 'utf8') const [imports] = lexer.parse(text) - for (const i of [...imports].reverse()) { + const typeImports = parseTypeImports(text, true) + const allImports = [...imports, ...typeImports] + // In reverse order + .sort((a, b) => b.s - a.s) + + for (const i of allImports) { let id = i.n - if (!id || !/^\.\.?(?:\/|$)/.test(id)) { + if (!id || !/^\.\.?(?:\/|$)/.test(id) || id.endsWith('.cjs')) { continue } @@ -48,4 +53,44 @@ function isDirectory(file: string) { } } +// This assumes no each import/export statement is on its own line. +function parseTypeImports(code: string, exportsOnly?: boolean) { + const imports = [] + + const openKeywords = exportsOnly ? ['export'] : ['import', 'export'] + const openPattern = [['', '\n'], openKeywords, ['type']] + const fromPattern = [['from'], ['"', "'"]] + + let cursor = 0 + let pattern = openPattern + let patternIndex = 0 + + const words = code.split(/([\w/\-@.]+|\n)/g) + for (let i = 0; i < words.length; i++) { + const word = words[i].replace(/ /g, '') + if (pattern[patternIndex].includes(word)) { + if (++patternIndex === pattern.length) { + patternIndex = 0 + if (pattern === openPattern) { + pattern = fromPattern + } else if (pattern === fromPattern) { + pattern = openPattern + const moduleSpecifier = words[i + 1] + const start = cursor + words[i].length + imports.push({ + s: start, + e: start + moduleSpecifier.length, + n: moduleSpecifier + }) + } + } + } else if (patternIndex > 0 && word) { + patternIndex = 0 + } + cursor += words[i].length + } + + return imports +} + main()