Skip to content

Commit

Permalink
fix: keep variable in template string for import meta URL parse
Browse files Browse the repository at this point in the history
  • Loading branch information
fi3ework committed Apr 9, 2022
1 parent 09c4fc0 commit c400f87
Show file tree
Hide file tree
Showing 4 changed files with 54 additions and 12 deletions.
23 changes: 23 additions & 0 deletions packages/vite/src/node/__tests__/utils.spec.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import {
dropStringLiteralsFromString,
getPotentialTsSrcPaths,
injectQuery,
isWindows,
Expand Down Expand Up @@ -97,3 +98,25 @@ test('ts import of file with .js and query param', () => {
'test-file.js.tsx?lee=123'
])
})

test('drop string literals from string', () => {
const c1 = { raw: `console.log(ab)`, expected: `console.log(ab)` }
const c2 = { raw: `console.log('ab')`, expected: `console.log(' ')` }
const c3 = {
raw: `console.log(ab + "cd")`,
expected: `console.log(ab + '\0\0')`
}
const c4 = {
raw: 'console.log(`ab${cd}ef`)',
expected: 'console.log(`\0\0${cd}\0\0`)'
}
const c5 = {
raw: 'console.log(`ab${cd + "ef"}gh`)',
expected: "console.log(`\0\0${cd + '\0\0'}\0\0`)"
}

expect(dropStringLiteralsFromString(c2.raw, ' ')).toBe(c2.expected)
;[c1, c3, c4, c5].forEach(({ raw, expected }) => {
expect(dropStringLiteralsFromString(raw, '\0')).toBe(expected)
})
})
10 changes: 5 additions & 5 deletions packages/vite/src/node/plugins/assetImportMetaUrl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@ import path from 'path'
import { fileToUrl } from './asset'
import type { ResolvedConfig } from '../config'
import {
blankReplacer,
dropStringLiteralsFromString,
multilineCommentsRE,
singlelineCommentsRE,
stringsRE,
blankReplacer
singlelineCommentsRE
} from '../utils'

/**
Expand All @@ -34,11 +34,11 @@ export function assetImportMetaUrlPlugin(config: ResolvedConfig): Plugin {
const noCommentsCode = code
.replace(multilineCommentsRE, blankReplacer)
.replace(singlelineCommentsRE, blankReplacer)
.replace(stringsRE, (m) => `'${'\0'.repeat(m.length - 2)}'`)
const noStringCode = dropStringLiteralsFromString(noCommentsCode, '\0')

let s: MagicString | null = null
let match: RegExpExecArray | null
while ((match = importMetaUrlRE.exec(noCommentsCode))) {
while ((match = importMetaUrlRE.exec(noStringCode))) {
const { 0: exp, 1: emptyUrl, index } = match

const urlStart = exp.indexOf(emptyUrl) + index
Expand Down
9 changes: 3 additions & 6 deletions packages/vite/src/node/plugins/workerImportMetaUrl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@ import { fileToUrl } from './asset'
import {
blankReplacer,
cleanUrl,
dropStringLiteralsFromString,
injectQuery,
multilineCommentsRE,
singlelineCommentsRE,
stringsRE
singlelineCommentsRE
} from '../utils'
import path from 'path'
import { workerFileToUrl } from './worker'
Expand Down Expand Up @@ -124,10 +124,7 @@ export function workerImportMetaUrlPlugin(config: ResolvedConfig): Plugin {
.replace(multilineCommentsRE, blankReplacer)
.replace(singlelineCommentsRE, blankReplacer)

const noStringCode = noCommentsCode.replace(
stringsRE,
(m) => `'${' '.repeat(m.length - 2)}'`
)
const noStringCode = dropStringLiteralsFromString(noCommentsCode, ' ')
let match: RegExpExecArray | null
let s: MagicString | null = null
while ((match = importMetaUrlRE.exec(noStringCode))) {
Expand Down
24 changes: 23 additions & 1 deletion packages/vite/src/node/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -733,4 +733,26 @@ export function parseRequest(id: string): Record<string, string> | null {
}

export const blankReplacer = (match: string) => ' '.repeat(match.length)
export const stringsRE = /"[^"]*"|'[^']*'|`[^`]*`/g

export function dropStringLiteralsFromString(
code: string,
replacer: string
): string {
let result = code

const templateLiteralMatch = code.match(/`[^`]*`/g)
if (templateLiteralMatch) {
const templateLiteralRE = /`([^`]*)\$\{([^}]+)\}([^`]*)`/g
result = result.replace(
templateLiteralRE,
(full, prefix, variable, suffix) => {
const prefixPadding = replacer.repeat(prefix.length)
const suffixPadding = replacer.repeat(suffix.length)
return `\`${prefixPadding}\$\{${variable}\}${suffixPadding}\``
}
)
}

const stringsRE = /"[^"]*"|'[^']*'/g
return result.replace(stringsRE, (m) => `'${replacer.repeat(m.length - 2)}'`)
}

0 comments on commit c400f87

Please sign in to comment.