Скрипт предназначен для замены всех вхождений контролов, когда они переносятся из одного модуля в другой, либо переименовывается. Также скрипт позволяет переносить утилиты, переименовать опцию у контрола, переименовать/удалить css переменную или класс, а также позволяет передать свою настройку для замены.
Также есть возможность исправить проблему, когда был
запущен скрипт массовой обработки git-репозиториев
, но по какой-то причине ему не удалось запушить изменения. И при повторном запуске скрипта, ничего не происходило.
Чтобы исправить эту проблему, нужно запустить скрипт с флагом fixCommit
Готовый скрипт можно скачать из репозитория, либо собрать самому. Для этого нужно скачать проект, выполнить npm i
и npm run build
Необходимо запустить файл dist/replacer.js
, а также подготовить json файл с настройкой.
Переименовывания контролов:
node replacer.js config.json
Переименовывания опций контрола:
node replacer.js replaceOpt config.json
Переименовывания css переменных или классов:
node replacer.js cssReplace config.json
Свое переименование:
node replacer.js customReplace config.json
Сброс правок, на случай если скрипт запущен ошибочно, либо с некорректным config.json:
node replacer.js resetGit config.json
Сброс коммита, на случай когда нужно перезапустить скрипт для создания mr:
node replacer.js fixCommit config.json
Если модуль полностью переносится, то можно использовать сокращенную запись для module и controls[i].newModuleName, указав /* в конце. Например Name переносится в Controls-Name, тогда module: "Name/*", а controls[i].newModuleName: "Controls-Name/*"
{
"path": "Путь к репозиториям, где нужно выполнить замену",
"replaces": [
{
"module": "Текущее имя модуля",
"newModule": "Новое имя модуля. Стоит указывать когда весь модуль со всеми контролами переносится",
"controls": [
{
"name": "Текущее имя контрола",
"newName": "Новое имя контрола. Если контрол не переименовывается, то свойство указывать не нужно",
"newModuleName": "Новое имя модуля. Стоит указывать если из модуля выносится 1 определенный контрол"
}
]
}
],
"maxFileSize": "Максимальный размер файла. По умолчанию 50"
}
{
"path": "Путь к репозиториям, где нужно выполнить замену",
"replaces": [
{
"thisOpt": "Текущее имя опции",
"newOpt": "Новое имя опции",
"module": "Имя модуля, для которого нужно осуществить переименовывание",
"control": "Имя контрола, в котором нужно переименовать опцию"
}
],
"maxFileSize": "Максимальный размер файла. По умолчанию 50"
}
{
"path": "Путь к репозиториям, где нужно выполнить замену",
"replaces": [
{
"varName": "Текущее имя переменной или класса. Важно указывать имя css переменной полностью(--css-var), а класс указывать с '.'",
"newVarName": "Новое имя переменной или класса",
"isRemove": "Класс или переменная полностью удаляется"
}
],
"maxFileSize": "Максимальный размер файла. По умолчанию 50"
}
{
"path": "Путь к репозиториям, где нужно выполнить замену",
"replaces": [
{
"reg": "Регулярное выражение",
"flag": "Флаг для регулярного выражения. По умолчанию g",
"replace": "То как производится замена",
"scriptPath": "Путь до пользовательского скрипта"
}
],
"maxFileSize": "Максимальный размер файла. По умолчанию 50"
}
При кастомной замене стоит правильно указывать значение в replace. Замена осуществляется следующим образом:
str.replace(new RegExp(congig.reg, config.flag || "g"), config.replace);
Если нужно выполнить какое-то свое преобразование, то можно в scriptPath
передать путь до своего скрипта. Скрипт
должен быть следующего вида:
interface ICustomScriptParam {
path: string; // Полный путь до файла
file: string; // Имя файла с расширением
fileContent: string; // Содержимое файла
}
interface ICustomScriptResult {
status: boolean; // Статус выполнения скрипта. Если вернется true, то значение файла перезапишется на значение в result
result?: string; // Новое содержимое файла
error?: string; // Ошибки найденные при обработке файла
}
export function run(param: ICustomScriptParam): ICustomScriptResult {
return {
status: true,
result: 'Результат работы скрипта'
};
}
Для режимов resetGit и fixCommit, можно указать любой их указанных выше файлов конфигурации, либо создать отдельный. Важно чтобы в файле было указано поле path
.
Замена утилиты Controls/utils:oldUtil
на Controls/newUtils:newUtil
{
"path": "",
"replaces": [
{
"module": "Controls/utils",
"controls": [
{
"name": "oldUtils",
"newName": "newUtil",
"newModuleName": "Controls/newUtils"
}
]
}
]
}
Перенос всего модуля из одного места в другое. Например: Name/*
в Controls-Name/*
{
"path": "",
"replaces": [
{
"module": "Name/*",
"controls": [
{
"name": "",
"newModuleName": "Controls-Name/*"
}
]
}
]
}
Перенос отдельных частей модуля из одного места в другое. Например: Name/Input
в Controls-Name/Input
{
"path": "",
"replaces": [
{
"module": "Name/Input",
"controls": [
{
"name": "*",
"newModuleName": "Controls-Name/Input"
}
]
}
]
}
Замена Controls/buttons:ArrowButton
на Controls/extButtons:ArrowButton
{
"path": "",
"replaces": [
{
"module": "Controls/buttons",
"controls": [
{
"name": "ArrowButton",
"newModuleName": "Controls/extButtons"
}
]
}
]
}
Замена Controls/toggle:Tumbler
на Controls/toggle:NewTumbler
{
"path": "",
"replaces": [
{
"module": "Controls/toggle",
"controls": [
{
"name": "Tumbler",
"newName": "NewTumbler"
}
]
}
]
}
Замена Controls/list:Button
на Controls-button/list:Button
{
"path": "",
"replaces": [
{
"module": "Controls/list",
"controls": [
{
"name": "Button",
"newModuleName": "Controls-button/list"
}
]
}
]
}
Замена Controls/toggle:Tumbler
на Controls-toggle/Tumbler
. Обратите внимание на newName
, если свойство не
указывать, то произойдет переименование модуля(Controls-toggle/Tumbler:Tumbler
), но при указании пустой строки,
контрол подключается как модуль.
{
"path": "",
"replaces": [
{
"module": "Controls/toggle",
"controls": [
{
"name": "Tumbler",
"newName": "",
"newModuleName": "Controls-toggle/Tumbler"
}
]
}
]
}
Замена опции myClassName
на className
у контрола Controls/toggle:Toggle
{
"path": "",
"replaces": [
{
"thisOpt": "myClassName",
"newOpt": "className",
"module": "Controls/toggle",
"control": "Toggle"
}
]
}
Замена css переменной --oldName
на --newName
{
"path": "",
"replaces": [
{
"varName": "--oldName",
"newVarName": "--newName"
}
]
}
Замена css класса oldClassName
на newClassName
{
"path": "",
"replaces": [
{
"varName": ".oldClassName",
"newVarName": ".newClassName"
}
]
}
Важно чтобы в module и newModuleName разделение было сделано через /
иначе возможна некорректная работа. Также
в controls
можно не указывать newName и newModuleName, в таком случае значения поставятся из name и module. При этом,
одно из значений должно быть заполнено, иначе скрипт посчитает что правки не нужны и завершит работу.
Подобное сделано для удобства, когда переименовывается только модуль или контролл.
При использовании кастомной замены, перепроверьте получаемый результат в консоли, и только после этого запускайте скрипт. В противном случае можно получить не тот результат, который ожидался, и придется откатывать изменения.
Скрипт автоматически вносит правки в wml файлы. А также может вносить правки в ts, tsx и другие файлы.
Корректно обрабатываются следующие сценарии:
import { Tumbler } from "Controls/toggle";
<Tumbler />;
import { Tumbler as View } from "Controls/toggle";
<View />;
import { default as toggle } from "Controls/toggle";
<toggle.Tumbler />;
import {Tumbler, Switch} from 'Controls/toggle';
<Tumbler/>
<Switch/>
Если из исходной библиотеки выносится 1 контрол, то скрипт сам создаст или найдет нужный импорт, и поместит туда новый контрол
При переименовывании css переменных или классов корректно отрабатываются все случаи связанные с переменными. Также если указан isRemove=true, то определение переменной удалится.
Сейчас есть проблемы с импортом следующего вида:
import * as toggle from "Controls/toggle";
Скрипт самостоятельно не сможет обработать подобные сценарии, на что кинет ошибку. Но при этом скрипт сможет внести правки по использованию контрола, и заменит
<toggle.Name>
на
<toggle.NewName>
Скрипт не тронет сам импорт, так как не знает как нужно его заменить. Если вы полностью переносите весь модуль, то можно
указать это название в replaces.newModule
, в таком случае скрипт заменит импорт для модуля. Свойство стоит
использовать тогда, когда полностью переименовывается модуль, в противном случае скрипт отработает некорректно.
Также если контрол использовался так Controls.LoadingIndicator
, а нужно превратить его в Controls.loading:Indicator
,
то скрипт самостоятельно не сможет подобное обработать, а любая попытка провернуть подобное может обернуться ошибками.
Возможно, когда-то подобный функционал появится, но на данный момент в нем нет необходимости.
При переносе модуля, когда используется конструкции с указанием в имени модуля "/*", и указанием нового имени контрола, произойдет переименовывание самого модуля, старое имя контрола при этом не заменится.
Скрипт не сможет обработать случаи, когда контрол вставляется в другой контрол в качестве шаблона с передачей опций.
<Async templateName="Controls.toggle:Tumblet" templateOptions="{optionName: ...}" />
и
<Async templateName="Controls.toggle:Tumblet">
<ws:templateOptions optionName="..."/>
</Async>
Также не отработают случай с использованием spread оператора
<Tumbler {...{ optionName: "..." }} />
Скрипт корректно отрабатывает все случаи с заменой классов. Но могут возникнуть сложности, когда isRemove=true. Скрипт не сможет корректно отработать в следующих конструкциях:
.myClass .removeClass {
. . .
}
и
.removeClass {
/* ... */
.template {
/* ... */
}
}
Данные конструкции скрипт пропустит, но выкинет ошибку, чтобы можно было вручную внести правку. Все остальные конструкции отрабатывают корректно.
Через скрипт можно переименовывать различные утилиты, но есть вероятность что будет проблемы в редких случаях(см "Что работает нестабильно").
Скрипт проходится по всем файлам в директории, но не смотрит файлы больше 50mb, но можно настроить другое ограничение
используя maxFileSize
(не рекомендуется устанавливать большие значения)
О найденных проблемах или идеях по улучшению можно писать мне