You all know that a modern script editor web part is available within the PnP Samples that allows you to write code directly into the web part as you did for on-premises versions of SharePoint. Remember, it is a sample; if you don’t need it, don’t use it. As it is sample code, you need to compile it yourself.

The advantage of this is that you can modify it if needed. I recently adjusted the web part for some testing I was doing, one of which works well.

Now you know the idea is to write code into the property pane field, and then it executes. I wanted to write code in the property pane utilizing either the Graph API or PnPjs to write information backward and forward to a SharePoint list. Trying to reference various externally hosted scripts or even downloading bundles locally and referencing them had mixed results. Sometimes they would load, sometimes, it looked like they loaded, and then the code would fail. I wondered if there was an easier way; of course, I could have just written a web part for what I needed, but it might be fun to see if I could make it work.

My idea was to load PnPjs directly into the SharePoint Framework Web Part (SPFx) and make it globally available to reference within the property pane without loading it.

First, to make sure it is not somehow loaded magically, you can edit the Modern Script Editor Web Part and add this code:

<script>
	console.log('PnPjs:', window.PnPjs);
</script>

When you save and refresh the page, it should write to the console this error: “PnPjs: undefined.”

To make it work, we load the entire project into Visual Studio Code (not going to cover that) and make a few adjustments.

Step 1: Import “PnPjs”

import { sp } from "@pnp/sp";

Step 2: Modify the Constructor

# Original Code
constructor() {
        super();
        this.scriptUpdate = this.scriptUpdate.bind(this);
}

# Modified Code
constructor() {
	super();
	this.scriptUpdate = this.scriptUpdate.bind(this);
	sp.setup({
		spfxContext: this.context
	});
	(window as any).PnPjs = sp;
}

Step 3: Modify the Render Method

# Original Code (First few lines)
public render(): void {
	this._unqiueId = this.context.instanceId;
	// Rest of the code

# Modified Code (First few lines)
public render(): void {
        this._unqiueId = this.context.instanceId;
        (window as any).PnPjs = sp;

We can recompile the code and test using the Workbench or Build, Bundle, Package, and Deploy. Using the same test from earlier, we can add this code:

<script>
	console.log('PnPjs:', window.PnPjs);
</script>

When we refresh the page this time, we get this:

As you can see, we now have access to PnPjs within the property pane. To confirm, let’s try getting some list items. We need to add this code:

<script>
	(function() {
		console.log('PnPjs:', window.PnPjs);
		const listName = "SampleDataList";
		let items = window.PnPjs.web.lists.getByTitle(listName).items.select('*').get();
		console.log(items);
	})();
</script>

When we execute, you should now see the first message as before and then a second one that, when expanded, displays the list of items.

With it loading and available, it now means we could write something more complex that interacts with anything PnPjs can access and use. An example could be a table form like this:

It took 300 lines of code (CSS, HTML, and JavaScript) to create a fully functional table form a structure like this that uses PnPjs within the Modern Script Editor Web Part and performs all the Create, Read, Update, and Delete (CRUD) using PnPjs directly to a SharePoint List.

Anyway, just a little fun thing to add to a very useful web part; in fact, you could apply the same principle to other libraries that are available within SharePoint Framework (SPFx), TypeScript, and JavaScript.