vkcom / elephize Goto Github PK
View Code? Open in Web Editor NEWTypescript to PHP translation tool
License: MIT License
Typescript to PHP translation tool
License: MIT License
Некоторые имена атрибутов в react отличаются от html-представления. Сейчас мы поддерживаем только перевод className в class, но это не единственный такой атрибут (есть еще htmlFor, например). Нужно найти список таких атрибутов и поддержать их всех.
В JS коде иногда попадаются переменные, которые начинаются с $
. После прохода через elephize, такой код становится невалидным. Нужно эскейпить $
на _
, например.
Не нашел информацию, как сделать имплементацию функции в каждом окружении (client-side и server-side) вручную, без транспиляции модуля
При использовании компонента-функции до его определения, Elephize ругается, что не может найти ее определения. Баг НЕ воспроизводится при таких же условиях, если функции не являются React-компонентами
Воспроизведение (псевдокод):
// @elephizeTarget
function Usage() {
return <Component />
}
// @elephizeTarget
function Component() {
}
При деструктуризации пропсов, в PHP переменная кастится к базовому типу, даже если там пришел null (например, для типа foo?: string в PHP будет генерироваться код $foo = (string)$props['foo'].
При компиляции возникают ошибки вида Identifier "props" was used but was never declared. This is compile error
Проявляется для кода следующего вида:
interface Props { /* ... */ }
// @elephizeTarget
export const Component: React.FC<Props> = (props: Props) => { ... };
Лечится убиранием аннотации :Props из сигнатуры функции. Не очень нормальная ситуация, такая сигнатура должна быть допустима.
Хочется уметь игнорировать целые папки и модули, в которых 100% неподдерживаемый код для транспиляции. Не проверял, возможно ли это сейчас, но было бы круто в этих glob поддержать алисы. Например,
"importRules": { "#helpers": { "ignore": true } }
Добавить в таски, настроить gh actions
Если импортируемый модуль содержит в своем пути папку, которая является ключевым словом в PHP, то при использовании будет ошибка Keywords as part of namespace are only allowed since PHP 8.0
. В моем случае одной из папок оказалась 'static'
<span>{text}</span> - экранируется, а <>{text}</> - нет
Сейчас вызов useMemo просто отбрасывается, но это можно улучшить, если отбрасывать только мемоизацию, но оставить мемоизируемый на клиенте код.
Примерная схема работы:
Такая защита от дурака наверно недостаточна, так как тут например может быть массив или ещё какое значение приводимое к опасной строке.
Вот пример TS-компонента, при котором использование компонента в PHP может привести к небезопасной вставке строки:
@@ -4,10 +4,15 @@
const injection = `<img src=x onerror=alert()>`;
// @elephizeTarget
-export const EscapeHtmlChars = ({ children }: { children: React.ReactNode[] }) => {
+export const EscapeHtmlChars = ({
+ children,
+ // Dangerous string from input or server, received from props
+ mixedValue = [injection]
+}: { children: React.ReactNode[], mixedValue?: string[] }) => {
const arr = [1, 2, 3, 4];
return (
<div className="App">
+ <div>{mixedValue}</div>
<h1>Hello CodeSandbox</h1>
<h2>Start editing to see some magic happen!</h2>
{arr.map((v) => <span>{injection}{v}</span>)}
Конкретных решений не предложу.
Может тогда вынести этот вопрос отдельным issue?
Originally posted by @fix-fix in #112 (comment)
Сейчас мы требует четкого указания конкретного файла в импорте. Т.е. если имеем файл ./foo/index.ts, то
import { Foo } from './foo/index'; // работает
import { Foo } from './foo'; // не работает
Хочется поддержать это в сокращенной форме, не затаскивая полный резолвинг модулей из ноды.
Пример нерабочего кода:
function dvf(a: number, b: number = 123, c: boolean = true) {
console.log(a, b, c);
}
function dvdo({a, b = 123, c = true}: { a: number, b?: number, c?: boolean }) {
console.log(a, b, c);
}
function dvda([a, b = 123, c = true]: [number, number?, boolean?]) {
console.log(a, b, c);
}
console.log(dvf(1));
console.log(dvdo({ a: 1 }));
console.log(dvda([1]));
Хочется поддержать эту фичу, т.к. она выглядит как часто используемая
При обращении к свойствам this
генерируется невалидный PHP-код.
Выражение вида this.property
преобразуется в property["undefined"]
Пример TS input:
function test() {
console.log(window.setTimeout); // OK
// @ts-ignore
console.log(this.setTimeout);
}
Пример PHP output:
public function test() {
\VK\Elephize\Builtins\Console::log($window["setTimeout"]);
\VK\Elephize\Builtins\Console::log(setTimeout["undefined"]);
}
Судя по доке this
не поддерживается, но он всё равно может где-то использоваться в коде. И если его не запретить на уровне транспайлинга в PHP, то нужно поддерживать его кодген.
Само использование this
почти всегда скорее невалидно, если не поддержаны классы, так что возможно вообще стоит при использовании this
завершать транспайлинг ошибкой.
Сейчас же из-за ошибки генерируется невалидный PHP-код, который может не скомпилироваться в KPHP.
В watch режиме некоторые mixed значения в PHPDoc заменяются другими (в моем случае, кажется, проставился @return string в месте, где ожидается mixed), а некоторые JSX тэги оборчиваются в IntrinsicElement::escape.
Возможно, причина первой ошибки в том, что у меня кастомный IntrinsicElement, где JSX возвращает mixed вместо string, а по-дефолту Elephize из JSX возвращает именно string
Написать пошаговую инструкцию для базового create-react-app приложения.
Комплексные типы вроде { [key: string]: string }
могут быть более точно представлены как string[]
на стороне php. Подумать какие еще варианты комплексных типов можно представить более точно. Рассмотреть возможные использования конструкции tuple()
По опыту этот warning не имеет смысла. Чаще всего, длина строчки используется только в кейсе string.length !== 0
. Потенциальная проблема еще актуальна, для нее нужно придумать какое-то другое решение отдельно. Например, получать длину строки тем же алгоритмом, что и в JS (тут есть возможные проблемы с кодировкой и emoji)
Typecast в PHP добавляется только для переменных, созданных через десктрутуризацию (const { foo } from props
).
Нужно применять typecast также для использований через props.foo
Дано:
export const IconLeft = ({ ref }: Props) => {
const onClick = () => {
ref?.current?.scroll({ left: ref.current.scrollLeft - 50, behavior: 'smooth' });
};
return (
<div onClick={onClick} className="ico--left">
<Icon24 fill="rgba(153,162,173, 1)" />
</div>
);
};
Ожидаемый результат: переменная ref отсутствует в выводе, т.к. используется только внутри клиентского обработчика.
Фактический результат: в выводе есть присваивание переменной (как результат деструктуризации)
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.