enhance: estree-walkerをoxc-walkerに変更 (#17556)

* enhance: estree-walkerをoxc-walkerに変更

* fix lint [ci skip]
This commit is contained in:
かっこかり 2026-06-09 12:10:15 +09:00 committed by GitHub
commit 0b4764c68b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 74 additions and 36 deletions

View file

@ -4,23 +4,12 @@
*/
import { parseAst } from 'rolldown/parseAst';
import * as estreeWalker from 'estree-walker';
import { walk } from 'oxc-walker';
import { assertNever } from '../utils.js';
import type { ESTree } from 'rolldown/utils';
import type { LocaleInliner, TextModification } from '../locale-inliner.js';
import type { Logger } from '../logger.js';
// WalkerContext is not exported from estree-walker, so we define it here
interface WalkerContext {
skip: () => void;
}
const walk = estreeWalker.walk as {
(node: ESTree.Node, callback: {
enter?: (this: WalkerContext, node: ESTree.Node, parent: ESTree.Node | null, property: string | number | symbol | null | undefined) => void;
}): void;
};
export function collectModifications(sourceCode: string, fileName: string, fileLogger: Logger, inliner: LocaleInliner): TextModification[] {
if (sourceCode === '') return [];
let programNode: ESTree.Program;
@ -42,7 +31,7 @@ export function collectModifications(sourceCode: string, fileName: string, fileL
// 2) replace all `localStorage.getItem("lang")` with `localeName` variable
// 3) replace all `await window.fetch(`/assets/locales/${d}.${x}.json`).then(u=>u.json())` with `localeJson` variable
walk(programNode, {
enter(this: WalkerContext, node: ESTree.Node) {
enter(this, node) {
if (node.type === 'Literal' && typeof node.value === 'string' && node.raw) {
if (node.raw.substring(1).startsWith(inliner.scriptsDir)) {
// we find `scripts/\w+\.js` literal and replace 'scripts' part with locale code
@ -130,13 +119,15 @@ export function collectModifications(sourceCode: string, fileName: string, fileL
const toSkip = new Set();
toSkip.add(i18nImport);
walk(programNode, {
enter(this: WalkerContext, node, parent, property) {
enter(this, node, parent, ctx) {
if (toSkip.has(node)) {
// This is the import specifier, skip processing it
this.skip();
return;
}
const property = ctx.key;
// We don't care original name part of the import declaration
if (node.type === 'ImportDeclaration') this.skip();

View file

@ -17,9 +17,9 @@
"rollup": "4.60.4"
},
"dependencies": {
"estree-walker": "3.0.3",
"i18n": "workspace:*",
"magic-string": "0.30.21",
"oxc-walker": "1.0.0",
"rolldown": "1.0.3",
"vite": "8.0.14"
}

View file

@ -3,7 +3,7 @@
* SPDX-License-Identifier: AGPL-3.0-only
*/
import * as estreeWalker from 'estree-walker';
import { walk } from 'oxc-walker';
import { RolldownMagicString } from 'rolldown';
import { assertType } from './utils.js';
import type { ESTree } from 'rolldown/utils';
@ -27,8 +27,7 @@ export function pluginRemoveUnrefI18n(
if (!code.includes('unref(i18n)')) return null;
const ast = this.parse(code);
const magicString = meta.magicString ?? new RolldownMagicString(code);
// eslint-disable-next-line @typescript-eslint/no-explicit-any
(estreeWalker.walk as any)(ast, {
walk(ast, {
enter(node: ESTree.Node) {
if (node.type === 'CallExpression' && node.callee.type === 'Identifier' && node.callee.name === 'unref'
&& node.arguments.length === 1) {

View file

@ -14,7 +14,6 @@
"@rollup/pluginutils": "5.4.0",
"@vitejs/plugin-vue": "6.0.7",
"buraha": "0.0.1",
"estree-walker": "3.0.3",
"frontend-shared": "workspace:*",
"i18n": "workspace:*",
"icons-subsetter": "workspace:*",

View file

@ -3,7 +3,7 @@
* SPDX-License-Identifier: AGPL-3.0-only
*/
import * as estreeWalker from 'estree-walker';
import { walk } from 'oxc-walker';
import type { Plugin } from 'vite';
import type { ESTree } from 'rolldown/utils';
import { RolldownMagicString } from 'rolldown';
@ -185,7 +185,7 @@ function isClassProperty(node: ESTree.Node | null): node is Extract<ESTree.Node,
}
export function unwindCssModuleClassName(ast: ESTree.Node, magicString: RolldownMagicString): void {
(estreeWalker.walk as any)(ast, {
walk(ast, {
enter(node: ESTree.Node, parent: ESTree.Node | null): void {
//#region
if (parent?.type !== 'Program') return;
@ -267,7 +267,7 @@ export function unwindCssModuleClassName(ast: ESTree.Node, magicString: Rolldown
*/
//#endregion
//#region
(estreeWalker.walk as any)(render.body, {
walk(render.body, {
enter(childNode: ESTree.Node) {
if (!isCssModuleReference(childNode, ctx.name, key)) return;
const actualKey = getMemberPropertyName(childNode.property, childNode.computed);
@ -278,6 +278,9 @@ export function unwindCssModuleClassName(ast: ESTree.Node, magicString: Rolldown
this.replace({
type: 'Literal',
value: actualValue,
raw: JSON.stringify(actualValue),
start: childNode.start,
end: childNode.end,
});
},
});
@ -314,7 +317,7 @@ export function unwindCssModuleClassName(ast: ESTree.Node, magicString: Rolldown
*/
//#endregion
//#region
(estreeWalker.walk as any)(render.body, {
walk(render.body, {
enter(childNode: ESTree.Node) {
if (!isCssModuleReference(childNode, ctx.name, key)) return;
const actualKey = getMemberPropertyName(childNode.property, childNode.computed);
@ -357,7 +360,7 @@ export function unwindCssModuleClassName(ast: ESTree.Node, magicString: Rolldown
*/
//#endregion
//#region
(estreeWalker.walk as any)(render.body, {
walk(render.body, {
enter(childNode: ESTree.Node, childParent: ESTree.Node | null) {
if (childNode.type !== 'CallExpression') return;
if (childNode.arguments.length !== 1) return;
@ -404,7 +407,7 @@ export function unwindCssModuleClassName(ast: ESTree.Node, magicString: Rolldown
}
const hasRemainingCssModuleReference = Array.from(moduleForest.keys()).some((key) => {
let found = false;
(estreeWalker.walk as any)(render.body, {
walk(render.body, {
enter(childNode: ESTree.Node) {
if (!isCssModuleAccess(childNode, ctx.name, key)) return;
found = true;
@ -417,7 +420,7 @@ export function unwindCssModuleClassName(ast: ESTree.Node, magicString: Rolldown
//#region
if (node.declarations[0].init.arguments[1].elements.length === 1) {
if (componentNode.type === 'Identifier') {
(estreeWalker.walk as any)(ast, {
walk(ast, {
enter(childNode: ESTree.Node) {
if (childNode.type !== 'Identifier') return;
if (childNode.name !== componentNode.name) return;

View file

@ -116,7 +116,6 @@
"cypress": "15.16.0",
"eslint-plugin-import": "2.32.0",
"eslint-plugin-vue": "10.9.1",
"estree-walker": "3.0.3",
"happy-dom": "20.9.0",
"intersection-observer": "0.12.2",
"lightningcss": "1.32.0",
@ -125,6 +124,7 @@
"msw": "2.14.6",
"msw-storybook-addon": "2.0.7",
"nodemon": "3.1.14",
"oxc-walker": "1.0.0",
"prettier": "3.8.3",
"react": "19.2.6",
"react-dom": "19.2.6",

64
pnpm-lock.yaml generated
View file

@ -873,9 +873,6 @@ importers:
eslint-plugin-vue:
specifier: 10.9.1
version: 10.9.1(@stylistic/eslint-plugin@5.10.0(eslint@9.39.4))(@typescript-eslint/parser@8.60.0(eslint@9.39.4)(typescript@5.9.3))(eslint@9.39.4)(vue-eslint-parser@10.4.0(eslint@9.39.4))
estree-walker:
specifier: 3.0.3
version: 3.0.3
happy-dom:
specifier: 20.9.0
version: 20.9.0(bufferutil@4.1.0)(utf-8-validate@6.0.6)
@ -900,6 +897,9 @@ importers:
nodemon:
specifier: 3.1.14
version: 3.1.14
oxc-walker:
specifier: 1.0.0
version: 1.0.0(oxc-parser@0.127.0)(rolldown@1.0.3)
prettier:
specifier: 3.8.3
version: 3.8.3
@ -957,15 +957,15 @@ importers:
packages/frontend-builder:
dependencies:
estree-walker:
specifier: 3.0.3
version: 3.0.3
i18n:
specifier: workspace:*
version: link:../i18n
magic-string:
specifier: 0.30.21
version: 0.30.21
oxc-walker:
specifier: 1.0.0
version: 1.0.0(oxc-parser@0.127.0)(rolldown@1.0.3)
rolldown:
specifier: 1.0.3
version: 1.0.3
@ -1003,9 +1003,6 @@ importers:
buraha:
specifier: 0.0.1
version: 0.0.1
estree-walker:
specifier: 3.0.3
version: 3.0.3
frontend-shared:
specifier: workspace:*
version: link:../frontend-shared
@ -7201,6 +7198,9 @@ packages:
resolution: {integrity: sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ==}
hasBin: true
magic-regexp@0.11.0:
resolution: {integrity: sha512-LG77Z/gVnwz7oaDpD4heX6ryl+lcr4l1B2gnP4MMvt2pGhGC1Dfj7dl1pXpP4ih+VQFLuAadeKVa+lARAzfW+Q==}
magic-string@0.30.21:
resolution: {integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==}
@ -7848,6 +7848,17 @@ packages:
oxc-resolver@11.19.1:
resolution: {integrity: sha512-qE/CIg/spwrTBFt5aKmwe3ifeDdLfA2NESN30E42X/lII5ClF8V7Wt6WIJhcGZjp0/Q+nQ+9vgxGk//xZNX2hg==}
oxc-walker@1.0.0:
resolution: {integrity: sha512-eMsHflAGfOskpWxtp9xP/f5b96XLEU8ifTd2gOOCkdux9HMxKGy5S1ru0Gh1B3aPu+YbfmWUUVkcb7MrZz3XyQ==}
peerDependencies:
oxc-parser: '>=0.98.0'
rolldown: '>=1.0.0'
peerDependenciesMeta:
oxc-parser:
optional: true
rolldown:
optional: true
p-finally@1.0.0:
resolution: {integrity: sha512-LICb2p9CB7FS+0eR1oqWnHhp0FljGLZCWBE9aix0Uye9W8LTQPwMTYVGWQWIw9RdQiDg4+epXQODwIYJtSJaow==}
engines: {node: '>=4'}
@ -8562,6 +8573,10 @@ packages:
regex@6.1.0:
resolution: {integrity: sha512-6VwtthbV4o/7+OaAF9I5L5V3llLEsoPyq9P1JVXkedTP33c7MfCG0/5NOPcSJn0TzXcG9YUrR0gQSWioew3LDg==}
regexp-tree@0.1.27:
resolution: {integrity: sha512-iETxpjK6YoRWJG5o6hXLwvjYAoW+FEZn9os0PD/b6AP6xQwsa/Y7lCVgIixBbUPMfhu+i2LtdeAqVTgGlQarfA==}
hasBin: true
regexp.prototype.flags@1.5.4:
resolution: {integrity: sha512-dYqgNSZbDwkaJ2ceRd9ojCGjBq+mOm9LmtXnAnEGyHhN/5R7iDW2TRw3h+o/jCFxus3P2LfWIIiwowAjANm7IA==}
engines: {node: '>= 0.4'}
@ -9594,6 +9609,9 @@ packages:
resolution: {integrity: sha512-OZs6gsjF4vMp32qrCbiVSkrFmXtG/AZhY3t0iAMrMBiAZyV9oALtXO8hsrHbMXF9x6L3grlFuwW2oAz7cav+Gw==}
engines: {node: '>= 0.6'}
type-level-regexp@0.1.17:
resolution: {integrity: sha512-wTk4DH3cxwk196uGLK/E9pE45aLfeKJacKmcEgEOA/q5dnPGNxXt0cfYdFxb57L+sEpf1oJH4Dnx/pnRcku9jg==}
typed-array-buffer@1.0.3:
resolution: {integrity: sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw==}
engines: {node: '>= 0.4'}
@ -9744,6 +9762,10 @@ packages:
resolution: {integrity: sha512-5uKD0nqiYVzlmCRs01Fhs2BdkEgBS3SAVP6ndrBsuK42iC2+JHyxM05Rm9G8+5mkmRtzMZGY8Ct5+mliZxU/Ww==}
engines: {node: '>=18.12.0'}
unplugin@3.0.0:
resolution: {integrity: sha512-0Mqk3AT2TZCXWKdcoaufeXNukv2mTrEZExeXlHIOZXdqYoHHr4n51pymnwV8x2BOVxwXbK2HLlI7usrqMpycdg==}
engines: {node: ^20.19.0 || >=22.12.0}
until-async@3.0.2:
resolution: {integrity: sha512-IiSk4HlzAMqTUseHHe3VhIGyuFmN90zMTpD3Z3y8jeQbzLIq500MVM7Jq2vUAnTKAFPJrqwkzr6PoTcPhGcOiw==}
@ -16411,6 +16433,13 @@ snapshots:
lz-string@1.5.0: {}
magic-regexp@0.11.0:
dependencies:
magic-string: 0.30.21
regexp-tree: 0.1.27
type-level-regexp: 0.1.17
unplugin: 3.0.0
magic-string@0.30.21:
dependencies:
'@jridgewell/sourcemap-codec': 1.5.5
@ -17303,6 +17332,13 @@ snapshots:
- '@emnapi/core'
- '@emnapi/runtime'
oxc-walker@1.0.0(oxc-parser@0.127.0)(rolldown@1.0.3):
dependencies:
magic-regexp: 0.11.0
optionalDependencies:
oxc-parser: 0.127.0
rolldown: 1.0.3
p-finally@1.0.0: {}
p-limit@2.3.0:
@ -18014,6 +18050,8 @@ snapshots:
dependencies:
regex-utilities: 2.3.0
regexp-tree@0.1.27: {}
regexp.prototype.flags@1.5.4:
dependencies:
call-bind: 1.0.9
@ -19154,6 +19192,8 @@ snapshots:
media-typer: 1.1.0
mime-types: 3.0.2
type-level-regexp@0.1.17: {}
typed-array-buffer@1.0.3:
dependencies:
call-bound: 1.0.4
@ -19288,6 +19328,12 @@ snapshots:
picomatch: 4.0.4
webpack-virtual-modules: 0.6.2
unplugin@3.0.0:
dependencies:
'@jridgewell/remapping': 2.3.5
picomatch: 4.0.4
webpack-virtual-modules: 0.6.2
until-async@3.0.2: {}
untildify@4.0.0: {}