In that case, there are various possible solutions.
The first is to use a naming rule such as characterA/eyes_Happy
and characterB/eyes_Happy
, so that while the characterA skin is applied, the combination of "characterA/" + "expression name" is used to change the facial expression of the character at runtime. (Just in case you didn't know, it is possible to apply multiple skins to a skeleton at the same time: Skins view - Spine User Guide)
Unfortunately, the Spine editor does not have that feature such as Skin sets so you can not switch between multiple skins at once, but it should be possible at runtime if the naming conventions are well defined.
The second is to use skins only for switching between characters’ appearance, and create animations for each facial expression. For example, creating a “blink” animation for each of Normal, Happy, and Sad expressions and play them back in the game as needed. This solution would be good if the number of facial expression animations were not so large.
The third is to use skins for switching facial expressions, and switch characters by making the texture size uniform for all characters and replacing the textures depending on what you want to display at runtime.
In the Spine editor, you can switch the skeleton's appearance by changing the image path in the Images node if the images for each character are placed into each character folder.
This takes a lot of time to first determine the standard texture size, but if you have a large number of facial expression parts and switching facial expression animations may be difficult, this may be a better option. If your characters are overall complex with a large number of attachments, I do not recommend this approach.
There was a similar question in the past, so the following post may be helpful:
Question about skins and animation export