I’ve been working with SPFx for SharePoint Online for quite a while and have done numerous client projects for it but recently I’ve been asked to create a few SPFx web parts that would work on both SharePoint Online (SPO) and SharePoint 2019 (SP2019). I’d done a couple SP2019 web parts and extensions in the past but they were pretty simple and I didn’t really pay too much attention to some core pieces but now that I’m doing projects of a more complex nature I decided I should pay attention. In doing so I found a few minor issues with the initial project setup and documentation that caused me some headaches so I figured I’d document those issues here for others to find. I’ll add more if I stumble across others and feel free to add your discoveries in the comments.

SPFx Dependency Version

I’m currently using version 1.12.1 of the solution generator but of course if you are targeting SP2019 it’s going to set the package dependencies to 1.4.0 (or specifically “~1.4.0” - more on that in a bit). I prefer to use the latest supported version for the platform which, for me, means that it would be better if solution generator would actually 1.4.1 instead. You can see the release notes for 1.4.1 here: https://docs.microsoft.com/en-us/sharepoint/dev/spfx/release-1.4.1. There’s not too much included in this release, namely the support for Node v8 and NPM v5 - the rest is just preview APIs which I’ll cover later in this post.

If you want to upgrade the default solution to the 1.4.1 version just run the following command:

1npm install --save --save-exact @microsoft/sp-core-library@1.4.1 @microsoft/sp-webpart-base@1.4.1 @microsoft/sp-lodash-subset@1.4.1 @microsoft/sp-office-ui-fabric-core@1.4.1

Again, given the small number of changes it might not be worth doing this but I prefer to be on the latest supported version where possible so I’ll often do this right out of the gate.

Make Sure You Use The Exact Version (–save-exact)

In the last section recall that I noted that the solution generator specifically uses the “~1.4.0” version of the SPFx dependencies. In my opinion this is an error and it should be “1.4.0” (or preferably “1.4.1”). The reason for this is simple - if you are forced to delete the package-lock.json file for some reason (and there are numerous reasons why you might have to do so) then the next time you run npm install it will result in all sorts of errors because that little tilde (~) is going to result in dependencies on 1.12 (or whatever the latest version is) to be installed even though you haven’t added any directly. Basically the @microsoft/sp-webpart-base project will trigger a cascade of references to other newer versions of the project including adding references to @uifabric which isn’t supported with React v15 (which is required for SP2019).

If you look at the package.json file for the @microsoft/sp-webpart-base after doing the install you’d see the following (some chunks removed for brevity):

 1{
 2  "_from": "@microsoft/sp-webpart-base@^1.4.1",
 3  "_id": "@microsoft/sp-webpart-base@1.12.1",
 4  "_inBundle": false,
 5  "_location": "/@microsoft/sp-webpart-base",
 6  "_phantomChildren": {
 7    "@types/z-schema": "3.16.31",
 8    "loose-envify": "1.4.0",
 9    "object-assign": "4.1.1",
10    "prop-types": "15.7.2",
11    "scheduler": "0.15.0",
12    "z-schema": "3.18.4"
13  },
14  "_requested": {
15    "type": "range",
16    "registry": true,
17    "raw": "@microsoft/sp-webpart-base@^1.4.1",
18    "name": "@microsoft/sp-webpart-base",
19    "escapedName": "@microsoft%2fsp-webpart-base",
20    "scope": "@microsoft",
21    "rawSpec": "^1.4.1",
22    "saveSpec": null,
23    "fetchSpec": "^1.4.1"
24  },
25  "_resolved": "https://registry.npmjs.org/@microsoft/sp-webpart-base/-/sp-webpart-base-1.12.1.tgz",
26  "_spec": "@microsoft/sp-webpart-base@^1.4.1",
27  "dependencies": {
28    "@microsoft/sp-component-base": "1.12.1",
29    "@microsoft/sp-core-library": "1.12.1",
30    "@microsoft/sp-diagnostics": "1.12.1",
31    "@microsoft/sp-dynamic-data": "1.12.1",
32    "@microsoft/sp-http": "1.12.1",
33    "@microsoft/sp-loader": "1.12.1",
34    "@microsoft/sp-lodash-subset": "1.12.1",
35    "@microsoft/sp-module-interfaces": "1.12.1",
36    "@microsoft/sp-page-context": "1.12.1",
37    "@microsoft/sp-property-pane": "1.12.1",
38    "@microsoft/teams-js": "1.8.0",
39    "@types/office-js": "1.0.36",
40    "office-ui-fabric-react": "7.156.0",
41    "react": "16.9.0",
42    "react-dom": "16.9.0",
43    "tslib": "~1.10.0"
44  }

So you can see that the version is 1.4.1 (I had upgraded to v1.4.1 in this case) but it introduces all kinds of dependencies on v1.12.1 which is just bad. However, if you get rid of the tilde and then run npm install you won’t have this issue and it will keep all of the v1.12.1 references out of the project.

This is why in the previous section I used --save-exact when demonstrating how to update the project to v1.4.1. The use of --save-exact removes the tilde and fixes the issue (of course if you initialize the project without installing the dependencies then you can simply manually delete the tilde and then you’ll be good to go).

Preview APIs Missing

In the first section I mentioned that the release notes for v1.4.1 included details about preview APIs that were available. The API I was particularly interested in was the AadHttpClient and related components. There’s a ton of documentation out there that specifically states that in order to use the AadHttpClient that you must use v1.4.1 - here’s a prime example: https://docs.microsoft.com/en-us/sharepoint/dev/spfx/use-aadhttpclient. The image below shows a screenshot of that documentation in case it gets changed:

Connect to Azure AD-secured APIs in SharePoint Framework solutions Page Snippet

The problem I ran into, however, was that the preview APIs are not in fact present in the v1.4.1 build as stated by the documentation (the documentation doesn’t even refer to the as preview APIs for v1.4.1, you have to go to the release notes to find out that they were just previews). So back when v1.4.1 first came out these preview APIs were likely present (I honestly don’t know) but as of today there’s no way to get to them in this version and you’d have to deploy v1.5.0 to use them, but of course, that won’t work with SP2019 so if you’re looking to create an SPO/SP2019 app that connects to resources secured with Azure AD you’ll be stuck using the ADAL JS library instead. Hopefully the documentation will be correctly soon but apparently nobody has noticed this in a couple of years so it would seem that using SP2019 with Azure AD secured resources is somewhat of an edge case.

TSLINT Doesn’t Work

SPFx has gone through a couple changes when it comes to how tslint is configured. It used to be that there was a tslint.json file in the root config folder of the project. That file would look something like this:

 1{
 2    "$schema": "https://developer.microsoft.com/json-schemas/core-build/tslint.schema.json",
 3    "displayAsWarning": true,
 4    "removeExistingRules": true,
 5    "useDefaultConfigAsBase": false,
 6    "lintConfig": {
 7        "rules": {
 8            "class-name": false,
 9            "export-name": false,
10            "forin": false,
11            "label-position": false,
12            "member-access": true,
13            "no-arg": false,
14            "no-console": false,
15            "no-construct": false,
16            "no-duplicate-case": true,
17            "no-duplicate-variable": true,
18            "no-eval": false,
19            "no-function-expression": true,
20            "no-internal-module": true,
21            "no-shadowed-variable": true,
22            "no-switch-case-fall-through": true,
23            "no-unnecessary-semicolons": true,
24            "no-unused-expression": true,
25            "no-use-before-declare": true,
26            "no-with-statement": true,
27            "semicolon": true,
28            "trailing-comma": false,
29            "typedef": false,
30            "typedef-whitespace": false,
31            "use-named-parameter": true,
32            "valid-typeof": true,
33            "variable-name": false,
34            "whitespace": false,
35            "prefer-const": true,
36            "no-null": false,
37            "no-any": false,
38            "max-line-length": false
39        }
40    }
41}

And then things changed so that the tslint.json file was moved to the root folder (where it always should have been IMHO) and the structure was changed to inherit from base-tslint.json as such:

 1{
 2  "extends": "./node_modules/@microsoft/sp-tslint-rules/base-tslint.json",
 3  "rules": {
 4    "class-name": false,
 5    "export-name": false,
 6    "forin": false,
 7    "label-position": false,
 8    "member-access": true,
 9    "no-arg": false,
10    "no-console": false,
11    "no-construct": false,
12    "no-duplicate-variable": true,
13    "no-eval": false,
14    "no-function-expression": true,
15    "no-internal-module": true,
16    "no-shadowed-variable": true,
17    "no-switch-case-fall-through": true,
18    "no-unnecessary-semicolons": true,
19    "no-unused-expression": true,
20    "no-use-before-declare": true,
21    "no-with-statement": true,
22    "semicolon": true,
23    "trailing-comma": false,
24    "typedef": false,
25    "typedef-whitespace": false,
26    "use-named-parameter": true,
27    "variable-name": false,
28    "whitespace": false,
29    "no-any": false,
30    "max-line-length": false
31  }
32}

The problem is that when you’re targeting SP2019 and using v1.4 of the framework it doesn’t properly handle the new structure so you have to basically revert to the old structure and then replace the tslint.json file in the root with the following:

1{
2    "rulesDirectory": "./config"
3}

There might be another (better?) way to make this work - I’m no expert on tslint - but this is the only way I could find to make it work. Otherwise my project was overwhelmed with all kinds of typescript errors and warnings on build that did not reflect what I was seeing in the editor as the rules defined in the root file were just outright ignored.

Conclusion

I suspect there’s a ton more issues around SP2019 and SPFx but these were just a handful that I ran into with just trying to get a simple project going with the core dependencies I knew I’d need so I figure others might eventually bump into these as well at some point. I posted all of these issues on the git project site (https://github.com/SharePoint/sp-dev-docs/issues/7304) and Pat Miller has been helping me through them so you can see the history of those discussions there (this article is basically a summary of that issue but I wanted to post here as well so you didn’t have to read the back and forth discovery bits). If you find other issues that aren’t well documented please comment about them here and maybe other readers might find it useful.