Были опубликованы последующие фактические боевые статьи:«Практика GogoCode» Узнайте, что подсказки для замены кода AST в одном Go
Как программист, вы, конечно, всегда ожидаете, что ваш код будет «написан один раз, работает везде», но реальный опыт часто таков: «одна модификация — сто заделок дыр», зависимости отстают на несколько версий, хочется обновить, старый код Я уже выгляжу очень неловко и планирую рефакторинг, и нам всем нужно принять твердое решение. Ведь там, где мы упускаем или допускаем ошибки, это может привести к катастрофе. Что мы обычно делаем?
сдаться
Мгновенно боль утихает, нет... но если вы настаиваете на этом, читайте ниже!
Истинный аромат и ограничения местных методов
Для некоторых простых нужд, таких как пример, недавно замеченный на Nuggets, удалите проект изconsole.log(xxx)
Код, я полагаю, что первая идея, с которой обычно сталкивается каждый, — это прямой выбор редактора для замены основного текста пустой строкой:
С помощью регулярных выражений мы по-прежнему можем справиться со многими требованиями, но действительно ли они охватывают все случаи? Некоторым коллегам очень нравится возврат каретки.
console
.log('aaa')
В этом случае, если мы сталкиваемся с более сложными требованиями или строгими сценариями, либо мы пишем более сложные регулярные выражения, либо нам приходится переходить к жестким операциям AST.
AST немного сложно
Поискав в интернете, я действительно нашел пример использования jscodeshift для работы AST для удаления console.log:
export default (fileInfo, api) => {
const j = api.jscodeshift;
const root = j(fileInfo.source)
const callExpressions = root.find(j.CallExpression, {
callee: {
type: 'MemberExpression',
object: { type: 'Identifier', name: 'console' },
},
}
);
callExpressions.remove();
return root.toSource();
};
Это требует от всех знакомства со структурой AST.При написании необходимо писать медленно против разобранной структуры узла.Если смотреть через некоторое время,то лучше не будет,чем регулярность намотки-каждый Обычно слишком мало контакта с АСТ.
попробуй совместить
Однажды, когда я переживал за капитальный рефакторинг API проекта и готовился к взрыву, барышня рядом со мной уже не выдержала — ее проект рефакторили раньше меня, и мало того, что они не взорвались. , а также сделал инструментGoGoCode, этот инструмент заимствует две идеи из jQuery:
Селектора такжецепной вызов
удалить с помощью этого инструментаconsole.log(xxx)
, что на самом деле является предложением:
const $ = require('gogocode')
/** 刻意凌乱的代码 **/
const input = `
console
.log(\`a, b,c\`);
`
// 关键代码
const output = $(input).replace('console.log()', '').generate()
console.log(output)
Что инновационно по этому поводу, это то, что он принимает ваш вкладconsole.log()
Проанализируйте соответствие дерева узлов в разделе узла AST исходному коду, чтобы не было проблем с форматом кода. Введенный код эквивалентен селектору в jQuery, но на этот раз выбран узел кода.
больше примеров
очиститьconsole.log
Эта операция еще слишком проста, я дам еще один каштан!
Мы часто используем перечисляемые списки следующим образом:
const list = [
{
text: "A策略",
value: 1,
tips: "Atip",
},
{
text: "B策略",
value: 2,
tips: "Btip",
},
{
text: "C策略",
value: 3,
tips: "Ctip",
},
];
Внезапно однажды, чтобы унифицировать различные перечисления в коде, нам нужно переименовать атрибут text в имя и атрибут value в id.Это трудно точно сопоставить с обычными правилами и легко случайно повредить.Это немного неудобно работать с деревом AST.GoGoCodeПросто замените его на это:
const $ = require('gogocode')
const input = `
const list = [
{
text: "A策略",
value: 1,
tips: "Atip",
},
{
text: "B策略",
value: 2,
tips: "Btip",
},
{
text: "C策略",
value: 3,
tips: "Ctip",
},
];
// ts的类型标记,这种正则替换会被错误替换的,在 gogocode 里就不会
const text: string = ''
// 这一段因为没有 value 就不会被选择器匹配到,也不会被错误替换
const cfg = {
text: ''
}
`
const output = $(input2).replace(
'{ text: $_$1, value: $_$2, $$$ }',
'{ name: $_$1, id: $_$2, $$$ }'
).generate();
в$_$1
а также$_$2
Это эквивалентно подстановочному знаку в обычном, но здесь он будет соответствовать только действительным узлам AST в коде,$$$
Затем вы можете сопоставить оставшиеся узлы, как в es6....
, этот код соответствуетtext
а такжеvalue
Соответствующее значение заполняетсяname
а такжеid
, а остальные верните обратно целыми.
Во второй части я намеренно добавил несколько «кодов помех», раньше использовал замену строкtext:
дляname:
Локальный способ столкнуться с такой ситуацией приведет к случайной травме, ноGoGoCodeНе будет.
Посмотрите на пример из сообщества в предыдущем абзаце
Случайно увидел статью в Наггетс в предыдущем абзацеИграйте в AST как в jQuery, в котором представлен пример преобразования кода React jsx с помощью jscodeshift:
Я планирую внести изменения в этот код:
- Изменен импорт с @alifd/next на antd
- до перевода после перевода
- Преобразование параметра типа в кнопке: обычное -> по умолчанию, среднее -> среднее
- Измените текстовый параметр в кнопке на type="link"
- Измените параметр предупреждения в кнопке на опасность
import * as React from 'react';
import styles from './index.module.scss';
import { Button } from "@alifd/next";
const Btn = () => {
return (
<div>
<h2>转译前</h2>
<div>
<Button type="normal">Normal</Button>
<Button type="primary">Prirmary</Button>
<Button type="secondary">Secondary</Button>
<Button type="normal" text>Normal</Button>
<Button type="primary" text>Primary</Button>
<Button type="secondary" text>Secondary</Button>
<Button type="normal" warning>Normal</Button>
</div>
</div>
);
};
export default Btn;
Вероятно, что-то вроде этого:
Такого рода требования на самом деле довольно распространены.Реализация на основе jscodeshift, вглубь AST для манипуляций, но если использоватьGoGoCodeЭто будет гораздо более интуитивно понятно:
// 省略依赖和 input
const output = $(input)
.replace(`import { $$$ } from "@alifd/next"`, `import { $$$ } from "antd"`)
.replace(`<h2>转译前</h2>`, `<h2>转译后</h2>`)
.replace(
`<Button type="normal" $$$></Button>`,
`<Button type="default" $$$></Button>`
)
.replace(
`<Button size="medium" $$$></Button>`,
`<Button size="middle" $$$></Button>`
)
.replace(`<Button text $$$></Button>`, `<Button type="link" $$$></Button>`)
.replace(`<Button warning $$$></Button>`, `<Button danger $$$></Button>`)
.generate();
Я полагаю, что вы можете понять, что делает этот код, не объясняя его ~
Открытый исходный код, надеюсь получить ваши отзывы
Я считаю этот проект очень интересным.Можно сказать,что программа замены специально сделана для кода.Дама сказала,что я слишком ясно увидела.На самом деле этот проект не только трюк замены,этот проект нас поддержал несколько десятков тысяч Выполнение плана модернизации архитектуры фронтенд-инжиниринга, даже если требования более сложные, способ все же естьвозьмиДа, вы можете подписаться на нашу учетную запись или колонку, и позже автор опубликует более профессиональную и исчерпывающую вводную статью.
Мисс Йе Си из нашей команды Alimama MUX.iconfont,Rap,MockJSТакой проект приветствуется сообществом, на этот раз мы ставимGoGoCodeТакже с открытым исходным кодом на Github:GitHub.com/thx/gogo код…, я надеюсь, что это может быть полезно для друзей, у которых также есть много потребностей в модификации кода.
Мы хотели бы знать, с какими проблемами конвертации вы часто сталкиваетесь, если используете текущуюGoGoCodeНеудобно решать или делать ошибки, надеюсь, вы можете указать нам на это (проблема:GitHub.com/thx/gogo код…Группа QQ: 735216094).
Напоследок: новые проекты просят звездной поддержки!
Гитхаб:GitHub.com/thx/gogo код…
Официальный сайт:gogocode.io