In Prod

← Back to Posts

Modern SPFx on SharePoint 2019

February 12, 2020

SharePoint Framework (SPFx) allows developers to create modern applications (web parts) that can seamlessly integrate into a SharePoint environment to provide business solutions for users. Developers can use modern frameworks like React with Typescript out of the box.

The latest version of SPFx (1.10 at the time of writing) supports React 16.7 and Typescript 3.3. This is great, but we do miss out on some of the latest paradigms such as the hooks and context APIs in React.

While SharePoint Online (SPO) supports the latest versions of SPFx, officially, SharePoint 2019 only supports up to version 1.4.1. This is quite an issue as this version only supports React 15.6 and Typescript 2.4, meaning a lot of other packages will require old versions.

Another limiting factor is the Office UI Fabric React library that ships is stuck on 5.21 whereas the latest (7.9) has a lot of bug fixes that we miss out on.

The main problem here is that because SPFx is locked to a specific version of React, we cannot use a later version of typescript as React doesn't support it. And because we don't have the latest versions of React OR Typescript, we are locked to a lower version of Fabric as well.


Using any package

Luckily we get around these limitations by modifying the gulp script and specifying later versions of those packages in our installed modules.

package.json

_43
{
_43
// ... meta
_43
// ... scripts
_43
"dependencies": {
_43
"@microsoft/sp-core-library": "1.4.1",
_43
"@microsoft/sp-lodash-subset": "1.4.1",
_43
"@microsoft/sp-office-ui-fabric-core": "1.4.1",
_43
"@microsoft/sp-webpart-base": "1.4.1",
_43
_43
// add own versions of react as dependencies
_43
"react": "16.12.0",
_43
"react-dom": "16.12.0",
_43
_43
// add fabric
_43
"office-ui-fabric-react": "7.90.0",
_43
},
_43
_43
// REQUIRED FOR YARN
_43
// add resolutions for react types, fabric and typscript for yarn to be able to use our
_43
// specified versions, instead of bundled peer dependencies in sub packages
_43
"resolutions": {
_43
"@types/react": "16.9.5",
_43
"typescript": "^3.6.3",
_43
"office-ui-fabric-react": "^7.45.1"
_43
},
_43
_43
"devDependencies": {
_43
"@types/es6-promise": "0.0.33",
_43
"@types/webpack-env": "1.13.1",
_43
"@types/chai": "3.4.34",
_43
"@types/mocha": "2.2.38",
_43
"@microsoft/sp-build-web": "1.4.1",
_43
"@microsoft/sp-module-interfaces": "1.4.1",
_43
"@microsoft/sp-webpart-workbench": "1.4.1",
_43
"ajv": "~5.2.2",
_43
"gulp": "~3.9.1",
_43
_43
// add react types and typescript as dev dependencies
_43
"@types/react": "16.9.19",
_43
"@types/react-dom": "16.9.0",
_43
"typescript": "3.7.5"
_43
}
_43
}

Installing the above will grant us access to the packages in our dev environment, however, SPFx has a built-in webpack operation that strips out included versions of React by default, and locks it to the version used in the SharePoint environment. This will cause any code that leverages newer features not available in these versions to blow up.

Luckily, we can edit the gulp script to tell web pack to ignore that rule and bundle in our specified versions:

gulpfile.js

_20
'use strict';
_20
_20
const gulp = require('gulp');
_20
const build = require('@microsoft/sp-build-web');
_20
build.addSuppression(/Warning - \[sass\] The local CSS class .* is not camelCase and will not be type-safe./gi);
_20
_20
// force use of projects specified typescript version
_20
const typeScriptConfig = require('@microsoft/gulp-core-build-typescript/lib/TypeScriptConfiguration');
_20
typeScriptConfig.TypeScriptConfiguration.setTypescriptCompiler(require('typescript'));
_20
_20
// force use of projects specified react version
_20
build.configureWebpack.mergeConfig({
_20
additionalConfiguration: (generatedConfiguration) => {
_20
generatedConfiguration.externals = generatedConfiguration.externals
_20
.filter(name => !(["react", "react-dom"].includes(name)))
_20
return generatedConfiguration;
_20
}
_20
});
_20
_20
build.initialize(gulp);

Now when the project is built and packaged it will include our version of React. This means that we can safely use the latest Typescript, which in turn means that we can use the latest version of Fabric as well.


Fabric

The only issue we have found so far is that there are some slight naming conflicts with the default theme in the version of fabric that is embedded in SharePoint 2019. The workaround we have in place for this is to force default values in the components we use our project:

index.tsx

_6
import { loadTheme } from "@uifabric/styling";
_6
import { themeRulesStandardCreator } from "office-ui-fabric-react";
_6
_6
// this forces a default theme that loads in the new base
_6
// theme object so values are available to new fabric components
_6
loadTheme(themeRulesStandardCreator());


Andrew McMahon
These are a few of my insignificant productions
by Andrew McMahon.