 SharePoint Framework developers often face the challenge of determining how to share code or refactor it from their project in order to make it available for multiple projects. The objective is to avoid duplicating code, which is a common issue in development. Now I have never used or found a good use or need for SharePoint Framework library components. There's simply no need for a SharePoint Framework specific solution to a problem that has already been solved with NPM packages. We've already got a wheel, we don't need a new wheel. In this episode, I'm going to look at the two options for externalizing your code to share across multiple projects. And I'm going to compare the advantages and the disadvantages of each one. And then I'm going to offer my thoughts and opinions on which of the two options I prefer and why. But first, let's look at the challenge and some of the unique aspects related to the SharePoint Framework. Hey, I'm Andrew and if this topic interests you, please hit that like button below the video. It helps me reach more people just like you and grow this channel. And if you're new here, consider subscribing to my channel with the button below the video to see when I publish more videos for Microsoft 365 and Microsoft Azure full stack developers. And check out my biweekly newsletter where I talk about the same topics and share them the most important news in the Microsoft 365 and Microsoft Azure space for full stack developers. Delivered straight to your inbox. And you may have code that's shared across multiple SharePoint Framework solutions. Duplicating your code in projects, not ideal. It's not ideal for maintenance and performance. So it's recommended to externalize whenever possible. Now, how can code duplication impact performance? Well, if you've got multiple web parts on a page that all reference the same code, you don't want to load the same code multiple times. Ideally, it should only be loaded once on the page. Similar to how we don't load or react multiple times on a page when multiple web parts depend on it. We want to ensure that it's only loaded one time on the page. So how can you share code across your SharePoint Framework projects? The solution is to externalize the shared code from your project and then consume it from one or more components. And there are two different options available to achieve this. Now, the option that most developers look to is the library component. And that was introduced in the SharePoint Framework version 1.9.1. And this is a Microsoft and SharePoint specific solution that's covered in the documentation. But the other option is to use an NPM package. This is the standard way to distribute JavaScript packages. And it works for all JavaScript-based projects, including SharePoint Framework solutions. So let's explore these two different options, including the advantages and disadvantages of each one. SharePoint Framework library components were introduced in the SharePoint Framework version 1.9.1. And they allow you to have code that can be versioned independently of the SharePoint Framework project that consumes them. Any SharePoint Framework component can consume an SPFX library component. And once deployed, when an SPFX component that depends on the library component is loaded in the page, the SharePoint Framework runtime is going to load the library components bundle. Now, every subsequent request for the same library component on that page by other components won't result in additional requests to go load that library that's already on the page. So let's look at the advantages and disadvantages of these library components. Now, these are some of the advantages of using a SharePoint Framework library component. First, there's no extra deployment step that's going to be necessary. The SharePoint Framework package that contains the library component is deployed just like a package that contains a web part. Everything it needs to run is included in the package as it's all hosted by SharePoint. Number two is not publicly available outside of the deployment scope, like a site collection or a tenant scoped app catalog. The third advantage is they can be created using the SharePoint Framework Yeoman Generator and the Build Toolchain. And the fourth advantage is the development process is similar to any other kind of a SharePoint Framework component. The project scaffolding contains everything that you need to get started right away. No additional typescript, compilation, or packaging process is necessary. But there are some disadvantages. Library components can only be used with SharePoint Framework solutions. They can't be used with other Node.js based projects because they must be hosted within SharePoint online. And another disadvantage is that you cannot have multiple versions of the same library component deployed simultaneously. There is only one version deployed at any given time. Now that means that when you deploy version two of your library component, you better make sure that all the components that consume v1 are ready and compatible with v2. Why? Because the SharePoint Framework runtime does not factor in version numbers when loading an SPFX library component. The third reason is that library components are limited to the scope where they've been deployed. They can't be mixed and matched across different scopes, such as the site collection or the tenant app catalog. Another disadvantage is that it's hard to implement automated testing with library components. See, library components are intended and expected to be run within a SharePoint Framework runtime context, which is very hard to simulate in an automated testing scenario. Another disadvantage is they're only available for SharePoint Framework solutions in SharePoint Online. Library components were introduced in SharePoint Framework 1.9.1. And no on-prem SharePoint Server deployment supports a SharePoint Framework version higher than SPFX version 1.5.1 at this time. But library components are not your only option. In fact, they're not even a good option. Oh, I'm skipping ahead. Now an NPM package is a standardized way to share code in a JavaScript or a Node.js-based project. In fact, we're already using NPM packages in all of our SharePoint Framework projects. It allows for independently versioned code and any SPFX component can consume a bundled NPM package. We are currently using this approach with React and other libraries listed in the package.json file. Now some of the advantages of using packages include the following. Reusability is a big one. An NPM package can be used in multiple SharePoint Framework solutions and non-SharePoint Framework solutions providing flexibility and saving development time. Another benefit is versioning. NPM packages can be versioned independently of other projects that depend on it allowing for better control and management of code changes. The third advantage is automated testing. Implementing automated testing is so much easier with an NPM package enhancing code quality and reliability. Another advantage is it's standards-based. An NPM package provides a standards-based solution to a common need. In other words, unlike library components from the SharePoint framework that only work with SharePoint Framework projects, you can use an NPM package within a SharePoint Framework project, a Node.js project, or any other client-side-based web project. And they work in all SharePoint Framework versions including the oldest SharePoint server on-prem deployment. Now it's not perfect and when compared to the SharePoint Framework library components one could argue that there are some downsides to using NPM packages for sharing across SPFX projects. So here are some of the disadvantages that I could find of using an NPM package for code reuse within an SPFX-based solution. It does require an additional deployment step that is going to be required if you decide to externalize your bundle. You need to decide where you're going to host the bundle that's going to contain the entire NPM package, the resulting bundle. Probably some CDN, but that's not a big deal. Another disadvantage is the inability to use the existing Yeoman Generator for SharePoint Framework projects in the build tool chain. You're going to need to create your own generator. Although there are many open and standard examples that are available for reference. Another disadvantage? You can't easily use a SharePoint Framework-based component inside these solutions. I mean, technically you can, but the testing and the development process is very hard because you can't inject the SharePoint context into them without a lot of additional work. Now that I've gone over these two different options, let's look at how to use NPM packages in your SPFX projects. There's already plenty of examples on using SPFX library components and SharePoint Framework projects. So I'm going to skip that for now. Let's see how that we can create and use an NPM package in a SharePoint Framework project. Now I cover this topic at a lot more depth, including a step-by-step instructor-led demo in my course Mastering the SharePoint Framework. And for viewers of this video, enter the code YouTube at checkout to save 20% off any of the bundles. Just don't tell anybody. It's just for you guys that are watching this. And by default, during the build process, WebPacket is going to ingest the reference dependencies and include them in each project's bundle. For smaller projects where duplicating code in the bundles won't add much to the size of the generator bundle, this method might be acceptable to you. However, if you have one common package that's used by multiple SPFX projects, anytime you update the common package, you're going to need to redeploy or rebuild and redeploy the consuming SPFX projects. Now the other option is to externalize your common package's bundle and host it in a CDN or in some other location where the bundle is accessible by your deployed SPFX projects. That could be a publicly accessible CDN or one that's only available to users within your organization. Now to do this, you're first going to build and deploy your common SharePoint packages bundle. Now to do this, you're going to first build and deploy your common packages bundle to some location. So let's say, for example, that you've externalized code into some new package called the Apollo Mission Service and deploy the bundle to CDN.contoso.com slash AMS, some version number, and then whatever the JavaScript file is. Next, you're going to install the NPM package of your common library in your SharePoint framework project using a standard NPM install command to list it in your project's package.json file. So you're just going to use something like NPM install ApolloMissionLibrary-SE to save the exact version. Next, configure your SharePoint framework project so that Webpack will ignore the library and not include it in your SharePoint framework project's bundle. Instead, it will be listed as a dependency, so when the SPFX runtime goes to load your dependencies, it will ensure it's loaded on the page from the CDN location before it loads your SPFX components bundle. Now this is done in the config slash config.json file within your project. So what does this do? Well, now, anytime that Webpack sees our library referenced in a module like import ApolloMissionServiceLibrary from ApolloMissionService, instead of including it in the generator bundle, it's going to ignore it assuming that it's already going to get added to the page some other way. Now another part of the SharePoint framework build process is that it's going to generate a component manifest that's going to include with our library as a dependency. Now when the SPFX runtime loads the manifest for a component, it's going to see this reference and ensure that all the dependencies are downloaded onto the page before loading the components bundle that the libraries were already present. Now from my point of view an NPM package is a much better option for externalizing your code in a SharePoint framework solution. It's an established solution to a common problem unlike a SharePoint framework library component which, in my view, it simply creates a SharePoint framework-specific solution to an already solved problem and at the same time it introduces a bunch of limitations that you don't face with NPM packages. Honest to God, I've never used or found the need for a SharePoint framework library component. I simply see no need for a SharePoint framework-specific solution to a problem that has already been solved and doesn't have all the baggage a SharePoint framework library component introduces into the scenario like only having one deployed version and not being able to be easily testable. In my SharePoint framework projects I always rely on NPM packages and generate bundles that either I host on my own CDN or include the code directly in the consuming projects bundles. If I'm adding the packages to the bundle if it doesn't significantly increase its size and the externalized code isn't used in more than just a couple projects that are only updated every once in a while I usually bundle it just for simplicity. Otherwise, I'm going to store them separately in my own Azure hosted CDN and reference them as external resources in my config.json file. In Azure CDN it's incredibly cheap so the cost is really no concern. What about you? Have you tried both options and prefer one of them over the other? Why? Let me know by dropping a comment below and let me know if you want to see more Microsoft 365 videos for full stack developers. And if you found this video useful or you liked it, please give me a thumbs up. It really helps me grow the channel by reaching more people just like you. And if you haven't already, please hit that subscribe button below the video. So you're going to see when I publish more videos for full stack developers Microsoft 365 and Microsoft Azure topics. And let me know if you want to see more videos about reusing code and SharePoint framework projects. I just went over the basics here and why I prefer NPM packages. But is something confusing to you? Well, let me know. Let me know specifically what's challenging to you and what you want to see. Maybe that'll make the next video. I'm Andrew Connell. Thank you for watching and I hope to see you in my next episode.