Встроенный плагин для 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. Это предотвращает двойное срабатывание эффектов и наблюдателей.
Хотя опция и протестирована, она считается экспериментальной и может иметь неожиданные проблемы в разных сборщиках.
Формула
"effector/babel-plugin",
{
"hmr": "es"
}
]
- Тип:
"es"
|"cjs"
|"none"
"es"
: Использует API HMRimport.meta.hot
в сборщиках, соответствующих ESM, таких как Vite и Rollup"cjs"
: Использует API HMRmodule.hot
в сборщиках, использующих CommonJS модули, таких как Webpack и Next.js"none"
: Отключает Hot Module Replacement.
- По умолчанию:
none
При сборке для продакшена убедитесь, что задали опции hmr
значение "none"
, чтобы уменьшить размер бандла и улучшить производительность в 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
, необходимо выполнить следующие шаги:
- Установите пакет
@vitejs/plugin-react
. 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. Перевод документации на другие языки осуществляется сообществом по мере наличия сил и желания.
Помните, что переведенные статьи могут быть неактуальными, поэтому для получения наиболее точной и актуальной информации рекомендуем использовать оригинальную англоязычную версию документации.