In one of my hobby projects I am using a library that has a dependency on an old version of node-gyp
(8.4.1) which in turn has a dependency on distutils
. This project is hosted on Vercel and when deploying, the build fails during the npm install
step with this error:
npm error ModuleNotFoundError: No module named 'distutils'
What is distutils??
distutils
is a python package (see here: https://docs.python.org/3.10/library/distutils.html). It is used by old versions of node-gyp
for version parsing. The issue is that, disutils
is not supported anymore starting from python3.12 and Vercel’s build system uses python3.12.2 (at the time of writing this post).
As stated in the distutils
docs:
distutils is deprecated with removal planned for Python 3.12.
So how can we fix the issue?
There are two ways this issue can be fixed.
Option 1: Update the offending package to use node-gyp
>- v10.
As stated in the node-gyp
ReadMe on GitHub:
Python >= v3.12 requires
node-gyp
>= v10
This option is only viable if you have direct access to the offending package (usually rare). Alternatively, you could issue a pull request updating the node-gyp
dependency and hope that it gets merged. If none of these approaches are possible, as it was in my case, then go for option 2
Option 2: Install the setuptools
python package during the Vercel build.
As stated in the python3.12 release notes:
For projects still using
distutils
and cannot be updated to something else, thesetuptools
project can be installed: it still providesdistutils
.
To do this, we need to override the Install command during the build. To do this navigate to the Build and Deployment settings for your Vercel project and under Framework Settings change the Install Command to this:
python3 -m pip install setuptools && npm install
Note: This assumes you are using npm for your package manager, if you are using yarn or pnpm or something else, just change the npm install command to the correct one for your package manager.
Thats it, now when the build runs, setuptools
will get installed prior to the package installation command being run.