Skip to content

Commit 454e2d1

Browse files
authored
refactor: remove acorn (#16238)
1 parent f599ab4 commit 454e2d1

File tree

9 files changed

+177
-247
lines changed

9 files changed

+177
-247
lines changed

package.json

+3-14
Original file line numberDiff line numberDiff line change
@@ -104,22 +104,11 @@
104104
"overrides": {
105105
"vite": "workspace:*"
106106
},
107-
"packageExtensions": {
108-
"acorn-walk": {
109-
"peerDependencies": {
110-
"acorn": "*"
111-
},
112-
"peerDependenciesMeta": {
113-
"acorn": {
114-
"optional": true
115-
}
116-
}
117-
}
118-
},
119107
"patchedDependencies": {
108+
"acorn@8.11.3": "patches/acorn@8.11.3.patch",
120109
"chokidar@3.6.0": "patches/chokidar@3.6.0.patch",
121-
"sirv@2.0.4": "patches/sirv@2.0.4.patch",
122-
"http-proxy@1.18.1": "patches/http-proxy@1.18.1.patch"
110+
"http-proxy@1.18.1": "patches/http-proxy@1.18.1.patch",
111+
"sirv@2.0.4": "patches/sirv@2.0.4.patch"
123112
},
124113
"peerDependencyRules": {
125114
"allowedVersions": {

packages/vite/LICENSE.md

-58
Original file line numberDiff line numberDiff line change
@@ -587,64 +587,6 @@ Repository: rollup/plugins
587587
588588
---------------------------------------
589589

590-
## acorn
591-
License: MIT
592-
By: Marijn Haverbeke, Ingvar Stepanyan, Adrian Heine
593-
Repository: https://github.com/acornjs/acorn.git
594-
595-
> MIT License
596-
>
597-
> Copyright (C) 2012-2022 by various contributors (see AUTHORS)
598-
>
599-
> Permission is hereby granted, free of charge, to any person obtaining a copy
600-
> of this software and associated documentation files (the "Software"), to deal
601-
> in the Software without restriction, including without limitation the rights
602-
> to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
603-
> copies of the Software, and to permit persons to whom the Software is
604-
> furnished to do so, subject to the following conditions:
605-
>
606-
> The above copyright notice and this permission notice shall be included in
607-
> all copies or substantial portions of the Software.
608-
>
609-
> THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
610-
> IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
611-
> FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
612-
> AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
613-
> LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
614-
> OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
615-
> THE SOFTWARE.
616-
617-
---------------------------------------
618-
619-
## acorn-walk
620-
License: MIT
621-
By: Marijn Haverbeke, Ingvar Stepanyan, Adrian Heine
622-
Repository: https://github.com/acornjs/acorn.git
623-
624-
> MIT License
625-
>
626-
> Copyright (C) 2012-2020 by various contributors (see AUTHORS)
627-
>
628-
> Permission is hereby granted, free of charge, to any person obtaining a copy
629-
> of this software and associated documentation files (the "Software"), to deal
630-
> in the Software without restriction, including without limitation the rights
631-
> to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
632-
> copies of the Software, and to permit persons to whom the Software is
633-
> furnished to do so, subject to the following conditions:
634-
>
635-
> The above copyright notice and this permission notice shall be included in
636-
> all copies or substantial portions of the Software.
637-
>
638-
> THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
639-
> IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
640-
> FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
641-
> AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
642-
> LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
643-
> OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
644-
> THE SOFTWARE.
645-
646-
---------------------------------------
647-
648590
## ansi-regex
649591
License: MIT
650592
By: Sindre Sorhus

packages/vite/package.json

-2
Original file line numberDiff line numberDiff line change
@@ -106,8 +106,6 @@
106106
"@rollup/pluginutils": "^5.1.0",
107107
"@types/escape-html": "^1.0.4",
108108
"@types/pnpapi": "^0.0.5",
109-
"acorn": "^8.11.3",
110-
"acorn-walk": "^8.3.2",
111109
"artichokie": "^0.2.1",
112110
"cac": "^6.7.14",
113111
"chokidar": "^3.6.0",

packages/vite/src/node/__tests__/plugins/importGlob/parse.spec.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -237,7 +237,7 @@ describe('parse positives', async () => {
237237
describe('parse negatives', async () => {
238238
it('syntax error', async () => {
239239
expect(await runError('import.meta.glob(')).toMatchInlineSnapshot(
240-
'[SyntaxError: Unexpected token (1:17)]',
240+
'[Error: Invalid glob import syntax: Close parenthesis not found]',
241241
)
242242
})
243243

packages/vite/src/node/plugins/dynamicImportVars.ts

+2-7
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { posix } from 'node:path'
22
import MagicString from 'magic-string'
33
import { init, parse as parseImports } from 'es-module-lexer'
44
import type { ImportSpecifier } from 'es-module-lexer'
5-
import { parse as parseJS } from 'acorn'
5+
import { parseAst } from 'rollup/parseAst'
66
import { dynamicImportToGlob } from '@rollup/plugin-dynamic-import-vars'
77
import type { Plugin } from '../plugin'
88
import type { ResolvedConfig } from '../config'
@@ -68,12 +68,7 @@ function parseDynamicImportPattern(
6868
strings: string,
6969
): DynamicImportPattern | null {
7070
const filename = strings.slice(1, -1)
71-
const ast = (
72-
parseJS(strings, {
73-
ecmaVersion: 'latest',
74-
sourceType: 'module',
75-
}) as any
76-
).body[0].expression
71+
const ast = (parseAst(strings).body[0] as any).expression
7772

7873
const userPatternQuery = dynamicImportToGlob(ast, filename)
7974
if (!userPatternQuery) {

packages/vite/src/node/plugins/importAnalysis.ts

+17-12
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,9 @@ import type {
88
ImportSpecifier,
99
} from 'es-module-lexer'
1010
import { init, parse as parseImports } from 'es-module-lexer'
11-
import { parse as parseJS } from 'acorn'
12-
import type { Node } from 'estree'
13-
import { findStaticImports, parseStaticImport } from 'mlly'
11+
import { parseAst } from 'rollup/parseAst'
12+
import type { StaticImport } from 'mlly'
13+
import { ESM_STATIC_IMPORT_RE, parseStaticImport } from 'mlly'
1414
import { makeLegalIdentifier } from '@rollup/pluginutils'
1515
import type { ViteDevServer } from '..'
1616
import {
@@ -119,11 +119,21 @@ function extractImportedBindings(
119119
}
120120

121121
const exp = source.slice(importSpec.ss, importSpec.se)
122-
const [match0] = findStaticImports(exp)
123-
if (!match0) {
122+
ESM_STATIC_IMPORT_RE.lastIndex = 0
123+
const match = ESM_STATIC_IMPORT_RE.exec(exp)
124+
if (!match) {
124125
return
125126
}
126-
const parsed = parseStaticImport(match0)
127+
128+
const staticImport: StaticImport = {
129+
type: 'static',
130+
code: match[0],
131+
start: match.index,
132+
end: match.index + match[0].length,
133+
imports: match.groups!.imports,
134+
specifier: match.groups!.specifier,
135+
}
136+
const parsed = parseStaticImport(staticImport)
127137
if (!parsed) {
128138
return
129139
}
@@ -934,12 +944,7 @@ export function transformCjsImport(
934944
importer: string,
935945
config: ResolvedConfig,
936946
): string | undefined {
937-
const node = (
938-
parseJS(importExp, {
939-
ecmaVersion: 'latest',
940-
sourceType: 'module',
941-
}) as any
942-
).body[0] as Node
947+
const node = parseAst(importExp).body[0]
943948

944949
// `export * from '...'` may cause unexpected problem, so give it a warning
945950
if (

packages/vite/src/node/plugins/importMetaGlob.ts

+50-49
Original file line numberDiff line numberDiff line change
@@ -4,22 +4,18 @@ import { stripLiteral } from 'strip-literal'
44
import colors from 'picocolors'
55
import type {
66
ArrayExpression,
7-
CallExpression,
87
Expression,
98
Literal,
10-
MemberExpression,
119
Node,
12-
SequenceExpression,
1310
SpreadElement,
1411
TemplateLiteral,
1512
} from 'estree'
16-
import { parseExpressionAt } from 'acorn'
17-
import type { CustomPluginOptions, RollupError } from 'rollup'
18-
import { findNodeAt } from 'acorn-walk'
13+
import type { CustomPluginOptions, RollupAstNode, RollupError } from 'rollup'
1914
import MagicString from 'magic-string'
2015
import fg from 'fast-glob'
2116
import { stringifyQuery } from 'ufo'
2217
import type { GeneralImportGlobOptions } from 'types/importGlob'
18+
import { parseAstAsync } from 'rollup/parseAst'
2319
import type { Plugin } from '../plugin'
2420
import type { ViteDevServer } from '../server'
2521
import type { ModuleNode } from '../server/moduleGraph'
@@ -218,7 +214,7 @@ export async function parseImportGlob(
218214
resolveId: IdResolver,
219215
logger?: Logger,
220216
): Promise<ParsedImportGlob[]> {
221-
let cleanCode
217+
let cleanCode: string
222218
try {
223219
cleanCode = stripLiteral(code)
224220
} catch (e) {
@@ -236,51 +232,30 @@ export async function parseImportGlob(
236232
return e
237233
}
238234

239-
let ast: CallExpression | SequenceExpression | MemberExpression
240-
let lastTokenPos: number | undefined
241-
242-
try {
243-
ast = parseExpressionAt(code, start, {
244-
ecmaVersion: 'latest',
245-
sourceType: 'module',
246-
ranges: true,
247-
onToken: (token) => {
248-
lastTokenPos = token.end
249-
},
250-
}) as any
251-
} catch (e) {
252-
const _e = e as any
253-
if (_e.message && _e.message.startsWith('Unterminated string constant'))
254-
return undefined!
255-
if (lastTokenPos == null || lastTokenPos <= start) throw _e
256-
257-
// tailing comma in object or array will make the parser think it's a comma operation
258-
// we try to parse again removing the comma
259-
try {
260-
const statement = code.slice(start, lastTokenPos).replace(/[,\s]*$/, '')
261-
ast = parseExpressionAt(
262-
' '.repeat(start) + statement, // to keep the ast position
263-
start,
264-
{
265-
ecmaVersion: 'latest',
266-
sourceType: 'module',
267-
ranges: true,
268-
},
269-
) as any
270-
} catch {
271-
throw _e
272-
}
235+
const end =
236+
findCorrespondingCloseParenthesisPosition(
237+
cleanCode,
238+
start + match[0].length,
239+
) + 1
240+
if (end <= 0) {
241+
throw err('Close parenthesis not found')
273242
}
274243

275-
const found = findNodeAt(ast as any, start, undefined, 'CallExpression')
276-
if (!found) throw err(`Expect CallExpression, got ${ast.type}`)
277-
ast = found.node as unknown as CallExpression
244+
const statementCode = code.slice(start, end)
278245

246+
const rootAst = (await parseAstAsync(statementCode)).body[0]
247+
if (rootAst.type !== 'ExpressionStatement') {
248+
throw err(`Expect CallExpression, got ${rootAst.type}`)
249+
}
250+
const ast = rootAst.expression
251+
if (ast.type !== 'CallExpression') {
252+
throw err(`Expect CallExpression, got ${ast.type}`)
253+
}
279254
if (ast.arguments.length < 1 || ast.arguments.length > 2)
280255
throw err(`Expected 1-2 arguments, but got ${ast.arguments.length}`)
281256

282257
const arg1 = ast.arguments[0] as ArrayExpression | Literal | TemplateLiteral
283-
const arg2 = ast.arguments[1] as Node | undefined
258+
const arg2 = ast.arguments[1] as RollupAstNode<Node> | undefined
284259

285260
const globs: string[] = []
286261

@@ -321,14 +296,12 @@ export async function parseImportGlob(
321296
)
322297

323298
options = parseGlobOptions(
324-
code.slice(arg2.range![0], arg2.range![1]),
325-
arg2.range![0],
299+
code.slice(start + arg2.start, start + arg2.end),
300+
start + arg2.start,
326301
logger,
327302
)
328303
}
329304

330-
const end = ast.range![1]
331-
332305
const globsResolved = await Promise.all(
333306
globs.map((glob) => toAbsoluteGlob(glob, root, importer, resolveId)),
334307
)
@@ -348,6 +321,34 @@ export async function parseImportGlob(
348321
return (await Promise.all(tasks)).filter(Boolean)
349322
}
350323

324+
function findCorrespondingCloseParenthesisPosition(
325+
cleanCode: string,
326+
openPos: number,
327+
) {
328+
const closePos = cleanCode.indexOf(')', openPos)
329+
if (closePos < 0) return -1
330+
331+
if (!cleanCode.slice(openPos, closePos).includes('(')) return closePos
332+
333+
let remainingParenthesisCount = 0
334+
const cleanCodeLen = cleanCode.length
335+
for (let pos = openPos; pos < cleanCodeLen; pos++) {
336+
switch (cleanCode[pos]) {
337+
case '(': {
338+
remainingParenthesisCount++
339+
break
340+
}
341+
case ')': {
342+
remainingParenthesisCount--
343+
if (remainingParenthesisCount <= 0) {
344+
return pos
345+
}
346+
}
347+
}
348+
}
349+
return -1
350+
}
351+
351352
const importPrefix = '__vite_glob_'
352353

353354
const { basename, dirname, relative, join } = posix

patches/acorn@8.11.3.patch

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
diff --git a/package.json b/package.json
2+
index 1b8dc76afc3cf5890cc3693c2975577fd3117dd6..9ac3a4d813fda1be476bd896a8f6168b3a459e41 100644
3+
--- a/package.json
4+
+++ b/package.json
5+
@@ -46,5 +46,6 @@
6+
},
7+
"bin": {
8+
"acorn": "./bin/acorn"
9+
- }
10+
+ },
11+
+ "sideEffects": false
12+
}

0 commit comments

Comments
 (0)