Tooling: Python2 error in SASS building frontend

Written on September 16, 2022

Category: Tooling

Author: David Rodríguez, @davidjguru

Picture from Unsplash, by @markuswinkler
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:

Getting python2 error in a frontend buil up
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):

  1. Connect to your selected docker container and move to your theme folder:
    $ fin bash
    docker@cli:/var/www$ cd docroot/themes/custom/
    
  2. 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
    
  3. 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
    
  4. 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
    
  5. 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-pathin 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",
  1. Pay attention in your code cause you can get some warnings after switching to dart-sass. For instance, after switching from node-sass to dart-sass, there are some deprecated expressions that may cause you receive some warning messages. See:
Getting some warnings from dart-sass deprecated code
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

:wq!


Written on September 16, 2022