Skip to content

Commit

Permalink
BREAKING: make style-dictionary ESM-only and browser-compatible (#1014)
Browse files Browse the repository at this point in the history
  • Loading branch information
jorenbroekema committed Oct 22, 2023
1 parent 7d2310c commit dcbe2fb
Show file tree
Hide file tree
Showing 111 changed files with 12,015 additions and 20,986 deletions.
8 changes: 8 additions & 0 deletions .changeset/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# Changesets

Hello and welcome! This folder has been automatically generated by `@changesets/cli`, a build tool that works
with multi-package repos, or single-package repos to help you version and publish your code. You can
find the full documentation for it [in our repository](https://github.com/changesets/changesets)

We have a quick list of common questions to get you started engaging with this project in
[our documentation](https://github.com/changesets/changesets/blob/main/docs/common-questions.md)
12 changes: 12 additions & 0 deletions .changeset/big-worms-collect-2.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
---
'style-dictionary': minor
---

FileSystem that is used by Style-Dictionary can now be customized:

```js
import { setFs } from 'style-dictionary/fs';
setFs(myFileSystemShim);
```

By default, it uses an in-memory filesystem shim `@bundled-es-modules/memfs` in browser context, `node:fs` built-in module in Node context.
12 changes: 12 additions & 0 deletions .changeset/big-worms-collect.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
---
'style-dictionary': major
---

#### BREAKING:

- The project has been fully converted to [ESM format](https://nodejs.org/api/esm.html), which is also the format that the browser uses.
For users, this means you'll have to either use Style-Dictionary in ESM JavaScript code, or dynamically import it into your CommonJS code.
- `Style-Dictionary.extend()` method is now asynchronous, which means it returns `Promise<StyleDictionary.Core>` instead of `StyleDictionary.Core`.
- `allProperties` / `properties` was deprecated in v3, and is now removed from `StyleDictionary.Core`, use `allTokens` and `tokens` instead.
- Templates and the method `registerTemplate` were deprecated in v3, now removed. Use Formats instead.
- The package now uses [package entrypoints](https://nodejs.org/api/packages.html), which means that what is importable from the package is locked down to just the specified entrypoints: `style-dictionary` & `style-dictionary/fs`. If more is needed, please raise an issue explaining which file you were importing and why you need it to be public API.
11 changes: 11 additions & 0 deletions .changeset/config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"$schema": "https://unpkg.com/@changesets/config@2.3.1/schema.json",
"changelog": "@changesets/cli/changelog",
"commit": false,
"fixed": [],
"linked": [],
"access": "public",
"baseBranch": "v4",
"updateInternalDependencies": "patch",
"ignore": []
}
8 changes: 8 additions & 0 deletions .changeset/pre.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"mode": "pre",
"tag": "prerelease",
"initialVersions": {
"style-dictionary": "3.8.0"
},
"changesets": []
}
3 changes: 2 additions & 1 deletion .eslintrc.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
{
"parserOptions": {
"ecmaVersion": "latest"
"ecmaVersion": "latest",
"sourceType": "module"
},
"plugins": ["jest"],
"env": {
Expand Down
13 changes: 11 additions & 2 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,16 @@ jobs:
with:
node-version: 18.x
registry-url: 'https://registry.npmjs.org'
- run: npm ci
- run: npm publish

- name: Install Dependencies
run: npm ci

- name: Create Release Pull Request or Publish to npm
id: changesets
uses: changesets/action@v1
with:
# This expects you to have a script called release which does a build for your packages and calls changeset publish
publish: npm run release
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
23 changes: 0 additions & 23 deletions .github/workflows/test.yml

This file was deleted.

15 changes: 11 additions & 4 deletions .github/workflows/verify.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,25 @@ jobs:
verify:
name: Verify changes
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [18.x, 20.x]
steps:
- uses: actions/checkout@v2

- name: Setup Node 18.x
uses: actions/setup-node@v1
- name: Setup Node ${{ matrix.node-version }}
uses: actions/setup-node@v2
with:
node-version: 18.x
node-version: ${{ matrix.node-version }}
cache: 'npm'

- name: Install Dependencies
run: npm ci

- name: Lint & Test
- name: Linting & Formatting
run: npm run lint

- name: Tests
run: npm run test

# in case we use playwright & @web/test-runner in the future
Expand Down
1 change: 1 addition & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
.changeset/
89 changes: 53 additions & 36 deletions bin/style-dictionary
Original file line number Diff line number Diff line change
Expand Up @@ -2,29 +2,33 @@

'use strict';

var fs = require('fs-extra'),
program = require('commander'),
path = require('path'),
StyleDictionary = require('..'),
pkg = JSON.parse(fs.readFileSync(path.join(__dirname, '..', 'package.json'), 'utf8')),
chalk = require('chalk');
import JSON5 from 'json5';
import program from 'commander';
import path from 'path';
import { fileURLToPath } from 'url';
import node_fs from 'node:fs';
// usually also node:fs in this context, but can be customized by user
import { fs } from '../fs.js';
import StyleDictionary from '../index.js';

const __dirname = path.dirname(fileURLToPath(import.meta.url));

const pkg = JSON5.parse(node_fs.readFileSync(path.join(__dirname, '..', 'package.json'), 'utf8'));

function collect(val, arr) {
arr.push(val);
return arr;
}

function getConfigPath(options) {
var configPath = options.config;
let configPath = options.config;

if(!configPath) {
if(fs.existsSync('./config.json')) {
if (!configPath) {
if (fs.existsSync('./config.json')) {
configPath = './config.json';
}
else if(fs.existsSync('./config.js')) {
} else if (fs.existsSync('./config.js')) {
configPath = './config.js';
}
else {
} else {
console.error('Build failed; unable to find config file.');
process.exit(1);
}
Expand All @@ -33,75 +37,88 @@ function getConfigPath(options) {
return configPath;
}

program
.version(pkg.version)
.description(pkg.description)
.usage('[command] [options]');

program.version(pkg.version).description(pkg.description).usage('[command] [options]');

program
.command('build')
.description('Builds a style dictionary package from the current directory.')
.option('-c, --config <path>', 'set config path. defaults to ./config.json')
.option('-p, --platform [platform]', 'only build specific platforms. Must be defined in the config', collect, [])
.option(
'-p, --platform [platform]',
'only build specific platforms. Must be defined in the config',
collect,
[],
)
.action(styleDictionaryBuild);

program
.command('clean')
.description('Removes files specified in the config of the style dictionary package of the current directory.')
.description(
'Removes files specified in the config of the style dictionary package of the current directory.',
)
.option('-c, --config <path>', 'set config path. defaults to ./config.json')
.option('-p, --platform [platform]', 'only clean specific platform(s). Must be defined in the config', collect, [])
.option(
'-p, --platform [platform]',
'only clean specific platform(s). Must be defined in the config',
collect,
[],
)
.action(styleDictionaryClean);

program
.command('init <type>')
.description('Generates a starter style dictionary')
.action(function(type){
var types = ['basic', 'complete'];
.action(function (type) {
const types = ['basic', 'complete'];
if (types.indexOf(type) < 0) {
console.error('Please supply 1 type of project from: ' + types.join(', '));
process.exit(1);
}

console.log('Copying starter files...\n');
fs.copySync(path.join(__dirname, '..', 'examples', type), process.cwd());
node_fs.copySync(path.join(__dirname, '..', 'examples', type), process.cwd());
console.log('Source style dictionary starter files created!\n');
console.log('Running `style-dictionary build` for the first time to generate build artifacts.\n');
console.log(
'Running `style-dictionary build` for the first time to generate build artifacts.\n',
);
styleDictionaryBuild();
});

// error on unknown commands
program.on('command:*', function () {
console.error('Invalid command: %s\nSee --help for a list of available commands.', process.argv.slice(2).join(' '));
console.error(
'Invalid command: %s\nSee --help for a list of available commands.',
process.argv.slice(2).join(' '),
);
process.exit(1);
});

function styleDictionaryBuild(options) {
async function styleDictionaryBuild(options) {
options = options || {};
var configPath = getConfigPath(options);
const configPath = getConfigPath(options);

// Create a style dictionary object with the config
var styleDictionary = StyleDictionary.extend( configPath );
const styleDictionary = await StyleDictionary.extend(configPath);

if (options.platform && options.platform.length > 0) {
options.platform.forEach(function(platform) {
styleDictionary.buildPlatform( platform );
options.platform.forEach(function (platform) {
styleDictionary.buildPlatform(platform);
});
} else {
styleDictionary.buildAllPlatforms();
}
}

function styleDictionaryClean(options) {
async function styleDictionaryClean(options) {
options = options || {};
var configPath = getConfigPath(options);
const configPath = getConfigPath(options);

// Create a style dictionary object with the config
var styleDictionary = StyleDictionary.extend( configPath );
const styleDictionary = await StyleDictionary.extend(configPath);

if (options.platform && options.platform.length > 0) {
options.platform.forEach(function(platform) {
styleDictionary.cleanPlatform( platform );
options.platform.forEach(function (platform) {
styleDictionary.cleanPlatform(platform);
});
} else {
styleDictionary.cleanAllPlatforms();
Expand Down
2 changes: 1 addition & 1 deletion examples/advanced/custom-file-header/build.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ const myCustomFormat = ({ dictionary, file }) => {
.join(`\n`)}`;
};

const styleDictionary = StyleDictionary.extend({
const styleDictionary = await StyleDictionary.extend({
// You can add custom file headers directly on the configuration by
// adding a `fileHeader` object. The keys inside are the names of
// the file headers
Expand Down
2 changes: 1 addition & 1 deletion examples/advanced/custom-filters/build.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ StyleDictionary.registerFilter({
// APPLY THE CONFIGURATION
// IMPORTANT: the registration of custom transforms
// needs to be done _before_ applying the configuration
const StyleDictionaryExtended = StyleDictionary.extend(__dirname + '/config.json');
const StyleDictionaryExtended = await StyleDictionary.extend(__dirname + '/config.json');

// FINALLY, BUILD ALL THE PLATFORMS
StyleDictionaryExtended.buildAllPlatforms();
Expand Down
28 changes: 17 additions & 11 deletions examples/advanced/custom-formats-with-templates/build.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,14 @@
const StyleDictionary = require('style-dictionary').extend(__dirname + '/config.json');
const fs = require('fs');
const _ = require('lodash');
const handlebars = require('handlebars');
const pug = require('pug');
import { dirname } from 'path';
import { fileURLToPath } from 'url';
import StyleDictionary from 'style-dictionary';
import fs from 'fs';
import _ from 'lodash';
import handlebars from 'handlebars';
import pug from 'pug';

const __dirname = dirname(fileURLToPath(import.meta.url));

const sd = await StyleDictionary.extend(__dirname + '/config.json');

console.log('Build started...');
console.log('\n==============================================');
Expand All @@ -11,17 +17,17 @@ console.log('\n==============================================');

// These formatting functions are using the Lodash "template" syntax

StyleDictionary.registerFormat({
sd.registerFormat({
name: 'custom/format/scss',
formatter: _.template(fs.readFileSync(__dirname + '/templates/web-scss.template')),
});

StyleDictionary.registerFormat({
sd.registerFormat({
name: 'custom/format/ios-plist',
formatter: _.template(fs.readFileSync(__dirname + '/templates/ios-plist.template')),
});

StyleDictionary.registerFormat({
sd.registerFormat({
name: 'custom/format/android-xml',
formatter: _.template(fs.readFileSync(__dirname + '/templates/android-xml.template')),
});
Expand All @@ -31,7 +37,7 @@ const templateCustomXml = handlebars.compile(
fs.readFileSync(__dirname + '/templates/android-xml_alt.hbs', 'utf8'),
);

StyleDictionary.registerFormat({
sd.registerFormat({
name: 'custom/format/android-xml-alt',
formatter: function ({ dictionary, platform }) {
return templateCustomXml({
Expand All @@ -50,7 +56,7 @@ const templateCustomPlist = pug.compileFile(__dirname + '/templates/ios-plist_al
pretty: true,
});

StyleDictionary.registerFormat({
sd.registerFormat({
name: 'custom/format/ios-plist-alt',
formatter: function ({ dictionary }) {
return templateCustomPlist({
Expand All @@ -60,7 +66,7 @@ StyleDictionary.registerFormat({
});

// FINALLY, BUILD ALL THE PLATFORMS
StyleDictionary.buildAllPlatforms();
sd.buildAllPlatforms();

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

0 comments on commit dcbe2fb

Please sign in to comment.