Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 35610ec

Browse files
authored
perf: migrate unplugins to oxc-walker (#663)
* chore: migrate unplugins to oxc-walker Replace legacy AST tooling (estree-walker, unplugin-ast, acorn-loose) with oxc-walker across addons, react, and solid-js packages. - addons: UseSeoMetaTransform now uses parseSync + walk instead of this.parse() + estree-walker - addons: TreeshakeServerComposables now uses parseSync + walk + MagicString instead of unplugin-ast - react/solid-js: streaming plugins use walk() instead of Visitor pattern with proper function stack context tracking Drops deps: estree-walker, unplugin-ast, @babel/types, @types/estree, acorn-loose * chore: migrate all streaming plugins to oxc-walker, drop mlly - Replace `findStaticImports` (mlly) with `parseAndWalk` (oxc-walker) across Vue, React, Solid, Svelte - Use Vite native `transform.filter` for file extension filtering via `createStreamingPlugin` - Remove `mlly` from all framework package dependencies and build externals * fix: resolve typecheck errors in streaming plugins and remove unused mlly catalog TS narrowed existingImport to never since it was mutated inside parseAndWalk callback. Use explicit type assertion to break the narrowing.
1 parent 17dbfe3 commit 35610ec

24 files changed

Lines changed: 539 additions & 537 deletions

package.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,6 @@
3838
"@fast-check/vitest": "catalog:",
3939
"@types/fs-extra": "catalog:",
4040
"@types/jsdom": "catalog:",
41-
"acorn-loose": "catalog:",
4241
"bumpp": "catalog:",
4342
"devalue": "catalog:",
4443
"eslint": "catalog:",

packages/addons/package.json

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -62,16 +62,13 @@
6262
},
6363
"dependencies": {
6464
"@rollup/pluginutils": "catalog:",
65-
"estree-walker": "catalog:",
6665
"magic-string": "catalog:",
67-
"mlly": "catalog:",
66+
"oxc-parser": "catalog:",
67+
"oxc-walker": "catalog:",
6868
"ufo": "catalog:",
69-
"unplugin": "catalog:",
70-
"unplugin-ast": "catalog:"
69+
"unplugin": "catalog:"
7170
},
7271
"devDependencies": {
73-
"@babel/types": "catalog:",
74-
"@types/estree": "catalog:",
7572
"rollup": "catalog:",
7673
"unhead": "workspace:*",
7774
"vite": "catalog:"

packages/addons/src/unplugin/TreeshakeServerComposables.ts

Lines changed: 32 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,19 @@
1-
import type { CallExpression } from '@babel/types'
2-
import type { Transformer } from 'unplugin-ast'
31
import type { ConfigEnv, UserConfig } from 'vite'
42
import type { BaseTransformerTypes } from './types'
53
import { pathToFileURL } from 'node:url'
4+
import MagicString from 'magic-string'
5+
import { parseSync } from 'oxc-parser'
6+
import { walk } from 'oxc-walker'
67
import { parseQuery, parseURL } from 'ufo'
78
import { createUnplugin } from 'unplugin'
8-
import { transform } from 'unplugin-ast'
99

10-
function RemoveFunctions(functionNames: string[]): Transformer<CallExpression> {
11-
return {
12-
onNode: node => node.type === 'CallExpression'
13-
&& node.callee.type === 'Identifier'
14-
&& functionNames.includes(node.callee.name),
15-
transform() {
16-
return false
17-
},
18-
}
19-
}
10+
const functionNames = [
11+
'useServerHead',
12+
'useServerHeadSafe',
13+
'useServerSeoMeta',
14+
// plugins
15+
'useSchemaOrg',
16+
]
2017

2118
export interface TreeshakeServerComposablesOptions extends BaseTransformerTypes {
2219
enabled?: boolean
@@ -59,7 +56,7 @@ export const TreeshakeServerComposables = createUnplugin<TreeshakeServerComposab
5956
return false
6057
},
6158

62-
async transform(code, id) {
59+
transform(code, id) {
6360
if (
6461
!code.includes('useServerHead')
6562
&& !code.includes('useServerHeadSafe')
@@ -69,24 +66,28 @@ export const TreeshakeServerComposables = createUnplugin<TreeshakeServerComposab
6966
return
7067
}
7168

72-
let transformed
73-
try {
74-
transformed = await transform(code, id, {
75-
parserOptions: {},
76-
transformer: [
77-
RemoveFunctions([
78-
'useServerHead',
79-
'useServerHeadSafe',
80-
'useServerSeoMeta',
81-
// plugins
82-
'useSchemaOrg',
83-
]),
84-
],
85-
})
69+
const ast = parseSync(id, code)
70+
const s = new MagicString(code)
71+
72+
walk(ast.program, {
73+
enter(node: any) {
74+
if (
75+
node.type === 'ExpressionStatement'
76+
&& node.expression.type === 'CallExpression'
77+
&& node.expression.callee.type === 'Identifier'
78+
&& functionNames.includes(node.expression.callee.name)
79+
) {
80+
s.remove(node.start, node.end)
81+
}
82+
},
83+
})
84+
85+
if (s.hasChanged()) {
86+
return {
87+
code: s.toString(),
88+
map: s.generateMap({ includeContent: true, source: id }),
89+
}
8690
}
87-
// safely fail
88-
catch {}
89-
return transformed
9091
},
9192
webpack(ctx) {
9293
if (ctx.name === 'server')

0 commit comments

Comments
 (0)