chris obrien - pitfalls when developing with the sharepoint framework (spfx)
TRANSCRIPT
Pitfalls when developing with the SharePoint Framework (SPFx)Chris O’Brien (MVP)Independent/Content and Code, UK
Add Speaker
Photo here
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
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
COB App- node_modules
- jQuery- node_modules
- cache-swap- node_modules
- React- node_modules
……
Simplified node_modules hierarchy
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
Understanding package.json
dependencies node• Lists all 3rd party libraries needed to
run
devDependencies node• Lists all 3rd party libraries needed to
develop/build
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
Fundamentals3 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
Versioning/dependency pitfalls
Using caret dependencies (the
default)
Not specifying –save on npm install
Dev:
Not locking dependencies
down
Shipping:
Will change in npm 5!
--save(until npm 5)
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
npm shrinkwrap
Tip - check-in npm-shrinkwrap.jsonfor 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
Remember the rule:
= OK
^ = Not OK
Recommendations – versioning etc.
Pitfall How avoided More reading
Avoid dependency issues in dev
Ensure devs *save* packages properly – use npminstall --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
Code re-use pitfall
Copy/pasting JS code into each app, because not clear how to re-use properly
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)
Re-using existing JS code
Access module with ‘require’
• var cobUtil = require('cob-utility')
• cobUtil.StringIsEmpty("foo");
So, now you have a module.
How to include/reference that?
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.com/en-us/docs/package/install
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/how-to-manage-private-npm-modules.html
http://stackoverflow.com/questions/21233108/cross-project-references-between-two-projects
SPFX coding pitfalls
Dealing with asynccode/ promises
Calling the Microsoft Graph (permutations)
Calling secure APIs (AAD)Office UI Fabric
Adding a library
TypeScript issues
Pitfall – Office UI Fabric issues
Problem:You want to use Fabric but are confused..
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.
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)
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
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
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
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)
Future option – Graph/customAPIs
Graph - Specify additional permission scopes for GraphHttpCliente.g. I’m OK with all SPFx web parts having access to more than Groups and Reports
Your APIs/Azure FunctionsSpecify 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",
}
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 APIissues
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
Pitfalls - deployment
Accidentally bundling external
libraries/frameworks
Accidentally shipping a debug build
Losing track of remote JS code
Bundling considerations
Libraries are included in your bundle BY DEFAULTUpdate config.json if (e.g.) jQuery should be referenced from CDN
One bundle per web part BY DEFAULT - across your site10 web parts = 10 different copies of jQuery being downloaded
GUID in bundle URL is regenerated on each build
This is the versioning/cache-busting mechanism
TIP – delete unused JS files from CDN to keep things tidy
Bundling – rule #1
“Externalise” where possible (CDN):
Bundling – rule #2
Ensure any libs you ARE bundling are consolidated (with SPFx component bundles):
WP1 WP2
cob-bothWebParts.js
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
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
Bundling – how it goes wrong
Perhaps a 2nd web part is added..
Some libraries are installed using npm (e.g. Angular)..
Bundling – how it goes wrong
gulp bundle --ship
gulp deploy-azure-storage
gulp package-solution --ship
SPFx deployment process:
Bundling – how it goes wrongApp package added to App Catalog:
Bundling – done wrong