Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to fix Some token references (2) could not be found. #1458

Open
codebysandeep opened this issue Feb 25, 2025 · 2 comments
Open

How to fix Some token references (2) could not be found. #1458

codebysandeep opened this issue Feb 25, 2025 · 2 comments
Labels

Comments

@codebysandeep
Copy link

Problem

When building Style Dictionary tokens for multiple brands, and themes the build process fails with a reference error:

Reference Errors:
Some token references (2) could not be found.

stackblitz link

amazon-style-dictionary-v1

The issue occurs when custom themes try to reference brand-specific tokens.

Steps to Reproduce

  1. Create brand-specific tokens in style-dictionary/tokens/brand-a/base.json and style-dictionary/tokens/brand-b/base.json
  2. Create custom themes in customThemes/a/theme-a.json and customThemes/a/theme-b.json that reference the brand tokens
  3. Run the build script with npm run build

Expected Behavior

Style Dictionary should resolve all token references and successfully complete the build process.

Actual Behavior

Build fails with reference errors. Two token references cannot be found.

Relevant Code

Issue appears to be in the token references:

In customThemes/a/theme-a.json:

"primaryDivider": {
  "$value": "{brand-a.brand-a/palette/light/divider}"
}

In customThemes/a/theme-b.json:

"primaryDivider": {
  "$value": "{brand-b.brand-b/palette/light/divider}"
}

Possible Causes

  1. The namespacing in the token references might be incorrect
  2. The build process may not be correctly importing tokens across files
  3. Style Dictionary might be creating separate instances per brand that don't share token definitions

style-dictionary/tokens/brand-a/base.json

{
  "brand-a": {
    "$type": "brand-a",
    "brand-a/palette/light/divider": {
      "$value": "00",
      "type": "px",
      "collection": "brand-a",
      "attributes": {
        "category": "brand-a",
        "group": "brand-a",
        "scopes": []
      }
    }
  }
}

style-dictionary/tokens/brand-b/base.json

{
  "brand-b": {
    "$type": "brand-b",
    "brand-b/palette/light/divider": {
      "$value": "11",
      "type": "px",
      "collection": "brand-b",
      "attributes": {
        "category": "brand-b",
        "group": "brand-b",
        "scopes": []
      }
    }
  }
}

customThemes/a/theme-a.json

{
  "themeA": {
    "primaryDivider": {
      "$value": "{brand-a.brand-a/palette/light/divider}",
      "type": "themeA",
      "attributes": {
        "category": "themeA",
        "group": "themeA",
        "scopes": []
      }
    }
  }
}

customThemes/a/theme-b.json

{
  "themeB": {
    "primaryDivider": {
      "$value": "{brand-b.brand-b/palette/light/divider}",
      "type": "themeB",
      "attributes": {
        "category": "themeB",
        "group": "themeB",
        "scopes": []
      }
    }
  }
}

build.js

import StyleDictionary from 'style-dictionary';
import { formats, transformGroups } from 'style-dictionary/enums';

const { scssVariables, cssVariables } = formats;
const { web, css } = transformGroups;

// HAVE THE STYLE DICTIONARY CONFIG DYNAMICALLY GENERATED
function getStyleDictionaryConfig(brand, platform) {
  return {
    source: [
      `style-dictionary/tokens/${brand}/**/*.json`,
      `customThemes/**/*.json`,
    ],
    platforms: {
      web: {
        transformGroup: web,
        buildPath: `build/web/${brand}/`,
        files: [
          {
            destination: 'tokens.scss',
            format: scssVariables,
          },
        ],
      },
      css: {
        transformGroup: css,
        buildPath: `build/customThemes/css`,
        files: [
          {
            destination: 'tokens.css',
            format: cssVariables,
          },
        ],
      },
    },
  };
}

console.log('Build started...');

// PROCESS THE DESIGN TOKENS FOR THE DIFFEREN BRANDS AND PLATFORMS

['brand-a', 'brand-b'].map(function (brand) {
  ['web', 'css'].map(function (platform) {
    console.log('\n==============================================');
    console.log(`\nProcessing: [${platform}] [${brand}]`);

    const sd = new StyleDictionary(getStyleDictionaryConfig(brand, platform));
    sd.buildPlatform(platform);
  });
});

console.log('\n==============================================');
console.log('\nBuild completed!');

Environment

Style Dictionary (version: 4.3.3)

@maharielrosario
Copy link

maharielrosario commented Feb 27, 2025

I also am having a similar issue using the multi-brand-multi-platform example but I get the "Some token references could not be found error" when the names of my brands match the directory names or when I provide a custom path in the source in the getStyleDictionaryConfig source property.

If my directories are named differently than what I use for brands in the build.js and remove the tokens/primitives/*.json5, it works fine.

build.js


import StyleDictionary from 'style-dictionary';

import { formats, transformGroups } from 'style-dictionary/enums';

 

const { androidResources, iosMacros, scssVariables, cssVariables } = formats;

const { web, android, ios } = transformGroups;

 

const brands = ['brand-1', 'brand-2'];

const platforms = ['android', 'ios', 'web'];

 

// HAVE THE STYLE DICTIONARY CONFIG DYNAMICALLY GENERATED

function getStyleDictionaryConfig(brand, platform) {

  return {

    source: [

      `tokens/brands/${brand}/*.json5`,

      'tokens/primitives/*.json5',

      `tokens/platforms/${platform}/*.json5`,

    ],

    platforms: {

      web: {

        transformGroup: web,

        buildPath: `build/web/${brand}/`,

        files: [

          {

            destination: 'tokens.scss',

            format: scssVariables,

          },

          {

            destination: 'tokens.css',

            format: cssVariables

          }

        ],

      },

      android: {

        transformGroup: android,

        buildPath: `build/android/${brand}`,

        files: [

          {

            destination: 'tokens.dimens.xml',

            format: androidResources,

            filter: {

              type: "dimension"

            }

          },

          {

            destination: 'tokens.font_dimens.xml',

            format: androidResources,

            filter: {

              type: "dimension"

            }

          },

        ],

      },

      ios: {

        transformGroup: ios,

        buildPath: `build/ios/${brand}/`,

        files: [

          {

            destination: 'tokens.h',

            format: iosMacros,

          },

        ],

      },

    },

  };

}

 

console.log('Build started...');

 

// PROCESS THE DESIGN TOKENS FOR THE DIFFERENT BRANDS AND PLATFORMS

 

brands.map(function (brand) {

  platforms.map(function (platform) {

    console.log('\n==============================================');

    console.log(`\nProcessing: [${platform}] [${brand}]`);

 

    const sd = new StyleDictionary(getStyleDictionaryConfig(brand, platform));

    sd.buildPlatform(platform);

  });

});

 

console.log('\n==============================================');

console.log('\nBuild completed!');

tokens/brands/brand-1/background.json5


"base": {

        "$type": "color",

        "$value": "{primitive.color.white}",

          "$extensions": {

            "mode": {

              "light": { "$value": "{primitive.color.white}"},

              "darK": { "$value": "{primitive.color.gray.1200}"}

            }

          }

      }

tokens/brands/brand-2/background.json5


"base": {

        "$type": "color",

        "$value": "{primitive.color.white}"

      }

package.json


{

  "name": "style-dictionary-auto-rebuild-watcher",

  "version": "1.0.0",

  "description": "",

  "main": "build/index.js",

  "type": "module",

  "files": [

    "build",

    "properties"

  ],

  "scripts": {

    "build": "node ./build.js",

    "clean": "rm -rf build",

    "test": "echo \"Error: no test specified\" && exit 1"

  },

  "author": "",

  "license": "Apache-2.0",

  "devDependencies": {

    "style-dictionary": "^4.0.0"

  }

}

tokens/primitives/breakpoint.json5


{

  "primitive": {

    "breakpoint": {

      "xs": {

        "$type": "dimension",

        "$value": "320px"

      },

      "sm": {

        "$type": "dimension",

        "$value": "768px"

      },

      "md": {

        "$type": "dimension",

        "$value": "1012px"

      },

      "lg": {

        "$type": "dimension",

        "$value": "1280px"

      },

      "xl": {

        "$type": "dimension",

        "$value": "1600px"

      }

    }

  }

}

npm version: 10.9.2
node version: 22.13.1

@jorenbroekema
Copy link
Collaborator

This is expected because you're putting your "custom theme a" and also "custom theme b" in the source property for both Style Dictionary instances. The former is referring to brand A and the latter is referring to brand B but the Style Dictionary instance only has one or the other available, one at a time.

Generally speaking, your theme-specific tokensets will contain the exact same token definitions but with different values (depending on the theme). In your example, your theme-specific tokensets contain different token definitions. This won't work when your non-theme-specific sets are referring to tokens in your theme-specific sets and expecting only to refer to a different token value (but the same token definition) when the theme changes.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants