react-spring: @react-spring/core or @react-spring/three production errors

🐛 Bug Report

Hi, i’m using these to animate R3F components, but I do not run into this in development. The issue only occurs in production:

Uncaught TypeError: r.willAdvance is not a function
    at 9cfe2b4608e7231bacc0d7d7deffe07ef300d220.20fefe92f1d342a18960.js:1
    at Module.d (9cfe2b4608e7231bacc0d7d7deffe07ef300d220.20fefe92f1d342a18960.js:1)
    at a.b.advance (9cfe2b4608e7231bacc0d7d7deffe07ef300d220.20fefe92f1d342a18960.js:1)
    at 9cfe2b4608e7231bacc0d7d7deffe07ef300d220.20fefe92f1d342a18960.js:1
    at 28ddf37e733bed61e8c6ac53a0464422aa01203b.0544bc5f695fe9930e09.js:1
    at Array.forEach (<anonymous>)
    at xe (28ddf37e733bed61e8c6ac53a0464422aa01203b.0544bc5f695fe9930e09.js:1)

To Reproduce:

Here is the code example i’m trying to run, and again, I want to stress this only happens in production

import React, { useRef } from 'react';
import { Canvas, useFrame } from 'react-three-fiber';
import { useSpring } from '@react-spring/core';
import { a } from '@react-spring/three';
import styled from '@emotion/styled';

const endless = true;

const Cube = () => {
  const m: any = useRef();
  useFrame(() => {
    m.current.rotation.y += 0.01;
  });

  const { scale, color } = useSpring({
    from: { scale: [1, 1, 1], color: '#17bebb' },
    to: async next => {
      while (endless) {
        await next({ scale: [4, 4, 4], color: '#FAD8D6' });
        await next({ scale: [1, 1, 1], color: '#17bebb' });
        await next({ scale: [3, 3, 3], color: '#CD5334' });
        await next({ scale: [2, 2, 2], color: '#EDB88B' });
        await next({ scale: [1, 1, 1], color: '##17bebb' });
      }
    }
  });

  return (
    <a.mesh ref={m} scale={scale}>
      <boxBufferGeometry attach="geometry" args={[1, 1, 1]} />
      <a.meshStandardMaterial attach="material" color={color} />
    </a.mesh>
  );
};

const AnimatingWithReactSpring = () => {
  return (
    <Container>
      <Canvas>
        <ambientLight position={[1, 1, 1]} />
        <Cube />
      </Canvas>
    </Container>
  );
};

const Container = styled.div`
  border: 1px solid #ccc;
  border-radius: 5px;
`;

Expected behavior

I expect it to run well, just like it does in development

Environment

About this issue

  • Original URL
  • State: closed
  • Created 4 years ago
  • Reactions: 59
  • Comments: 93 (9 by maintainers)

Commits related to this issue

Most upvoted comments

Okay so, I tried many of the fixes here, but none of them work. patch-package looked really promising, but trying to run it after making the changes returns:

$ npx patch-package
patch-package 6.2.2
Applying patches...

**ERROR** Failed to apply patch for package @react-spring/animated at path
  
    node_modules/@react-spring/animated

  This error was caused because patch-package cannot apply the following patch file:

    patches/@react-spring+animated+9.0.0-rc.3.patch

  Try removing node_modules and trying again. If that doesn't work, maybe there was
  an accidental change made to the patch file? Try recreating it by manually
  editing the appropriate files and running:
  
    patch-package @react-spring/animated
  
  If that doesn't work, then it's a bug in patch-package, so please submit a bug
  report. Thanks!

    https://github.com/ds300/patch-package/issues

Has anyone actually been able to fix this? Is there a development branch that we can use in the meantime?

EDIT:

So I tried a bunch of different stuff until I noticed that the patch files create by patch-package had a bunch of stuff in them that hadn’t been changed and I didn’t need to be changed, this prompted me to try to remove everything and keep the bare minimum so that my files looked something like this:

diff --git a/node_modules/@react-spring/animated/package.json b/node_modules/@react-spring/animated/package.json
index 4ef7565..f58f540 100644
--- a/node_modules/@react-spring/animated/package.json
+++ b/node_modules/@react-spring/animated/package.json
@@ -65,7 +74,6 @@
     "access": "public"
   },
   "react-native": "src/index.ts",
-  "sideEffects": false,
   "types": "index.d.ts",
   "version": "9.0.0-rc.3"
 }

I then tried installing again and it worked!

So here’s an actual guide on fixing this:

  • Go to node_modules/@react_spring (not node_modules/react_spring)
  • Edit each package.json in the included folders (animated, core, native, shared, three, web, zdog)
  • run npx patch-package --exclude 'nothing' @react-spring/<folder>, where <folder> is one of animated, core, native, shared, three, web, zdog each
  • This should create files inside patches/
  • Go into each file and delete everything apart from the bit that mentions "sideEffects": false (so that it looks like the example above)
  • add "postinstall": "patch-package" to your scripts in package.json
  • hopefully react-spring should be automatically patched when running npm install

Here’s hoping we get a new RC soon!

In case it helps anyone else, I wanted as light-touch a solution as possible since (hopefully 🙏 ) we’ll get an rc4 soon. Personally I’m using unejected CRA 4, but this should be generic.

Add a script to your root package.json, and run it on postinstall:

  "scripts": {
    "react-spring-issue-1078": "find node_modules -path \\*@react-spring/\\*/package.json -exec sed -i.bak 's/\"sideEffects\": false/\"sideEffects\": true/g' {} +",
    "postinstall": "npm run react-spring-issue-1078",
   }

(NB: Won’t generally work on windows for obvious reasons, but should be mac and linux compatible)

The issue was that "sideEffects": false was being used when it shouldn’t be, causing Globals.assign calls to be tree-shaked. Will be fixed in next RC. 👍

For the record, even with the potential simplicity of using patch-package, this effort is vastly more complex for projects than simply publishing an 9.0.0-rc.4 with this fix.

patch-package (and a like strategy) suffers from some fragile build context problems. It is easy to enact this, have it work locally, and fail on a remote build system.

Such is the case for my project and building on heroku. Their devDependency phase of build applies this patch correctly, only to reinstall the package again after pruning devDependencies, and this time patch-package fails due to slightly different working directory context.

While this sort of issue isn’t really the fault of react-spring, it could be totally avoidable (this whole work-around would be as well) with such a low effort action by the maintainer. Please, please with a cherry-on-top, npm publish 9.0.0-rc.4 with this trivial build fix.

If main branch is in a bad state, you could cut a hotfix branch off tag https://github.com/pmndrs/react-spring/releases/tag/v9.0.0-rc.3, apply fix, bump to v9.0.0-rc.4, and npm publish This would be so helpful. 🥺

For people who’s using react-spring along with webpack, here’s a workaround I believe you can use in webpack.config.js before a new react-spring is out with the fix:

  module: {
    rules: [
      {
        test: /react-spring/,
        sideEffects: true
      },

@enkicoma I was able to adapt @chenxsan’s solution to work with Next 10.0.3 by adding a webpack config function to my next.config.js file:

module.exports = {
  ...
  webpack: config => {
    config.module.rules.push({
      test: /react-spring/,
      sideEffects: true,
    })

    return config
  },
}

This fixed the TypeError: r.willAdvance is not a function error on my production build.

@CharlieHess @Emiliano-Bucci I ended up adding scpipt below in package.json postinstall hook. ("postinstall": "node postinstall.js", + "replace-in-file in devDependencies)

const replace = require('replace-in-file');

const removeAllSideEffectsFalseFromReactSpringPackages = async () => {
  try {
    const results = await replace({
      files: "node_modules/@react-spring/*/package.json",
      from: `"sideEffects": false`,
      to: `"sideEffects": true`
    });

  // console.log(results); // uncomment to log changed files
  } catch (e) {
    console.log('error while trying to remove string "sideEffects:false" from react-spring packages', e);
  }

}


removeAllSideEffectsFalseFromReactSpringPackages();

Could this not be released as a patch ? I think a lot of people are using the rc3 because it has been said that it’s more stable than 8.x, and since rc4 seems quite distant it might be a good idea to get really breaking things like this onto npm.

I can confirm that using NextJS with webpack > ^4.44.x is broken by this, in the mean time you can force webpack to ~4.43.x with resolutions in your package.json:

  "resolutions": {
    "webpack": "~4.43.0"
  },

@CharlieHess @Emiliano-Bucci I ended up adding scpipt below in package.json postinstall hook. ("postinstall": "node postinstall.js", + "replace-in-file in devDependencies)

const replace = require('replace-in-file');

const removeAllSideEffectsFalseFromReactSpringPackages = async () => {
  try {
    const results = await replace({
      files: "node_modules/@react-spring/*/package.json",
      from: `"sideEffects": false`,
      to: `"sideEffects": true`
    });

  // console.log(results); // uncomment to log changed files
  } catch (e) {
    console.log('error while trying to remove string "sideEffects:false" from react-spring packages', e);
  }

}


removeAllSideEffectsFalseFromReactSpringPackages();

Thank you, you saved my day!!

I added theses script in package.json and it worked.

"scripts": {
    "dev": "node postinstall.js && next dev",
    "build": "node postinstall.js && next build",
    "start": "next start",
},
"dependencies": {
    "react-spring": "9.0.0-rc.3",
},
"devDependencies": {
    "replace-in-file": "^6.1.0"
},

Hope this issuse would be fixed in next version!

had the exact same error in production build only and using @iam4x solution helped me.

// in package.json

"resolutions": {
  "webpack": "~4.43.0"
},

I’m hitting this in a similar environment (Next + r3f + react-spring) and none of the workarounds listed here work.

patch-package to remove sideEffects for all spring packages ⛔ webpack@4.4.3next@9.4.5-canary.43

It looks like:

module.exports = {
  webpack: (config) => {
    config.module.rules.push({
      test: /react-spring/,
      sideEffects: true,
    });
    return config;
  },
};```

I just had the same bug after bootstrapping a new create-react-app. Downgrading react 17.0.1 and react-scripts 4.0.0 back to 16.13.1 and 3.4.1 also works.

I can confirm that upgrading from NextJS 9.4.5-canary.45 to 9.5.0 produces the same error for me as well.

This works for me with Next 10 and next-images, variation on the above:

const withImages = require("next-images");

module.exports = withImages({
  webpack: (config) => {
    config.module.rules.push({
      test: /react-spring/,
      sideEffects: true,
    });
    return config;
  },
});
config.module.rules.push({
      test: /react-spring/,
      sideEffects: true,
    })

Confirm that this solution works, nice approach, the code looks much cleaner now 👍

@ivnaleta Try adding --exclude at the end of the command, it should work. Example: npx patch-package react-spring --exclude

I’m not using Gatsby. I’ve come across this using Nextjs

@enkicoma I was able to adapt @chenxsan’s solution to work with Next 10.0.3 by adding a webpack config function to my next.config.js file:

module.exports = {
  ...
  webpack: config => {
    config.module.rules.push({
      test: /react-spring/,
      sideEffects: true,
    })

    return config
  },
}

This fixed the TypeError: r.willAdvance is not a function error on my production build.

Confirm - it works! I asked for some help on discord and combined 3 things together with your one and finally: next.config.js

const withTM = require('next-transpile-modules')
  ([
    '@react-three/drei',
    'three',
    '@react-spring/web',
    'react-three-fiber'
  ])

module.exports = withTM({
  webpack: config => {
    config.module.rules.push({
      test: /react-spring/,
      sideEffects: true,
    })

    return config
  },
})

Thank you for your help and Happy New year!

@jdillick Made a PR #1229 which should make this easy.

@ivnaleta You could manually remove "sideEffects": false from the package.json of every node_modules/@react-spring/* directory, then use patch-package to auto-apply those changes when node_modules is re-installed.

Otherwise, if you still want to build v9 locally, you can follow the Contributing Guide and let me know if something trips you up. 👍

I also get this when bundling with webpack@5.0.0-beta.22. I didn’t have enough time to dig further in to the issue and reverted to webpack@4.43.0 which works fine, but it seems to be around how webpack was importing modules.

Is there a way to modify this webpack in create-react-app without ejecting?

Have a look at @craco/craco.

Thanks, got it working! If anyone is using craco this craco.config.js works:

module.exports = {
  webpack: {
    configure: {
      module: {
        rules: [
          {
            test: /react-spring/,
            sideEffects: true
          }
        ]
      }
    }
  }
};

In case it helps anyone else, I wanted as light-touch a solution as possible since (hopefully 🙏 ) we’ll get an rc4 soon. Personally I’m using unejected CRA 4, but this should be generic.

Add a script to your root package.json, and run it on postinstall:

  "scripts": {
    "react-spring-issue-1078": "find node_modules -path \\*@react-spring/\\*/package.json -exec sed -i.bak 's/\"sideEffects\": false/\"sideEffects\": true/g' {} +",
    "postinstall": "npm run react-spring-issue-1078",
   }

(NB: Won’t generally work on windows for obvious reasons, but should be mac and linux compatible)

And for the Windows platform, this is the PowerShell script to do the same thing.

$reactSpringPackageJSONs = Get-ChildItem -Path node_modules\\*@react-spring/\\*/package.json

foreach ($reactSpringPackageJSON in $reactSpringPackageJSONs) {
  (Get-Content $reactSpringPackageJSON) |
    Foreach-object { $_ -replace '"sideEffects": false', '"sideEffects": true' } |
    Set-Content $reactSpringPackageJSON
}

@heyimalex small typo in your comment. second L1 in the second command is missing a hyphen

Commands to do @creativiii 's method mentioned here apart from setting up patch-package.

find ./node_modules/@react-spring -type f -depth 2 -name package.json -exec sed -i '' '/"sideEffects": false/d' {} +
find ./node_modules/@react-spring -type d -depth 1 | xargs -L1 -I{} basename "{}" | xargs -L1 -I{} npx patch-package --exclude 'nothing' "@react-spring/{}"

Commands to do @creativiii 's method mentioned here apart from setting up patch-package.

find ./node_modules/@react-spring -type f -depth 2 -name package.json -exec sed -i '' '/"sideEffects": false/d' {} +
find ./node_modules/@react-spring -type d -depth 1 | xargs -L1 -I{} basename "{}" | xargs -L1 -I{} npx patch-package --exclude 'nothing' "@react-spring/{}"

In case it helps anyone else, I wanted as light-touch a solution as possible since (hopefully 🙏 ) we’ll get an rc4 soon. Personally I’m using unejected CRA 4, but this should be generic.

Add a script to your root package.json, and run it on postinstall:

  "scripts": {
    "react-spring-issue-1078": "find node_modules -path \\*@react-spring/\\*/package.json -exec sed -i.bak 's/\"sideEffects\": false/\"sideEffects\": true/g' {} +",
    "postinstall": "npm run react-spring-issue-1078",
   }

(NB: Won’t generally work on windows for obvious reasons, but should be mac and linux compatible)

Confirms that this works for those using CRA. many thanks

I faced this issue on Gatsby v2.24.91 two hours before go live time, ugh.

Thanks @creativiii, confirmed these steps worked for me.

Seeing the same with preact & create-react-app.

@aleclarson Is there a way to use patch-package? Because it seems that it doesn’t patch the changes that are only applied to the package.json 😕

I’m not opposed to waiting for a fix in the next version, any idea of when that might be?

The entirety of the code is in that snippet. You need to run it in with an application set to production mode. Also it seems like this is not the first time it has occured as a similar production issue mentioned here #1069

I think I’ve provided enough information. If you want to chase it down feel free, if not thats fine too. @aleclarson

@joshuaellis Hi! I’ve update react-spring to the latest version but still I’m getting this issue (of course I can fix it with the previous workaround), but just wanted to understand if this fix goes up in the version 9 or not 😃

Hello guys this issue reproduced with the verisons of "react-spring": "^8.0.27" "next": "^10.0.7" and I’m using the react-spring parallax module "@react-spring/parallax": "^9.0.0-rc.3"

I’ve tried all of the approaches and the error still reproducing with the app in production(Github pages).

Does anyone know how to avoid this error?

Scroll up!!! A contributor has already explained what’s the cause and there are literally a bunch of workarounds available.

@CharlieHess @Emiliano-Bucci I ended up adding scpipt below in package.json postinstall hook. ("postinstall": "node postinstall.js", + "replace-in-file in devDependencies)

const replace = require('replace-in-file');

const removeAllSideEffectsFalseFromReactSpringPackages = async () => {
  try {
    const results = await replace({
      files: "node_modules/@react-spring/*/package.json",
      from: `"sideEffects": false`,
      to: `"sideEffects": true`
    });

  // console.log(results); // uncomment to log changed files
  } catch (e) {
    console.log('error while trying to remove string "sideEffects:false" from react-spring packages', e);
  }

}


removeAllSideEffectsFalseFromReactSpringPackages();

Great stuff! Worked! 🎉

@enkicoma You’ll need to create a next.config.js file as described here: https://nextjs.org/docs/api-reference/next.config.js/custom-webpack-config

For people who’s using react-spring along with webpack, here’s a workaround I believe you can use in webpack.config.js before a new react-spring is out with the fix:

  module: {
    rules: [
      {
        test: /react-spring/,
        sideEffects: true
      },

Thanks @chenxsan - that worked for me!

Thank you, @creativiii. Those steps worked perfectly. It’s possible patch-package has been updated as I didn’t have to do this step:

  • Go into each file and delete everything apart from the bit that mentions “sideEffects”: false (so that it looks like the example above)

Thanks again for the detailed steps. We really appreciate it.

Confirming that removing "sideEffects": false from package.json fixed the issue for me. Thanks for the suggestion @aleclarson!

The issue was that "sideEffects": false was being used when it shouldn’t be, causing Globals.assign calls to be tree-shaked. Will be fixed in next RC. 👍

Thanks for isolating this @aleclarson. Is there any timeline on the next RC?

That’s good to know! 😆

Can you share your next.config.js?

Please provide a git repository that reproduces the issue. Thanks 👍