SharePoint Framework - Transition to @pnp/sp from sp-pnp-js

In this article, we will explore the reasons behind the depreciation of sp-pnp-js, what there is in @pnp/sp, and how we can transition our code from sp-pnp-js to @pnp/sp.

Overview

 
SharePoint Patterns and Practices (PnP) had introduced the sp-pnp-js to simplify common operations with SharePoint and SPFx. The sp-pnp-js had provided various wrapper APIs to perform operations with SharePoint in an efficient way and with less code. The sp-pnp-js had taken away the complicated work to form REST requests, processed the JSON responses and thus let developers concentrate on the actual business logic.
 

Why is sp-pnp-js deprecated?

 
The sp-pnp-js was a huge package of single JS handling multiple responsibilities (e.g. performing SharePoint operations, logging, performing operations with MS graph, taxonomy, etc.). As a result, it was a very bulky package.
 
The single sp-pnp-js package was broken into multiple packages that give developers more control and bring in only required pieces to their solutions. This also gives the flexibility to update the required package individually.
 

WebPart with sp-pnp-js

 
Follow the below steps if you do not have a prior project with sp-pnp-js.
 
Open the command prompt. Create a directory for SPFx solution.
  1. md spfx-sp-pnp  
Navigate to the above-created directory.
  1. cd spfx- sp-pnp  
Run the Yeoman SharePoint Generator to create the solution.
  1. yo @microsoft/sharepoint  
Yeoman generator will present you with the wizard by asking questions about the solution to be created.
 
 
Solution Name: Hit Enter to have a default name (spfx-sp-pnp in this case) or type in any other name for your solution.
Selected choice: Hit Enter
 
Target for component: Here, we can select the target environment where we are planning to deploy the client web part, i.e., SharePoint Online or SharePoint OnPremise (SharePoint 2016 or 2019 onwards).
Selected choice: SharePoint Online only (latest).
 
Place of files: We may choose to use the same folder or create a subfolder for our solution.
Selected choice: Use the current folder
 
Deployment option: Selecting Y will allow the app to be deployed instantly to all sites and will be accessible everywhere.
Selected choice: Y
 
Permissions to access web APIs: Choose if the components in the solution require permissions to access web APIs that are unique and not shared with other components in the tenant.
Selected choice: N (solution contains unique permissions)
 
Type of client-side component to create: We can choose to create a client side web part or an extension.
Selected choice: WebPart
 
Web Part Name: Hit Enter to select the default name or type in any other name.
Selected choice: HelloPnP
 
Web part description: Hit Enter to select the default description or type in any other value.
Selected choice: Hit Enter
 
Framework to use: Select any JavaScript framework to develop the component. Available choices are (No JavaScript Framework, React, and Knockout)
Selected choice: No JavaScript Framework
 
Open the command prompt, type the below command to add sp-pnp-js npm package to project.
  1. npm install sp-pnp-js --save  

Code the WebPart

 
On the command prompt, type the below command to open the solution in a code editor of your choice.
  1. code .  
Open the web part file at \src\webparts\helloPnP\HelloPnPWebPart.ts.
 
Add sp-pnp-js imports.
  1. import pnp, { Web } from 'sp-pnp-js';  
Write onInit() method to configure spfx context.
  1. public onInit(): Promise<void> {  
  2.   // setup to use spfx context  
  3.   return super.onInit().then(_ => {  
  4.     pnp.setup({  
  5.       spfxContext: this.context  
  6.     });  
  7.   });   
  8. }  
Implement render method.
  1. public render(): void {  
  2.   pnp.sp.web.lists.select("Title").getAs<{ Title: string }[]>().then(lists => {  
  3.     this.domElement.innerHTML += `<hr/><h2>Lists in web</h2><ul>${lists.map(l => `<li>${l.Title}</li>`).join("")}</ul>`;  
  4.   });  
  5. }  

Test the WebPart

  1. On the command prompt, type “gulp serve”
  2. Open SharePoint site
  3. Navigate to /_layouts/15/workbench.aspx
  4. Locate and add the webpart to page.
 

Transition to @pnp/sp from sp-pnp-js

 
On the command prompt, type the below command to add sp-pnp-js npm package to project.
  1. npm i @pnp/logging @pnp/common @pnp/odata @pnp/sp --save  
The new @pnp/sp package will appear under node_modules.
 
 
We will now update our imports to @pnp/sp.
  1. // sp-pnp-js imports  
  2. // import pnp, { Web } from 'sp-pnp-js';  
  3.   
  4. // @pnp/sp imports  
  5. import { sp, Web } from '@pnp/sp';  
Update the code to make use of new @pnp/sp imports. The “pnp” references are replaced with “sp”.
 
Update onInit() method.
  1. public onInit(): Promise<void> {  
  2.     return super.onInit().then(_ => {  
  3.       sp.setup({  
  4.         spfxContext: this.context  
  5.       });  
  6.     });  
  7.   }  
Update render() method.
  1. public render(): void {  
  2.     sp.web.lists.select("Title").get<{ Title: string }[]>().then(lists => {  
  3.        this.domElement.innerHTML += `<hr/><h2>Lists in web</h2><ul>${lists.map(l => `<li>${l.Title}</li>`).join("")}</ul>`;  
  4.     });  
  5.   }  

Test after @pnp/sp transition

 
From the command prompt, type “gulp” serve to test the webpart after @pnp/sp transition. On the UI front it looks the same as it was before (with sp-pnp-js implementation); however, we have upgraded the solution behind the scene to a newer package.
 

Summary

 
sp-pnp-js was introduced to simplify common operations with SharePoint and SPFx. However, it was one big bulky file with all functionalities together. SharePoint Patterns and Practices (PnP) have broken it in to multiple packages that give developers more control and brought in only required pieces to their solutions. As the old sp-pnp-js package is deprecated, to align with future updates it is advisable to start using new @pnp/sp packages and start transitioning old solutions to new @pnp/sp packages.