PREMISE:
Recently I was looking at the logging package in the @PNP/pnpjs library.
To summarize how the logging infrastructure works.
You use the Logger class to configure and subscribe your logger instance.
import {
Logger,
ConsoleListener,
LogLevel
} from "@pnp/logging";
const LOG_SOURCE: string = 'MyAwesomeWebPart';
Logger.subscribe(ConsoleListener(LOG_SOURCE, {color:'#0b6a0b',warningColor:'magenta'}));
Logger.activeLogLevel = LogLevel.Info;
Then you can just use the same Logger class anywhere in your web part to write a message to the subscribed loggers.
Logger.write("My special message");
Logger.write("A warning!", LogLevel.Warning);
Considering there is no dependency injection involved this seems to point to Logger being a global class (that acts similar to a C# static). This is confirmed by its typescript definition
export declare class Logger {
private static _instance;
/**
* Gets or sets the active log level to apply for log filtering
*/
static activeLogLevel: LogLevel;
private static readonly instance;
// more code here....
}
But... if this was the case then multiple web parts on the same page using the library would end up in multiple subscribed loggers... and each write operation would write to EVERY logger.
The issue
I was therefore trying to understand how the logger was supposed to work. And I stumbled up this page on github;
I'm interested to understand how the static Logger class handles usage in multiple SPFx components on the same page.
If we have a custom LogListener that's registered via the Logger's subscribe method, what is the scope of that subscription array?
For example, if the custom LogListener is defined with data specific to the calling web part, will it's data ever be used if the Logger static class is called in another context, e.g. another SPFx web part on the same page?
Patrick answer then mentions something interesting.
Each SPFx web part is itself a closure, meaning anything instantiated within that container is only present in that container. So your webparts wouldn't know that others were even using the same logging framework.
Each SPFx web part is itself a closure. I understand what they must mean: SharePoint has a way to encapsulate a web part code so that its "global" variables are actually accessible only to that specific web part instance.
What I don't get is how SharePoint does that.
I tried looking at the available documentation but as usual I couldn't find anything useful.
My question is therefore this: can anyone provide me with some references to any (preferably official) material that describe this "closure" behaviour in SharePoint (SPFX only?) web parts?