Sp-dev-docs: Cannot update to React ^16.0.0

Created on 4 Feb 2018  路  31Comments  路  Source: SharePoint/sp-dev-docs

Category

  • [X] Question
  • [ ] Typo
  • [X] Bug
  • [ ] Additional article idea

Expected or Desired Behavior

In order to be able to use FontAwesome v5 and the official fortawesome/react-fontawesome module, I need to be able to use React ^16.0.0 with SharePoint Framework.

  1. How can I use React ^16.0.0 with SPFx?
  2. If it is absolutely impossible now, where is it on the roadmap?

    • Is there a plan to upgrade to React ^16.0.0 in the near (i.e. < 3 months) future?

    • Is there a plan to make react version coupling less strict in the future at all?

Observed Behavior

It is not possible to use React ^16.0.0 with SPFx due to unnecessarily tight coupling of version dependencies. Many other modules are now requiring React with versions other than the very tightly specified versions used with SPFx, which is hampering development efforts.

Attempting to use React ^16.0.0 will cause module load to fail, even with successful compilation. Without React ^16.0.0 installed, many other modules will fail to work.

Steps to Reproduce

  1. Create a new SPFx project
  2. Update React by changing versions in package.json to ^16.0.0 and running npm update
  3. Execute the SPFx project
Author Feedback spfx-general no-recent-activity tracked discussion question

Most helpful comment

Ok I could reproduce it, it's definitely a problem with the webpack configuration.

The guys of Microsoft should fix it.

All 31 comments

It seems react and react-dom are automatically be registered in the loaderConfig as a scriptResource. _Where is this happening/configured? Somewhere deep in the gulp bundle task?_

Once you upgrade React, it is blowing up because the registered script resource has a version mismatch so it doesn't know where to find React.

Is there a way we can disable this automatic "scriptResource" registration and just let Webpack bundle it as a workaround?

/dist/{component-guid}.manifest.json

"loaderConfig": {
    "scriptResources": {
      "react": {
        "type": "component",
        "version": "16.2.0",
        "id": "0d910c1c-13b9-4e1c-9aa4-b008c5e42d7d",
        "failoverPath": "https://unpkg.com/react@16/umd/react.production.min.js"
      },
      "react-dom": {
        "type": "component",
        "version": "16.2.0",
        "id": "aa0a46ec-1505-43cd-a44a-93f3a5aa460a",
        "failoverPath": "https://unpkg.com/react-dom@16/umd/react-dom.production.min.js"
      },
      "@microsoft/sp-application-base": {
        "type": "component",
        "version": "1.4.1",
        "id": "4df9bb86-ab0a-4aab-ab5f-48bf167048fb"
      }
    }

Yields Error:
*Manifest not found for component id "0d910c1c-13b9-4e1c-9aa4-b008c5e42d7d" and version "16.2.0"

You could load your own version of React by removing react and react-dom from the list of externals through changing the gulpfile.js to:

'use strict';

const gulp = require('gulp');
const build = require('@microsoft/sp-build-web');
build.addSuppression(`Warning - [sass] The local CSS class 'ms-Grid' is not camelCase and will not be type-safe.`);

build.configureWebpack.mergeConfig({
    additionalConfiguration: (generatedConfiguration) => {
        generatedConfiguration.externals.splice(generatedConfiguration.externals.indexOf('react'), 1);
        generatedConfiguration.externals.splice(generatedConfiguration.externals.indexOf('react-dom'), 1);
        return generatedConfiguration;
    }
});

build.initialize(gulp);

By doing this however, you will not be able to use the local workbench which depends on React@15. It's also possible that you will stumble upon some other side effects as well so if you were to proceed down this path, I'd recommend you thoroughly test your solution before deploying it to production at your own risk.

Thank you @waldekmastykarz that worked as expected.

For my current use case, the project is a single Application Customizer, so losing local workbench is an acceptable sacrifice. If/When I need it, I'm guessing I can setup a build flag to toggle the webpack override, and leave react as external for local since it will get served from node_modules which will be version 16?

Any guidance on side effects I should be looking for? Are you thinking quirkiness related to 2 versions of react and react-dom on the page?

I'd agree, for me losing the local workbench is an acceptable loss if it means I can use the other tools and libraries I wish to in my development. I'll try this in the next couple of days and report back.

It would still be nice to have an officially supported mechanism for using React 16 though.

@DroopyTersen thanks for confirming it's working for you. Regarding the possible side effects it's hard to tell: I assume this scenario hasn't been tested, so either it could work just fine or you might stumble upon some hard to explain and reproduce issues. The best would be to test, test, test.

So, I can't get this to work, probably missing something simple. I've created a trivial example and pushed it up to https://github.com/PurpleGranite/Info.Insch.SpfxSandbox.

Loading the web part in that example results in the following error:

~~~
Original error: *Failed to load entry point from component "2a846d5b-9989-45cc-b7b8-68d8d4e8c231" (HelloWorldWebPart).
Original error: Error loading https://component-id.invalid/2a846d5b-9989-45cc-b7b8-68d8d4e8c231_0.0.1
Cannot read property 'placements' of undefined

INNERERROR:
*
Failed to load entry point from component "2a846d5b-9989-45cc-b7b8-68d8d4e8c231" (HelloWorldWebPart).
Original error: Error loading https://component-id.invalid/2a846d5b-9989-45cc-b7b8-68d8d4e8c231_0.0.1
Cannot read property 'placements' of undefined
*
*CALLSTACK:
Error
at t [as constructor] (https://spoprod-a.akamaihd.net/files/sp-client-prod_2018-03-09.017/sp-pages-assembly_en-us_8895c330a6dc6703110711151ff01ffe.js:301:15646)
at new t (https://spoprod-a.akamaihd.net/files/sp-client-prod_2018-03-09.017/sp-pages-assembly_en-us_8895c330a6dc6703110711151ff01ffe.js:700:37346)
at Function.e.buildErrorWithVerboseLog (https://spoprod-a.akamaihd.net/files/sp-client-prod_2018-03-09.017/sp-pages-assembly_en-us_8895c330a6dc6703110711151ff01ffe.js:700:43235)
at Function.e.buildLoadComponentError (https://spoprod-a.akamaihd.net/files/sp-client-prod_2018-03-09.017/sp-pages-assembly_en-us_8895c330a6dc6703110711151ff01ffe.js:700:39678)
at https://spoprod-a.akamaihd.net/files/sp-client-prod_2018-03-09.017/sp-pages-assembly_en-us_8895c330a6dc6703110711151ff01ffe.js:700:11287
at
~~~

@PurpleGranite I just had a look at your repo and can indeed repro the error you mentioned. If I however create a new SPFx project with a React web part and update React to v16, it works just fine. So I suspect the culprit is one of the dependencies you've added. Sorry I can't be of more help.

As an FYI - we'll be rolling out support for React 16 in the relatively near future. At that point, we'll follow the existing pattern of using the manifest version shared with the main application. Components build against 15 will continue to load a shared V15 version.

@waldekmastykarz I'll take a look at the dependencies later tonight - I'd suspect that it's ReactStrap that's triggering the issue as opposed to any of the other dependencies, but that (or something that accomplishes the same end goal, of making Bootstrap v4 components available via React) is critical to my development flow - I don't want to have to re-invent most of the functionality in that library, already started going down that route in an earlier iteration and it wasn't a satisfactory outcome.

@patmill that's excellent news :)
I can probably hold-off on further development on my project until full support for v16 is available, assuming 'relatively near' doesn't mean 6 months ... Looking forward to official v16 support.

A bit more digging, and I suspect the remaining issue is related to 'react-popper', which is required by reactstrap. Webpack is throwing errors related to modules differing only by case for this module, and the placements property mentioned in the SPFx error above is defined by react-popper.

Errors thrown by webpack are:
~~~
Warning - [webpack] 'dist':
./node_modules/react-popper/lib/Popper.js
There are multiple modules with names that only differ in casing.
This can lead to unexpected behavior when compiling on a filesystem with other case-semantic.
Use equal casing. Compare these module identifiers:

  • D:/PROJECTS/Info.Insch.HallMonitor2/Info.Insch.HallMonitor2.SPFx/node_modules/source-map-loader/index.js!D:/PROJECTS/Info.Insch.HallMonitor2/Info.Insch.HallMonitor2.SPFx/node_modules/react-popper/lib/Popper.js
    Used by 1 module(s), i. e.
    D:/PROJECTS/Info.Insch.HallMonitor2/Info.Insch.HallMonitor2.SPFx/node_modules/source-map-loader/index.js!D:/PROJECTS/Info.Insch.HallMonitor2/Info.Insch.HallMonitor2.SPFx/node_modules/react-popper/lib/react-popper.js
  • D:/PROJECTS/Info.Insch.HallMonitor2/Info.Insch.HallMonitor2.SPFx/node_modules/source-map-loader/index.js!D:/PROJECTS/Info.Insch.HallMonitor2/Info.Insch.HallMonitor2.SPFx/node_modules/react-popper/lib/popper.js
    Used by 2 module(s), i. e.
    D:/PROJECTS/Info.Insch.HallMonitor2/Info.Insch.HallMonitor2.SPFx/node_modules/source-map-loader/index.js!D:/PROJECTS/Info.Insch.HallMonitor2/Info.Insch.HallMonitor2.SPFx/node_modules/react-popper/lib/Popper.js
    ~~~

Still looking into how to fully resolve this - looks likely that input from other projects will be required.

Per Issue 111 for react-popper the build / load issue looks like it's probably something in the webpack config. That's buried deep inside one of the many supporting modules for SPFx, so not something I would be able to trivially change ... so, back to the SPFx side to look for more options to resolve.

I'm also having this issue. In my case, react-datepicker depends on react-popper.

Is this issue being looked into? or has anyone found a work-around?

Sadly, no workaround found yet ... hopefully either @waldekmastykarz or @patmill might be able to confirm whether there's anything that can be done to work around or resolve this. From the issue I had opened with the react-popper project, it seems to be an issue in the webpack configuration, so definitely needs something changed on the SPFx side.

So, I've tried updating my gulpfile.js file to:

~~~ js
'use strict';

const gulp = require('gulp');
const build = require('@microsoft/sp-build-web');
build.addSuppression(Warning - [sass] The local CSS class 'ms-Grid' is not camelCase and will not be type-safe.);

build.configureWebpack.mergeConfig({
additionalConfiguration: (generatedConfiguration) =>
{
generatedConfiguration.externals.splice(generatedConfiguration.externals.indexOf('react'), 1);
generatedConfiguration.externals.splice(generatedConfiguration.externals.indexOf('react-dom'), 1);
generatedConfiguration.resolve.modules.splice(generatedConfiguration.resolve.modules.indexOf('.'), 1);
return generatedConfiguration;
}
});

build.initialize(gulp);
~~~

Note the extra line removing '.' from the Resolver Modules array when compared to @waldekmastykarz version above.

This suppresses the react-popper warnings in the webpack steps, but causes lots of other problems for me - notably that I still cannot use a combination of reactstrap and fontawesome.

I've also tried making reactstrap an external in config.json which also doesn't work because after doing this, reactstrap can't load because it can't load its dependency on react, which has had to be removed as an external to allow use of React 16.

Ultimately, I think this is now a case of good old 'dependency hell' - many packages that use react-popper need '.' in the webpack configuration (likely including SPFx itself), but react-popper causes major errors if '.' is not removed from the webpack configuration.

So I asked the react-popper guys to re-open Issue 111 on their side, and was told:

"I find it so difficult to think that you are the only one having this problem honestly... If enough people report this we can think about a solution. Until then, I'm convinced the problem is on your side."

Not really helpful, as it still doesn't resolve the underlying issue of not being able to use any package which depends on react-popper when using the SharePoint Framework. I'd strongly suggest that if you continue to have issues and there's nothing the SPFx guys can do that you report a brand new issue to the react-popper team, as it seems they'll only consider spending time to carry out the trivial fix (i.e. renaming their Popper.js file) if enough people complain about this fault.

I haven't had the time to explore this issue in-depth as I was able to remove my dependency on react-datetime.
There must be some reproducible minimal package configuration which triggers this issue using a dependency on something that uses react-popper, such as reactstrap or react-datetime. From there maybe they will have a look?

Hey guys, this thing is intriguing me. (Popper.js and react-popper maintainer here)

The webpack configuration used by this "sharepoint" thing is telling webpack to treat imports (like import PopperJS from 'popper.js') as relative imports from the directory where the importing file is located?

Does it mean that import Popper from './popper' is going to be confused with import PopperJS from 'popper.js'?

@pedro-pedrosa: I don't have the time to go and pick up all the additional skills needed to do that - and nor should I have to. The only reason that I'm using npm, webpack or any of these things is so that I can use the SharePoint Framework.

I'm at the point where I'm considering whether SPFx and SharePoint is even the right platform, because I simply don't have time to play piggy-in-the-middle between Microsoft (who aren't responding to this issue any more) and some tin-pot two-bit project at the absolute bottom of the dependency tree can't see that they're wasting many hours of developer time - both paid and unpaid - because they can't rename one file in their project.

As I've said in the react-popper issue ... I'm just a consumer, of SPFx, React, Reactstrap, react-popper and other packages - it shouldn't be my issue and waste my time if one of the packages at the bottom of the dependency tree, that I don't even _want_ to be using in the first place, can't fix their bugs.

@PurpleGranite While I do share your pain (I work professionally with sharepoint and this issue actually made me look bad before my employers because of unmet estimates) I also believe that most of all we are benefiting from the open source community, not wasting time with it. In my case I had to quickly fix my issue so I just removed the package that depended on react popper.
That said, if you really need reactstrap with sharepoint, you can either investigate where exactly the issue lies and raise that with the team reaponsible for it or you can rethink your dependencies. I know this takes time and is not the most enjoyable thing to do (and if this isn't fixed soon I may find myself in the same position as you in the future) but really if you're using third party packages it's because it's saving you time, not wasting.
@FezVrasta while it may be true that this only happens with the SPFx framework it's also true that react-popper is also the only package among hundreds which is having issues with this configuration, so that says something about where the issue may lie.

@pedro-pedrosa if what I said is what actually happening that's worrying, it's a very unconventional configuration and I can't see the benefit of such decision actually.

The problem here is not react-popper, but the fact that this project doesn't properly supports packages like popper.js that end with .js in their name.

I suspect that if in your own code you create a file called popper.js and import it you are going to get the same warning/error right?
The same is valid for any other package that ends with .js I guess.

I'd like to get an answer on this from one of the guys that work on this project if possible. Unfortunately I don't think I'll be able to verify my thesis without a subscription to SharePoint right?

You don't need to deploy your package to see this issue in action. You can follow this guide here https://docs.microsoft.com/en-us/sharepoint/dev/spfx/set-up-your-development-environment to set up your environment and this one here https://docs.microsoft.com/en-us/sharepoint/dev/spfx/web-parts/get-started/build-a-hello-world-web-part to create your first project

Basically you install yeoman, install the sharepoint generator, and create a simple project using the sharepoint yeoman generator and choosing the react framework.

Then you can add your dependencies and run gulp bundle

Ok I could reproduce it, it's definitely a problem with the webpack configuration.

The guys of Microsoft should fix it.

I have ran into this issue again so I had to figure out a work around.

I had to manually go in the node_modules folder and rename the popper.js package to popperjs and then update the reference in Popper.js (from the react-popper module). This fixed the issue for me.

Any Update on react16 official upgrade from Microsoft however?

SPFx v1.7.1 rev'd to React16, so the issue seems moot now?

But SPFx v1.7 is not working on SharePoint online

@hafeez1042 what do you mean it's not working? SPO is running SPFx v1.7.1, the latest version, which included the update for React v16 & started rolled out last year: https://developer.microsoft.com/en-us/office/blogs/verification-guidance-sharepoint-online-moves-to-react-16

You're seeing something different?

@andrewconnell I had tried SPFx v 1.7.0 when its was released and its wasn't working with SPO at that time, But current v1.7.1 is working without any issue.

This issue has been automatically marked as stale because it has marked as requiring author feedback but has not had any activity for 7 days. It will be closed if no further activity occurs within next 7 days of this comment. Thank you for your contributions to SharePoint Developer activities.

Closing issue due no response from original author. If this issue is still occurring, please open a new issue with additional details. Notice that if you have included another related issue as additional comment on this, please open that also as separate issue, so that we can track it independently.

Issues that have been closed & had no follow-up activity for at least 7 days are automatically locked. Please refer to our wiki for more details, including how to remediate this action if you feel this was done prematurely or in error: Issue List: Our approach to locked issues

Was this page helpful?
0 / 5 - 0 ratings