Встроенный плагин для Babel может использоваться для SSR и отладки. Он добавляет имя юнита, выведенное из имени переменной, и sid (Стабильный Идентификатор), вычисленный из местоположения в исходном коде.

Например, в случае эффектов без обработчиков, это улучшает сообщения об ошибках, показывая, в каком именно эффекте произошла ошибка.

import { createEffect } from "effector";
const fetchFx = createEffect();
fetchFx();
// => no handler used in fetchFx

Запустить пример

Использование

В простейшем случае его можно использовать без какой-либо конфигурации:

.babelrc
{
"plugins": ["effector/babel-plugin"]
}

SID

Начиная с

Стабильный хэш-идентификатор для событий, эффектов, сторов и доменов, сохраняемый между окружениями, для обработки взаимодействия клиент-сервер в рамках одной кодовой базы.

Ключевое значение sid заключается в том, что он может быть автоматически сгенерирован effector/babel-plugin с конфигурацией по умолчанию, и он будет стабильным между сборками.

Подробное объяснение

Если вам нужно подробное объяснение о том, зачем нужны SID и как они используются внутри, вы можете найти его, перейдя по этой ссылке

Смотрите пример проекта

common.js
import { createEffect } from "effector";
export const getUser = createEffect({ sid: "GET /user" });
console.log(getUsers.sid);
// => GET /user
worker.js
import { getUsers } from "./common.js";
getUsers.use((userID) => fetch(userID));
getUsers.done.watch(({ result }) => {
postMessage({ sid: getUsers.sid, result });
});
onmessage = async ({ data }) => {
if (data.sid !== getUsers.sid) return;
getUsers(data.userID);
};
client.js
import { createEvent } from "effector";
import { getUsers } from "./common.js";
const onMessage = createEvent();
const worker = new Worker("worker.js");
worker.onmessage = onMessage;
getUsers.use(
(userID) =>
new Promise((rs) => {
worker.postMessage({ sid: getUsers.sid, userID });
const unwatch = onMessage.watch(({ data }) => {
if (data.sid !== getUsers.sid) return;
unwatch();
rs(data.result);
});
}),
);

Конфигурация

hmr

Начиная с

Включите поддержку Hot Module Replacement (HMR) для очистки связей, подписок и побочных эффектов, управляемых Effector. Это предотвращает двойное срабатывание эффектов и подписок

Взаимодействие с фабриками

Поддержка HMR показывает наилучшие результаты когда все фабрики в проекте правильно описаны, это помогает плагину и рантайму понимать, какой код нужно удалять при обновлении

Формула

"effector/babel-plugin",
{
"hmr": "es"
}
]
  • Тип: boolean | "es" | "cjs"
    • true: Использует API HMR с автоопределением необходимого варианта работы. Работает на базе функциональности бабеля supportsStaticESM, которая широко поддерживается в сборщиках
    • "es": Использует API HMR import.meta.hot в сборщиках, соответствующих ESM, таких как Vite и Rollup
    • "cjs": Использует API HMR module.hot в сборщиках, использующих CommonJS модули, таких как Webpack, Next.js и React Native
    • false: Отключает Hot Module Replacement.
  • По умолчанию: false
Сборка для продакшна

При сборке для продакшена убедитесь, что задали опции hmr значение false или удалили опцию полностью, чтобы уменьшить размер бандла и улучшить производительность в runtime.

importName

Указание имени или имен импорта для обработки плагином. Импорт должен использоваться в коде как указано.

Формула

[
"effector/babel-plugin",
{
"importName": ["effector"]
}
]
  • Тип: string | string[]
  • По умолчанию: ['effector', 'effector/compat']

factories

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

Формула

[
"effector/babel-plugin",
{
"factories": ["path/here"]
}
]
  • Тип: string[]
  • Фабрики могут иметь любое количество аргументов.
  • Фабрики могут создавать любое количество юнитов.
  • Фабрики могут вызывать любые методы effector.
  • Фабрики могут вызывать другие фабрики из других модулей.
  • Модули с фабриками могут экспортировать любое количество функций.
  • Фабрики должны быть скомпилированы с effector/babel-plugin, как и код, который их использует.

Примеры

.babelrc
{
"plugins": [
[
"effector/babel-plugin",
{
"factories": ["src/createEffectStatus", "~/createCommonPending"]
}
]
]
}
./src/createEffectStatus.js
import { rootDomain } from "./rootDomain";
export function createEffectStatus(fx) {
const $status = rootDomain.createStore("init").on(fx.finally, (_, { status }) => status);
return $status;
}
./src/statuses.js
import { createEffectStatus } from "./createEffectStatus";
import { fetchUserFx, fetchFriendsFx } from "./api";
export const $fetchUserStatus = createEffectStatus(fetchUserFx);
export const $fetchFriendsStatus = createEffectStatus(fetchFriendsFx);

Импорт createEffectStatus из './createEffectStatus' рассматривался как фабричная функция, поэтому каждый стор, созданный ею, имеет свой собственный sid и будет обрабатываться serialize независимо, хотя без factories они будут использовать один и тот же sid.

reactSsr

Заменяет импорты из effector-react на effector-react/scope. Полезно для сборки как серверных, так и клиентских сборок из одной кодовой базы.

Устарело

С effector 23.0.0 команда разработчиков рекомендует удалить эту опцию из конфигурации babel-plugin, потому что effector-react поддерживает SSR по умолчанию.

Формула

[
"effector/babel-plugin",
{
"reactSsr": false
}
]
  • Тип: boolean
  • По умолчанию: false

addNames

Добавляет имя к вызовам фабрик юнитов. Полезно для минификации и обфускации production сборок.

Начиная с

Формула

[
"effector/babel-plugin",
{
"addNames": true
}
]
  • Тип: boolean
  • По умолчанию: true

addLoc

Добавляет местоположение к вызовам методов. Используется devtools, например effector-logger.

Формула

[
"effector/babel-plugin",
{
"addLoc": false
}
]
  • Тип: boolean
  • По умолчанию: false

debugSids

Добавляет путь к файлу и имя переменной определения юнита к sid. Полезно для отладки SSR.

Формула

[
"effector/babel-plugin",
{
"debugSids": false
}
]
  • Тип: boolean
  • По умолчанию: false

noDefaults

Опция для effector/babel-plugin для создания пользовательских фабрик юнитов с чистой конфигурацией.

Формула

[
"effector/babel-plugin",
{
"noDefaults": false
}
]
  • Тип: boolean
  • По умолчанию: false

Примеры

.babelrc
{
"plugins": [
["effector/babel-plugin", { "addLoc": true }],
[
"effector/babel-plugin",
{
"importName": "@lib/createInputField",
"storeCreators": ["createInputField"],
"noDefaults": true
},
"createInputField"
]
]
}
// @lib/createInputField.js
import { createStore } from "effector";
import { resetForm } from "./form";
export function createInputField(defaultState, { sid, name }) {
return createStore(defaultState, { sid, name }).reset(resetForm);
}
src/state.js
import { createInputField } from "@lib/createInputField";
const foo = createInputField("-");
/*
будет обработано как создатель стор и скомпилировано в
const foo = createInputField('-', {
name: 'foo',
sid: 'z&si65'
})
*/

Использование со сборщиками

Vite + React (SSR)

Для использования с effector/babel-plugin, необходимо выполнить следующие шаги:

  1. Установите пакет @vitejs/plugin-react.
  2. vite.config.js должен выглядеть следующим образом:

Примечание: effector/babel-plugin не является отдельным пакетом, он входит в состав effector

vite.config.js
import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";
export default defineConfig({
plugins: [
react({
babel: {
plugins: ["effector/babel-plugin"],
// Использовать .babelrc файлы
babelrc: true,
// Использовать babel.config.js файлы
configFile: true,
},
}),
],
});
Перевод поддерживается сообществом

Документация на английском языке - самая актуальная, поскольку её пишет и обновляет команда effector. Перевод документации на другие языки осуществляется сообществом по мере наличия сил и желания.

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

Соавторы