Tooling: Python2 error in SASS building frontend
Written on September 16, 2022
Category: Tooling
Author: David Rodríguez, @davidjguru
Picture from Unsplash, user Markus Winkler, @markuswinkler |
Now in my current context I’m working on a multisite Drupal installation with several internal sites (more than a hundred sites) and among other experiences, I’m facing new issues that I had not experienced before. This little post is about that: a very specific error that can be common and how to solve it.
Well, now I’m working in a different stack from what I’m used to: I’m using Docksal, a software virtualization tool for containers and Acquia BLT (or Acquia Build and Launch Tool), a resource for automatization of tasks, deploys and testing. The combination of both allows to build Docker container networks in your local environment and to have pre-configured different tasks for the daily management of Drupal-based websites.
I recommend you to try them, although for containers I prefer DDEV -that’s true- but I think that experiencing a containerization tool (Docksal, DDEV, Docker4Drupal, Gitpod…) and a maintenance and development task management tool (Acquia BLT, Robo / Drobo, Deployer is a MUST for any Drupal developer.
Acknowledgments
This post was composed from my current position as Senior Drupal Developer at FFW Agency, one of the biggest companies oriented to Open Source in the world and specifically focused in Drupal.
The Issue
When I want to build up the frontend of a site, I execute a combined Docksal + BLT instruction, something like using the classical @alias/naming of a site:
fin blt frontend --site=one.of.my.sites.com
At some point, I’m getting this error message:
error /var/www/docroot/themes/custom/xxx_yyy_base_theme/node_modules/node-sass: Command failed.
And then in the same trace:
gyp verb check python checking for Python executable "python2" in the PATH
gyp verb `which` failed Error: not found: python2
And then the process is stopped and it is not possible to build the frontend of the required site… You can see the complete trace in the next screenshot:
Python2 error while we’re building up the frontend |
So what I do is first of all, check the version numbers of each element involved in the Issue, using command line for the first items and then reviewing package.json
file and getting some versions, or by using yarn
with subcommands just like:
$ yarn list --pattern "node-sass"
And so I get all the values I am interested in, since I will have to google the status of each one, looking for issues, known bugs or deprecated code ;-) :
node -v: v16.16.0
npm -v: 8.11.0
node-sass: 4.14.1
node-gyp: 3.8.0
Fixin’
Ok, let’s try to get a good understanding of what is happening throughout this process since we execute the frontend startup commands. As I said, when I’m running my current configuration in CLI, mixin’ docksal commands + Acquia tooling, I’m trying to run the build up for theming by usings something like this:
$ fin blt frontend --site=one.of.my.sites.com
Essentially I’m launching related scripting, diverse stuff as setup.sh
or build.sh
. And within these scripts (normally) you’re only running basic yarn specific and custom sub-commands, just like: yarn run build:sass
. Ok, and what does it means? traveling to every package.json
file, you can see the common scripts block:
"scripts": {
...
"clean": "rm -rf node_modules pattern-lab",
"build:sass": "node-sass src/_patterns -o src/_patterns --include-path breakpoint-sass/stylesheets",
...
},
So finally, when you (or your scripts) launch yarn run build:sass
finally you’re using the command:
node-sass src/_patterns -o src/_patterns --include-path ./node_modules/breakpoint-sass/stylesheets
Just in order to transpiling the CSS files in theming from SCSS syntax to processed CSS, marking source, the destiny folder (-o /folder/
) and other resources to integrate in the process (--include-path
) as usual.
Ok, What’s the problem? Well, the first key here: node-sass
. I’ve discovered the dependency is marked as deprecated from more than two years ago (nothing interesting from my side, just the magic of the hyperlink and a little of Google)… It causes problems and errors because nodejs compatibility with the current version of node-sass
installed. You can see the current status of node-sass
here or in tickets from some Drupal distributions like Varbase. This issue has been detected by me at least in a pair of themes of my current multisite structure, think about theme_one and theme_two. So, we’ll need a new resource instead the deprecated node-sass
. Ok, but, what’s the solution?
You can use dart-sass instead. The movement requires changes at some levels, just like those (follow the next steps):
- Connect to your selected docker container and move to your theme folder:
$ fin bash docker@cli:/var/www$ cd docroot/themes/custom/
- Remove deprecated dependencies using yarn and delete
node-sass
from requirements.docker@cli:/var/www/docroot/themes/custom/theme_one$ yarn remove node-sass docker@cli:/var/www/docroot/themes/custom/theme_two$ yarn remove node-sass
- Install new dependencies.
docker@cli:/var/www/docroot/themes/custom/theme_one$ yarn add --dev sass sass-loader docker@cli:/var/www/docroot/themes/custom/theme_two$ yarn add --dev sass sass-loader
- Remove
node_modules
folder in every theme directory and regenerate it using the new dependencies (dart-sass as just “sass” resource).docker@cli:/var/www/docroot/themes/custom/theme_one$ rm -rf node_modules docker@cli:/var/www/docroot/themes/custom/theme_one$ yarn install
- Review and execute small adjustments and changes in commands, sub-commands and flags or params used from internal scripts (e.g build.sh or setup.sh in some themes but executing scripting orders compiled in package.json files from every theme). So we have to ensure that after the executed changes, the commands are modified also in order to execute the same steps when building frontend.
For instance, while in node-sass
you had flags like -o
in order to set the output folder, now you don’t need the item in dart-sass
. Or param --include-path
is changed to --load-path
in the new library.
So in your scripting block you had:
"build:sass": "node-sass src/_patterns -o src/_patterns --include-path ./node_modules/breakpoint-sass/stylesheets",
"build:pl-sass": "node-sass --importer node_modules/node-sass-glob-importer/dist/cli.js src/sass/ -o src/css --include-path ./node_modules/breakpoint-sass/stylesheets",
And now we have:
"build:sass": "sass src/_patterns:src/_patterns --load-path ./node_modules/breakpoint-sass/stylesheets",
"build:pl-sass": "sass --importer node_modules/node-sass-glob-importer/dist/cli.js src/sass/ src/css --load-path ./node_modules/breakpoint-sass/stylesheets",
- Pay attention in your code cause you can get some warnings after switching to
dart-sass
. For instance, after switching fromnode-sass
todart-sass
, there are some deprecated expressions that may cause you receive some warning messages. See:
Deprecations warnings from dart-sass |
Before:
span {
box-sizing: border-box;
max-width: 40px;
padding: $space / 2;
After:
span {
box-sizing: border-box;
max-width: 40px;
padding: math.div($space, 2);
Once you have these adjustments made to your .scss files, you are ready to have a completely clean and updated frontend startup. That’s it.
Warning
It was only repaired in some themes of a large set of themes and subthemes in a multisite installation… I mean, if it is your scenario, may be necessary to make similar changes to other existing themes which, at this stage, you have not yet tested. Think that if your internal multisite structure looks like the one I’m using now, then each theme / subtheme has its own build up process, with its own resources and dependencies (package.json, yarn.lock, assets, etc.).
Read More
- npmjs: node-sass
- github: node-sass related issue
- sass-lang: libsass is deprecated
- stackoverflow: node-sass deprecated
- dev.to: migrating from node-sass to dart-sass
- stackoverflow: switching node-sass to dart-sass