Pull to refresh
108
0
Кирилл Коншин @dfuse

Principal Software Developer

Send message

Вам спасибо, что делитесь опытом ) мы пока еще не на финальной стадии, чтобы обернуть опыт в статью, но это уже не за горами.


Построение страниц для вставки — задача хоста. У него в том числе есть роутер, который отвечает за часть урла (до приложения) и обеспечивает связку роутинга внутри приложения с глобальным урлом (это в случае, если приложение полностраничное, а не попап какой-нибудь).


Авторизация внутри IFRAME — обычный 3-legged OAuth с Implicit Grant и prompt=none, т.е. тихий редирект, поскольку и хост и приложение ходят на один и тот же login.example.com. Веб-компоненты используют SDK, у которого авторизация глобальна.


Взаимодействие между кусочками — через общую шину (на основе postmessage в том числе) и через обычные коллбеки/пропсы которые можно передавать веб-компонентам, т.е. некая оркестрация в хосте конечно есть, но у нас довольно крупные куски.


"конфигурации конкретного тенанта нет какого-то микросервиса" можно пояснить, что это значит? Если компонент вставлен на страницу, значит он получен из реестра, а соотв. равзернут, под него есть бакенд и все необходимое в энвайронменте.

Мы пошли другим путем. Все под-приложения завернуты либо в веб-компонент, либо в IFRAME если это 3rd-party и там нужна особая безопасность и изолированность.

Так сам телеграм никто не заставляет сидеть через XMPP, это для сторонних клиентов, кто хочет в телеграмову сетку что-то послать или из нее что-то получить. Оригинальный клиент как был на MTProto так и останется.

Почему? На серверах телеграма может быть поднят гейт XMPP и к нему можно подключиться чем угодно. Полная функциональность при этом не гарантируется.

Я может что-то не понимаю, но вот например у Мегафона есть планы, на которых трафик Whatsapp или Telegram бесплатен, причем даже если лимиты кончились. Т.е. с ютуба ролик не посмотреть, а его же присланный через мессенджер — можно. Это же чистейший случай отсутствия нейтральности, только в положительном ключе.

Да, но зато так мы б могли обойтись только массивом todo и никаких индексов из ID не надо. Имхо, идея с ID здравая и элегантная, но это тот случай, когда с водой ребенка выплеснули. Лучше какой-то средний вариант взять, т.е. не спредать item в компонент, но и не закручивать гайки по максимуму с селектором по ID в connect. А чтоб работало совсем по красоте можно еще и обернуть в onlyUpdateForKeys из recompose, чтоб заигнорить лишнее.

А чем хуже с точки зрения производительности:


const TodoList = ({todos}) => (
  <ol>
    {todos.map( item => <ConnectedTodo key={item.id} item={item}  />)}
  </ol>
);

чем предложенный вариант по ID?


const TodoList = ({todos}) => (
  <ol>
    {todos.map( id => <ConnectedTodo key={id} id={id}  />)}
  </ol>
);

Во варианте с item мы же так же можем не рендерить если нет изменений (при условии иммутабельности item).

Новый? Да ему уже дофига лет… вон, видео из 2015 года https://www.youtube.com/watch?v=NpMnRifyGyw

Самая жесть начинается когда вы используете reduxForm например. Много мы тут можем натестировать? А главное — есть ли смысл тестировать подобное без редакса, формы, прогона валидации и тд? Мне кажется, такое тестирование ничего не даст. Вот пример компонента:


const onSubmit = async ({email, password}, dispatch, {userLogin, router}) => {
    try {
        await userLogin(email, password);
        router.push('/');
    } catch (e) {
        throw new SubmissionError({_error: 'Incorrect email or password.'});
    }
};

const validate = (values) => requredFields(values, ['email', 'password']);

let Login = ({handleSubmit, pristine, submitting, error, isAuthorized, location}) => {

    if (isAuthorized) {
        const {from} = location.state || {from: {pathname: '/'}};
        return (<Redirect to={from}/>);
    }

    return (
        <Form onSubmit={handleSubmit(onSubmit)}>
            <Field name="email" component={ReduxInput} label="Email" />
            <Field name="password" component={ReduxInput} label="Password"  type='password'/>
            {error && (
                <Error>{error}</Error>
            )}
            <SubmitButton disabled={pristine || submitting}>Login</SubmitButton>
        </Form>
    );

};

Login = reduxForm({form: Login.name, validate})(Login);
Login = connect((state) => ({
    isAuthorized: getToken(state)
}), {userLogin}, ownPropsWin)(Login);
Login = withRouter(Login);

export default Login;

При тесте мы можем подменить экшн, например, connect это позволяет, чтобы хотя бы по сети не ходить. Но все остальное надо брать и тестировать без разбора на атомарные кусочки, иначе кусочки то 100% будут работать, а самый главный связующий слой так и останется непокрытым.

Было бы неплохо описать как в нее интегрировать показ Redux компонентов, особенно чтобы можно было продолжать манипулировать стейтом, но экшны с сайд-эффектами вроде отправки данных на сервер и тд были подменены на экшны Storybook'а. А особенно как быть с nested connected components. Это целый огромный пласт знаний.

А я вот считаю, что лучше тронуть 30 строк и написать новое красивое решение (которым можно гордиться ближайшие 5 лет), чем костылить 2 и получать бяку в итоге :)

Дай бог в GitLab запилят, они иногда быстрее фичи выпускают

Можно линк на это видео?

Я в курсе, но для примера сознательно это не рассматривал.

В случае чистой синхронной функции — selector это что-то само собой разумеющееся. Это пока далеко от реальной жизни...


В случае хитрой бизнес логики с асинхронными запросами лучше всего таки идти через action creator. Да хотя бы методом исключения: редьюсер синхронный, селектор синхронный, lifecycle-методы синхронные и вообще мы их не рассматриваем, остаются только action creator'ы, ну может middleware, но зачем?


Принцип следующий:


  1. Диспатчим то, что пришло из формы синхронно
  2. Сразу в этом же action creator получаем новый полный стейт, по которому уже прошли редьюсеры (в стейте надо поставить какой-то флаг, что он недокалькулирован)
  3. Вырезаем от стейта часть, нужную для запроса на сервер (самый минимум) и засылаем
  4. Диспатчим результат работы сервера новым экшном
  5. По прошлой схеме набрасываемся на стейт редьюсерами (флаг можно снять) и селекторами (которые могут добить клиентские простые вычисления)

Вся эта бодяга либо уже есть в виде библиотеки (кто-то точно до этого додумался) либо может быть описана в виде некой функции-фабрики action-creator'ов.


Единственный минус — логика размазывается между селекторами и редьюсерами, но если четко обозначит сферы ответственности (редьюсер — операции закладки данных в стор, селектор — операции над данными без записи), то это не проблема.

Предположим есть builder контейнер, который строится и потом запускается через run, а результат его работы надо положить в другой pro контейнер. Ведь не будешь же класть весь NodeJS со всеми модулями из билдера в продакшен образ, где только Nginx нужен. Что то типа этого тикета и схожий кейс там же.


Может ли compose помочь с этим как-то?

Да, но у CRA куча жестких ограничений… Я сам тоже к нему склоняюсь, но тем не менее, надо это осознавать.

Переведите, пожалуйста, Readme на английский, а еще лучше — сразу и эту статью тоже.

Нужно в корне репозитория тоже сделать npm install, связано это с тем, что примеры используют код из /src, которому нужны peerDependencies главного пакета. Я напишу инструкцию в README или поменяю код примеров, чтоб легче было ставить. А вообще — с таким либо в issues на Github, либо в личку.

Выглядит многообещающе. Но тут есть страшный момент — когда у автора энтузиазм иссякнет не знает никто. Как часто будут апдейты и синкапы с апстримом? Через год можно оказаться без поддержки и с багами, которые никто не будет фиксить. Страшно как-то, это ведь не библиотека, а вся инфраструктура на форке.

Information

Rating
Does not participate
Location
San Francisco, California, США
Date of birth
Registered
Activity