A presentation given at ESPC 2017, discussing common pitfalls in SPFx development. Includes discussion of versioning and dependency issues, code re-use, SPFx component bundles, Office UI Fabric and more.
All These Sophisticated Attacks, Can We Really Detect Them - PDF
Chris OBrien - Pitfalls when developing with the SharePoint Framework (SPFx)
1. Pitfalls when developing with the
SharePoint Framework (SPFx)
Chris O’Brien (MVP)
Independent/Content and Code, UK
Add
Speaker
Photo here
2. Notes on this presentation
If you have previously seen this presentation/slide deck
before, note the following updates:
Content Slides
Pitfalls around Office UI Fabric 27-30
Pitfalls around calling the Microsoft
Graph or custom APIs secured with Azure
Active Directory
31-35
Use of SPFx component bundles 40-42
3.
4. Fundamentals – how it all works
Packages installed/updated using npm
• .NET analogy = NuGet
Dependent JS libraries stored in node_modules
• .NET analogy = the BIN directory
• Gets bundled/deployed with your app
Package.json records your top-level dependencies
• .NET analogy = packages.config
• Allows other devs to build app from source control
• N.B. Each dependency may have IT’S OWN dependencies and package.json
6. Fundamentals - how to add a library
Use npm install command e.g:
npm install jquery
Installs library to your app (in node_modules)
Important parameter:
--save OR --save-exact
Usually add TypeScript typings (for auto-complete)
npm install @types/jquery -–save
8. Semantic versioning (semver)
Example Known as Meaning
^1.2.1 Caret dependency Greater than or equal to 1.2.1, but less than 2.0.0
~1.2.1 Tilde dependency Greater than or equal to 1.2.1, but less than 1.3.0
1.2.1 Exact dependency 1.2.1 only
Fundamentals
3 part version number – e.g. 1.0.0
Major.Minor.Patch
Major = breaking change/substantial differences
Minor = non-breaking e.g. new methods
Patch = no interface changes e.g. optimisations,
documentation
11. Dependencies and shipping
The problem – “dependency float”
• Your app has many JS dependencies (the node_modules tree)
• node_modules should not be checked-in
• Different version somewhere in tree -> Broken app
The solution – npm shrinkwrap
• Generates npm-shrinkwrap.json file
Critical to getting a “100% reproducible build”
• Locks down dependencies – for entire node_modules tree
12. npm shrinkwrap
Tip - check-in npm-shrinkwrap.json
for each shipped release
• Allows exact build to be recreated
• Allows other devs to build exact app from
source control
Better than save-exact – deals with
full dependency tree
• save-exact only deals with top-level
dependencies
15. Recommendations – versioning etc.
Pitfall How avoided More reading
Avoid dependency issues
in dev
Ensure devs *save* packages properly – use npm
install --save/--save-exact.
Consider custom .npmrc file across team
http://cob-
sp.com/2fOtApJ
Avoid dependency issues
when shipping
Use npm shrinkwrap for each release https://docs.npmjs.
com/cli/shrinkwrap
18. Re-using existing JS code
Create a module for your code
• Expose each method with exports statement:
module.exports = {
CheckRealValue: COB.CORE.Utilities.CheckRealValue,
StringIsEmpty: COB.CORE.Utilities.StringIsEmpty
}
Create package.json file
• Specify entry point (file)
19. Re-using existing JS code
Access module with ‘require’
• var cobUtil = require('cob-utility')
• cobUtil.StringIsEmpty("foo");
20.
21. So, now you have a module.
How to include/reference that?
22. Some popular options
Use npm LOCAL packages
• Install from file path (COPY) or use NPM LINK
Use node_modules higher up filesystem
• Take advantage of “recurse upwards” approach of npm- See http://cob-
sp.com/2eXDJOI
Use private package hosting
• npm private packages - $7 pm/user
• VSTO private hosting - $4 pm/user
Also consider:
https://www.visualstudio.co
m/en-
us/docs/package/install
23. Recommendations – code re-use
Pitfall How More reading
Copy/pasting JS code into
each project
Create modules for existing code
Consider module strategy:
• npm install [filepath]
• npm link (for “parallel dev” of client and utility
code)
• Use of npm private packages etc.
http://nicksellen.co.
uk/2015/04/17/ho
w-to-manage-
private-npm-
modules.html
http://stackoverflo
w.com/questions/2
1233108/cross-
project-references-
between-two-
projects
24.
25. SPFX coding pitfalls
Dealing with async
code/ promises
Calling the
Microsoft Graph
(permutations)
Calling secure APIs
(AAD)Office UI Fabric
Adding a library
TypeScript issues
26. Pitfall – Office UI Fabric issues
Problem:
You want to use Fabric but are confused..
27. Office UI Fabric
• Office UI Fabric Core a.k.a. Fabric Core - this is a set of
core styles, typography, a responsive grid, animations,
icons, and other fundamental building blocks of the
overall design language.
• Office UI Fabric React a.k.a. Fabric React - this package
contains a set of React components built on top of the
Fabric design language.
28. Pitfall – Office UI Fabric issues
Problem:
You want to use Fabric but are confused..
Solution:
• To use Fabric Core easily, use SPFx v1.3.4
or later (
• Using React? Can use Fabric React
components – use individual static links
(for bundle size)
Key npm packages:
• office-ui-fabric-
react
• @microsoft/sp-
office-ui-fabric-
core (new)
29. Correct use of Fabric React (bundling
approach)
WARNING – React styles are bundled with EACH web part in this
approach. Mitigate with SPFx component bundles if you need to (e.g.
expecting many of your web parts on page).
See http://cob-sp.com/2hPVmUc
30. Pitfall – calling the Graph/custom APIs
Problem:
You need to call the Graph or a custom API
from SPFx (i.e. AAD-secured)
Solution:
• Understand today’s options:
• GraphHttpClient (limited scenarios!)
• AAD app + adal.js
• AAD app + SPO auth cookie/IFrame approach
• Understand a future option:
• AAD app + tell SPFx to trust it
31. Graph/custom API permutations
- GraphHttpClient
- or more likely, use of adal.js
Calling the Graph from
client-side
- adal.js
- SPO auth cookie/IFrame
Calling custom API (AAD)
from client-side
•- adal.js from client (SPO auth cookie approach gives token
which cannot be used with Graph)
- adal.NET within custom API
OR
- New Azure Functions bindings (preview – can’t get to work!)
- Use of both “on behalf of user” and “app-only”
Calling custom API
(AAD) from client-side
which calls the Graph
Reference:
Connect to API
secured with AAD -
http://cob-
sp.com/SPFx-AAD
32. Cheat sheet - custom APIs/Azure Functions
with AAD
ADAL.js
• CORS – define rule for each
calling page
• Code - Ensure asking for
token for your resource
(AAD client ID)
SPO auth cookie approach
• Empty CORS rules
• Code:
• Pass “credentials” :
“include” header, and sure
API/Function can receive..
• IFrame onto Function URL
Reference:
Connect to API
secured with AAD -
http://cob-
sp.com/SPFx-AAD
CONSIDER:
• Each web part/extension on
page must sign-in
• AAD reply URL needed for
each page with WP (max 10!)
CONSIDER:
• Sign-in applies to entire
page/session
• Cannot access user
identity (app-only)
33. Future option – Graph/customAPIs
Graph - Specify additional permission
scopes for GraphHttpClient
e.g. I’m OK with all SPFx web parts having access to
more than Groups and Reports
Your APIs/Azure Functions
Specify additional custom APIs for same token
Benefit – no need for sign-in button in your
WP/extension
Dev preview late 2017?
{
"WebApiPermissionRequest": {
"ResourceId": “GUID goes here",
"Scope": “GUID goes here",
}
"WebApiPermissionRequest": {
"ResourceId": “GUID goes here",
"Scope": “GUID goes here",
}
"WebApiPermissionRequest": {
"ResourceId": “GUID goes here",
"Scope": “GUID goes here",
}
34. Recommendations – coding
Pitfall How avoided More reading
Office UI Fabric
issues
Get familiar with:
• Fabric Core vs. Fabric React components
• SPFx 1.3.4/sp-office-ui-fabric-core package
• Using mixins in your SCSS
http://cob-sp.com/SPFx-
OUIF
Graph/custom API
issues
Get familiar with:
• Register AAD apps + adal.js
• SPO auth cookie approach
• Future SPFx option
http://cob-sp.com/SPFx-AAD
Async code issues Get familiar with:
• Promises
http://cob-sp.com/SPFX-
Promises
Security issues Avoid SPFX if sensitive data sent to client (page
or JS) - use Add-in parts/IFrames if needed
http://cob-sp.com/2ez9JNX
37. Bundling considerations
Librariesare includedin your bundle BY DEFAULT
Update config.json if (e.g.) jQuery should be referenced from CDN
One bundleper web part BY DEFAULT - across your site
10 web parts = 10 different copies of jQuery being downloaded
GUID in bundleURL is regeneratedon each build
This is the versioning/cache-busting mechanism
TIP – delete unused JS files from CDN to keep things tidy
40. Bundling – rule #2
Ensure any libs you ARE bundling are consolidated (with
SPFx component bundles):
WP1 WP2
cob-bothWebParts.js
41. Recommendations – deployment
Pitfall How avoided More reading
Accidental
bundling
Ensure libs loaded externally where possible
Update “externals” section of config.json
Waldek - http://cob-
sp.com/2frVMR3
Duplication of code
in bundle
Use SPFx component bundles Elio - http://cob-
sp.com/SPFx-
CompBundle
Losing track of
remote JS code
• Proactively track CDN locations (e.g. Excel?)
• Use SPCAF to help identify
www.spcaf.com
42. Key take-aways
It’s a new world, with different pitfalls!
Recommendations:
Get familiar with NPM especially
Plan for code re-use (e.g. modules) if appropriate
Practice “production” deployments
Dependencies/versioning e.g. dependency float
Coding e.g. OUIF, calling the Graph or custom APIs
Deployment e.g. accidental bundling, duplication in bundle