Friday, June 22, 2018

SPFx 1.5 npm install errors

I recently wanted to upgrade my SPFx project from 1.4 to 1.5 release.

I followed the instructions on sp-dev-docs for the upgrade (found here: https://github.com/SharePoint/sp-dev-docs/wiki/Release-Notes-for-SharePoint-Framework-Package-v1.5)

But at the last step - running npm install - I got a breaking error that would not let npm install complete:

Error:

node-sass@4.9.0 install C:\testspfx\node_modules\node-sass
node scripts/install.js
connect ETIMEDOUT 52.216.168.43:443
Timed out whilst downloading the prebuilt binary
Hint: If github.com is not accessible in your location
try setting a proxy via HTTP_PROXY, e.g.
  export HTTP_PROXY=http://example.com:1234
or configure npm proxy via
  npm config set proxy http://example.com:8080
phantomjs-prebuilt@2.1.16 install C:\testspfx\node_modules\phantomjs-prebuilt
node install.js
Considering PhantomJS found at C:\Users\xxx\AppData\Roaming\npm\phantomjs.CMD
Looks like an npm install -g on windows; skipping installed version.
Downloading https://github.com/Medium/phantomjs/releases/download/v2.1.1/phantomjs-2.1.1-windows.zip
Saving to C:\Users\xxx\AppData\Local\Temp\phantomjs\phantomjs-2.1.1-windows.zip
Receiving...
Error making request.
Error: connect ETIMEDOUT 52.216.168.43:443
at Object._errnoException (util.js:992:11)
at _exceptionWithHostPort (util.js:1014:20)
at TCPConnectWrap.afterConnect [as oncomplete] (net.js:1186:14)
Please report this full log at https://github.com/Medium/phantomjs
npm WARN ajv-keywords@3.2.0 requires a peer of ajv@^6.0.0 but none is installed. You must install peer dependencies yourself.
npm WARN optional SKIPPING OPTIONAL DEPENDENCY: fsevents@1.2.4 (node_modules\fsevents):
npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for fsevents@1.2.4: wanted {"os":"darwin","arch":"any"} (current: {"os":"win32","arch":"x64"})
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! phantomjs-prebuilt@2.1.16 install: node install.js
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the phantomjs-prebuilt@2.1.16 install script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.
npm ERR! A complete log of this run can be found in:
npm ERR! C:\Users\xxx\AppData\Roaming\npm-cache_logs\2018-06-21T17_03_52_895Z-debug.log
      _=+#####!
   ###########|       .-----------------------------------.
   ###/    (##|(@)    |          Congratulations!         |
   ###  ######|   \   |    Solution tester is created.    |
   ###/   /###|   (@) |  Run gulp serve to play with it!  |
   #######  ##|   /   '-----------------------------------'
   ###     /##|(@)
   ###########|
      **=+####!


My setup:

My package.json file is as follows:

{
  "name": "dvp",
  "version": "1.0.1",
  "private": true,
  "engines": {
    "node": ">=0.10.0"
  },
  "dependencies": {
    "@microsoft/sp-client-base": "~1.0.0",
    "@microsoft/sp-core-library": "~1.5.0-plusbeta",
    "@microsoft/sp-webpart-base": "~1.5.0-plusbeta",
    "@types/knockout": "3.4.55",
    "@types/webpack-env": "1.13.1",
    "@types/es6-promise": "0.0.33",
    "knockout": "3.4.2"
  },
  "devDependencies": {
    "@microsoft/sp-build-web": "~1.5.0-plusbeta",
    "@microsoft/sp-module-interfaces": "~1.5.0-plusbeta",
    "@microsoft/sp-webpart-workbench": "~1.5.0-plusbeta",
    "@types/chai": ">=3.4.34 <3 .6.0="" mocha="" types="">=2.2.33 <2 .6.0="" build="" bundle="" clean="" code="" gulp="" knockout-paging="" scripts="" test="">


Cause and workaround:

I created a new project using version 1.5 but got the same error.
So, next - I removed all packages in my package.json, deleted my node_modules folder and added them back one by one running npm install after each one to see which one was causing this issue.

I found the cause for this issue is coming from a dependency of one of the "@microsoft/sp" packages in my dev dependencies... not something I can live without.

I still can't be sure what is causing this issue but a bit of googling around I encountered a lot of people had a similar issue a few months or years back.

It seems to be something with the npm package installer causing it, and the workaround many people were using was:

npm install phantomjs-prebuilt@2.1.16 --ignore-scripts

So, I ran that command separately which completed successfully. Next I run the full npm install and what do you know! It finished successfully (with the regular list of 100+ warnings LOL)

Ran gulp, fixed a couple of lines of code that had to be changed and done. Now my project compiles and runs on SPFx 1.5

Still, this took an awful lot of time and the upgrade process is still something I fear as I have yet to have a single version upgraded without running into some npm hell like that (or worst) that just took half a day of work to fix.


Well, hope this helps someone else save some time! Good luck!

(reference github issue: https://github.com/SharePoint/sp-dev-docs/issues/2092)

Monday, May 7, 2018

SharePoint 2013 date picker scrolls form to the top

Just recently noticed a bug in SharePoint 2013... Yeah, I know it is 2018 now LOL

The bug is simple but very annoying.
If you have a long list form, with many columns, and you have a few date columns at the bottom - beyond the scroll position - clicking any date picker will open the picker but will scroll your page to the top.

This happens when using non-IE browsers (I use chrome), and it is the result of the following code running INSIDE the picker iframe:
    function: setFocusDatepicker

Is trying to set focus to the current date element.

Now, since this code is executed in the iframe it could be tricky to fix, since we don't have any code running in that iframe, but our code runs on the current window...

But there seems to be a fix for that we can use a little (a lot actually) JavaScript trickery to manipulate the frame's code from the containing document.

We will hook up to OnIframeLoadFinish function, which is called when the iframe of the picker is ready.

Once inside, we will find the function setFocusDatepicker INSIDE the iframe.
(Note: this is only allowed since we are on the same domain as the iframe...)

Then we will override the setFocusDatepicker to keep the workspace scrollTop, call setFocusDatepicker, and then restore the workspace scrollTop.

Here is the complete code, just call it once after all scripts were loaded:


ExecuteOrDelayUntilScriptLoaded( function() { if (typeof(window.original_OnIframeLoadFinish) !== 'function') { window.original_OnIframeLoadFinish = window.OnIframeLoadFinish; window.OnIframeLoadFinish = function() { original_OnIframeLoadFinish.apply(this, arguments); window.Picker.contentWindow.original_setFocusDatepicker = window.Picker.contentWindow.setFocusDatepicker; window.Picker.contentWindow.setFocusDatepicker = function() { workspaceTop = document.getElementById('s4-workspace').scrollTop; window.Picker.contentWindow.original_setFocusDatepicker.apply(this, arguments); document.getElementById('s4-workspace').scrollTop = workspaceTop; } } } }, "datepicker.js");

Enjoy!

Monday, April 9, 2018

Upgrading SPFx React from 1.1.0 to 1.4.0 build errors

Hey guys,

I've been playing with my SPFx demo project (code here on GitHub) getting ready for my session @SPSTC when I decided perhaps its time to upgrade one of my demo web parts to SPFx version 1.4.0 while keeping the other one in 1.1.0 so that I can discuss the upgrade process.

The upgrade process is, as I stated many times, a very tedious and hard manual work - and VERY error prone and time consuming.

Here are a few notes I gathered from this upgrade that I'd like to share - join my session to get the full picture!

Following this article as my base-line: https://docs.microsoft.com/en-us/sharepoint/dev/spfx/toolchain/update-latest-packages
There are a few things that went wrong here...

React versions

If you follow this guide, it says to run npm outdated and get all packages to the latest versions. Well, that simply is bad advice since when it comes to the react packaged - you should get the same version that the Microsoft packages are using. This is not explained anywhere - you just end up with hundreds of errors in your gulp command with no clue why they are there or how to fix them. I simply went into the Microsoft packages and saw they were using these versions so I used the same:
  • "@types/react": "15.6.6"
  • "@types/react-dom": "15.5.6"
  • "react": "15.6.2"
  • "react-dom": "15.6.2"
That brought down the errors count to 1. Sounds simple? Not so much...

React createComponent error

See, in my web part demo that was built on version 1.1.0 of SPFx - the react component class was declared as:
export default class ReactWebPart extends React.Component<IReactWebPartProps, void>
In the web part class, it was used in this code:
      const element: React.ReactElement<IReactWebPartProps> = React.createElement<IReactWebPartProps>(
        ReactWebPart,
        {
          description: this.properties.description,
          userName: Utilities.GetUserName(this.context as any),
          license: licenseMessage,
          color: this.properties.color
        }
      );
which, in turn, produced this error message:
Error - typescript - src/webparts/reactWebPart/ReactWebPartWebPart.ts(27,8): error TS2345: Argument of type 'typeof ReactWebPart' is not assignable to parameter of type 'string | ComponentClass<IReactWebPartProps> | StatelessComponent<IReactWebPartProps>'.
Error - 'typescript' sub task errored after 4.49 s
 TypeScript error(s) occurred.
So, we checked the typescript version we were running, all the npm modules dependencies and versions - they all seemed to check out.
We went with our favorite way for fixing SPFx versioning issues:
We created a new sample SPFx React web part, and if that one (hopefully) compiles - we compare the two.

In our case, since this is a sample component without a lot of code - it was easier to find the difference between the two.
In the new project, the react component class is defined with one difference:
export default class ReactWebPart extends React.Component<IReactWebPartProps, {}>
See, the "void" that was sent in as the react state was changed to an empty object.

This made the error go away and now our project compiles with no problem. Yay!

I can't help but feeling SPFx tooling still has a long way to go before it will be adopted by the mass development community. It can get pretty frustrating every time you have to move computers or upgrade versions to the point that it is just scary and unpredictable.

That said - I have to admit it is brilliant, fast and fun to build on when you get it to compile. So - I'm keeping my hopes up for this platform.

I will continue to provide this feedback to the team @Microsoft, which are doing a great job at listening for feedback, but please also share your experience in the comments below, on their GitHub project  or by voting on user voice requests.

Here is a link to the GitHub with this project in case you want to see the code changes during the upgrade: https://github.com/KWizCom/SPFxDemo

Hope this helps,
Shai.
Funny thing... not 5 minutes after posting this, I went back to my demo and run gulp. Guess what? It errored out. This time showing this strange error:
[17:53:08] Error - Unknown
 Cannot find module 'typescript'
Guess what worked this time to fix this? delete node_modules folder and running npm install again...