fix(auto-import): improve auto-import regex (#2172)

This commit is contained in:
Anthony Fu 2021-11-29 19:17:51 +08:00 committed by GitHub
parent 8a6db589fe
commit f5d1d9a208
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -5,7 +5,7 @@ import { AutoImportContext } from './context'
const excludeRE = [
// imported from other module
/\bimport\s*([\w_$]*?),?\s*(?:\{([\s\S]*?)\})?\s*from\b/g,
/\bimport\s*([\s\S]+?)\s*from\b/g,
// defined as function
/\bfunction\s*([\w_$]+?)\s*\(/g,
// defined as local variable
@ -14,13 +14,21 @@ const excludeRE = [
const importAsRE = /^.*\sas\s+/
const seperatorRE = /[,[\]{}\n]/g
const multilineCommentsRE = /\/\*(.|[\r\n])*?\*\//gm
const singlelineCommentsRE = /^\s*\/\/.*$/gm
const multilineCommentsRE = /\/\*\s(.|[\r\n])*?\*\//gm
const singlelineCommentsRE = /\/\/\s.*/g
const templateLiteralRE = /\$\{(.*)\}/g
const quotesRE = [
/(["'])((?:\\\1|(?!\1)|.|\r)*?)\1/gm,
/([`])((?:\\\1|(?!\1)|.|\n|\r)*?)\1/gm
]
function stripeComments (code: string) {
function stripeCommentsAndStrings (code: string) {
return code
.replace(multilineCommentsRE, '')
.replace(singlelineCommentsRE, '')
.replace(templateLiteralRE, '` + $1 + `')
.replace(quotesRE[0], '""')
.replace(quotesRE[1], '``')
}
export const TransformPlugin = createUnplugin((ctx: AutoImportContext) => {
@ -50,20 +58,19 @@ export const TransformPlugin = createUnplugin((ctx: AutoImportContext) => {
},
transform (code) {
// strip comments so we don't match on them
const withoutComment = stripeComments(code)
const striped = stripeCommentsAndStrings(code)
// find all possible injection
const matched = new Set(Array.from(withoutComment.matchAll(ctx.matchRE)).map(i => i[1]))
const matched = new Set(Array.from(striped.matchAll(ctx.matchRE)).map(i => i[1]))
// remove those already defined
for (const regex of excludeRE) {
Array.from(withoutComment.matchAll(regex))
Array.from(striped.matchAll(regex))
.flatMap(i => [
...(i[1]?.split(seperatorRE) || []),
...(i[2]?.split(seperatorRE) || [])
])
.map(i => i.replace(importAsRE, '').trim())
.filter(Boolean)
.forEach(i => matched.delete(i))
}