Install effector-logger
masterInstall effector-logger as a development dependency. Note that effector must also be installed in your project.
npm add effector
npm add --dev effector-loggeror
yarn add effector
yarn add -D effector-loggerrepository·master·Indexed 41 days ago
https://github.com/effector/loggerA utility for providing pretty, informative logs for Effector units such as stores, events, effects, and domains in the browser console. It includes features like attachLogger for enabling logs, configure for controlling unit visibility, and createDeclarationsLogger for tracking initialization. Supports metadata via Babel or SWC plugins to provide exact code locations and names in logs.
Install effector-logger as a development dependency. Note that effector must also be installed in your project.
npm add effector
npm add --dev effector-loggeryarn add effector
yarn add -D effector-loggerTo make logs more useful (including names and code locations), you must use an Effector plugin to provide metadata.
Add effector/babel-plugin to your Babel configuration. To see exact code locations in your development environment, enable addLoc.
Use the effector SWC plugin for SWC-based environments.
{
"plugins": [["effector/babel-plugin", { "addLoc": true }]]
}You can pass an options object to attachLogger to customize the output:
scope: If your app uses Scope (e.g., in SSR), pass the scope instance. Updates related to this scope will be prefixed with the scope ID.name: An optional string prefix for all logs. This is useful for distinguishing between multiple app instances or providing a more readable identifier than a scope ID.attachLogger({
scope,
name: `my-cool-app-${appId}`, // all logs will be prefixed with this string
});To stop the logger, capture the return value of attachLogger() and call it as a function.
const unlogger = attachLogger();
// later...
unlogger();To enable logging, call attachLogger() in your entrypoint module.
CRITICAL: attachLogger must be imported at the very top of your entrypoint module to ensure that initial states of stores (created via createStore, createEvent, etc.) are properly logged.
// src/index.tsx
import { attachLogger } from 'effector-logger';
import React from 'react';
import { createRoot } from 'react-dom/client';
import { App } from './app';
import { appStarted } from './shared/app-events';
attachLogger();
appStarted();
createRoot(document.querySelector('#app')).render(<App />);Use the configure function to control which units appear in the logs. You can pass a single unit or an array of units.
log: 'disabled'.log: 'enabled'.import { createEvent } from 'effector';
import { configure } from 'effector-logger';
import { $data, loadDataFx } from './model';
const pageMounted = createEvent<number>();
// Hide units
configure(pageMounted, { log: 'disabled' });
configure([$data, loadDataFx], { log: 'disabled' });
// Force derived units to be logged
const mappedMounted = pageMounter.map((x) => x);
configure(mappedMounted, { log: 'enabled' });effector-logger. Instead, use the dedicated @effector/redux-devtools-adapter package.Call storeUpdated to log whenever a store's value changes. The log entry includes the new value, the file where the store is defined, and the store's name.
import { storeUpdated } from 'effector-logger';
// Example usage within a subscription or middleware
storeUpdated('myStore', 'src/store.ts', newValue);Use createDeclarationsLogger to log the initialization of stores, events, and effects. This function uses a debounced mechanism to collect all declarations that were not explicitly named during the initial graph inspection and logs them in a single grouped console output.
name: A string used as a prefix or context for the logged units.scope (optional): An Effector Scope instance used to retrieve the initial state of stores during initialization logging.import { createDeclarationsLogger } from 'effector-logger';
// Initialize the logger
const logger = createDeclarationsLogger({
name: 'my-app',
scope: myScope
});
// Note: The logger is debounced, so it will trigger after the initial execution context.Call eventCalled to log when an event is triggered. The log entry includes the event payload, the file where the event is defined, and the event's name.
import { eventCalled } from 'effector-logger';
// Example usage
eventCalled('myEvent', 'src/events.ts', payload);Use configure() to explicitly enable or disable logging for specific Effector units (stores, events, or effects). This is useful for reducing noise in the console by hiding specific units or forcing the logging of derived units.
Arguments:
unitOrUnits: A single Unit or an array of Units.config: An object with a log property set to either 'enabled' or 'disabled'.Note: If you disable an Effect, its finally unit is also automatically disabled to ensure consistent lifecycle logging.
import { configure } from 'effector-logger';
import { myStore, myEvent, myEffect } from './model';
// Disable logging for specific units
configure([myStore, myEvent], { log: 'disabled' });
// Force logging for specific units (including derived ones)
configure(myEffect, { log: 'enabled' });Use attachLogger() to enable logging for your Effector application. It sets up listeners for unit updates, event calls, and effect lifecycles.
It accepts an optional configuration object:
scope: An Effector Scope to limit logging to a specific scope.name: A custom string to prefix your logs.attachLogger() returns a cleanup function. You should call this returned function when you want to stop logging (e.g., during teardown or when switching environments) to prevent memory leaks and stop the inspection process.
import { attachLogger } from 'effector-logger';
// Attach logger to the global scope
const stopLogging = attachLogger();
// Or attach to a specific scope with a custom name
const stopLoggingWithScope = attachLogger({
scope: myScope,
name: 'my-app'
});
// When done:
stopLogging();