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

Consider sass-extract or theo as a replacement for herman-export/sass-json-export. #217

Open
jgerigmeyer opened this issue Dec 5, 2017 · 14 comments
Assignees
Milestone

Comments

@jgerigmeyer
Copy link
Member

https://github.com/jgranstrom/sass-extract

@mirisuzanne
Copy link
Member

@jgerigmeyer I think this would be a great question to address sooner rather than later?

@jgerigmeyer
Copy link
Member Author

@mirisuzanne Sure, good call. I'll start here tomorrow morning.

@jgerigmeyer jgerigmeyer added this to the Herman 1.x Stretch Goals milestone Dec 6, 2017
@jgerigmeyer
Copy link
Member Author

@mirisuzanne I see some tradeoffs here, and I'd like to talk through the pros/cons with you. Right now (with herman-export), the API works as follows:

  • The user creates a Sass map.
  • The user adds the map to $herman with herman-add
  • The user exports the map with herman-export
  • The user displays the map with an annotation (e.g. @colors) and a key (e.g. my-color).

sass-extract is JS-driven. It works like node-sass, parsing a scss file and exposing the variables/maps. So if we wanted to use it, this is roughly the API I'd imagine:

  • The user creates a Sass map.
  • The user adds the map to $herman with herman-add (this step could likely be removed, but then we would need the user to provide the name of the global variable to look for)
  • The user displays the map with an annotation (e.g. @colors) and a key (e.g. my-color) and a file path to a scss file (e.g. ./scss/styleguide.scss). That file could be essentially the same as the current json.scss file, but without @include herman-export;.

Basically, the change would be that the user provides a path to a scss file instead of a path to a rendered css file that includes herman-export.

It would be possible to automatically parse the scss file where the annotation is found (looking there for the variable), but 1) that may not be a valid scss file on its own (i.e. it may use mixins or whatnot from elsewhere), and 2) it's not guaranteed that the file containing the annotation also contains the necessary variable/map. So I don't think that's a reliable approach.

So, if we go this route, I think the current sass.jsonfile option would become something like sass.variablesfile or whatever. Then when an annotation (@font, @colors, @sizes, or @ratios) is used, the JS would do something like:

const filePath = path.resolve(env.dir, env.herman.sass.variablesfile);
const vars = sassExtract.renderSync({
  file: filePath,
  importer: url => {
    if (url[0] === '~') {
      url = path.resolve(env.dir, 'node_modules', url.substr(1));
    }
    return { file: url };
  },
  includePaths: env.herman.sass.includepaths,
}).vars;
const fontData = vars.global.$herman.value.fonts.value[fontKey].value;

(Sidenote: There's actually a bug in sass-extract that prevents custom importer fns from working, but I've got it working locally and I'm submitting a PR to fix that.)

Variables are exposed as processed objects (not just the raw values). It's not really a problem, for where right now we get:

{
  name: 'rockingham',
  regular: 'rockingham/rockingham-regular-webfont',
  bold: 'rockingham/rockingham-bold-webfont',
  italic: 'rockingham/rockingham-italic-webfont',
  '"bold" "italic"': 'rockingham/rockingham-bolditalic-webfont',
  stack: 'fantasy'
}

We'd get this instead:

{
  name: {
    type: 'SassString',
    value: 'rockingham'
  },
  regular: {
    type: 'SassString',
    value: 'rockingham/rockingham-regular-webfont'
  },
  bold: {
    type: 'SassString',
    value: 'rockingham/rockingham-bold-webfont'
  },
  italic: {
    type: 'SassString',
    value: 'rockingham/rockingham-italic-webfont'
  },
  'bold italic': {
    type: 'SassString',
    value: 'rockingham/rockingham-bolditalic-webfont'
  },
  stack: {
    type: 'SassString',
    value: 'fantasy'
  }
}

In any case, I'm not 100% convinced this would be better. The user would no longer need to provide a CSS file generated with herman-export, but they would need to provide a path to a SCSS file that contains the necessary vars, in a consistent structure.

I do think sass-extract (and sass-extract-loader, https://github.com/jgranstrom/sass-extract-loader) is a candidate to replace our current sass-json-loader for accessing Sass vars from app JS, but that's a separate question.

@jgerigmeyer
Copy link
Member Author

(@davisagli @wlonk No pressure, but happy for your thoughts here as well if you like.)

@mirisuzanne
Copy link
Member

that makes sense, I think. If we can't really automate more of the Sass API side, I don't have much reason to push this.

@jgerigmeyer
Copy link
Member Author

I mean, we can automate most of it... but we still need to know where there's a valid Scss file with the maps/variables. It would certainly a less Herman-centric approach (no more custom mixin; just a path to a Scss file). I could go either way.

@jgerigmeyer
Copy link
Member Author

jgerigmeyer commented Dec 7, 2017

Thoughts from a discussion with @mirisuzanne:

Pro: It would be great to get rid of both herman-export and herman-add. We allow users to structure their variables however they want, and just give us a Scss file globally and then a variable name whenever they use an annotation that requires it.

Con: Right now, @example scss is the only time Herman is actually compiling Scss to CSS -- elsewhere the user is giving us compiled CSS. This is adding another place where Herman needs to be able to compile the user's Scss, and this can get complicated depending on the user's precompile/build process. We already have support for webpack-style ~ imports, but this opens the door to needing more things like that to support more build stacks. If we go this route, probably it would mean getting rid of the current sass.includepaths and sass.includes options, and just replacing with a more generic sassOptions option, which gets passed along to node-sass wherever we use that. So users can pass in any custom options they like, and we would use them for both @example scss and these other annotations.

@jgerigmeyer
Copy link
Member Author

In case we do want to use this, PR submitted to fix the custom importer bug: jgranstrom/sass-extract#25

@jgerigmeyer
Copy link
Member Author

Still interested in thoughts here from @mirisuzanne @davisagli or @wlonk if anyone has a leaning one way or the other.

@wlonk
Copy link
Contributor

wlonk commented Dec 8, 2017

I have no opinions yet.

@davisagli
Copy link
Contributor

After reading through the above, no strong leaning. I think it would be a significant win for the user only if we make the change to remove herman-export and herman-add, because then they only have to worry about how they configure herman and not also how they write their Sass for herman.

@jgerigmeyer
Copy link
Member Author

Yeah, I think that's a pretty compelling argument to try to make this change. And it doesn't seem unreasonable to say, "Any Scss that you're expecting Herman to understand (e.g. @example or these Sass variables) needs to be standard enough that node-sass can parse it with your provided options."

@mirisuzanne
Copy link
Member

I agree. We'll want to add a map-compile feature to each Accoutrement (since our maps don't fint a standard format), but that's a good idea anyway. Make Herman more flexible, and our tooling can adjust to fit.

@jgerigmeyer jgerigmeyer self-assigned this Jan 4, 2018
@mirisuzanne mirisuzanne changed the title Consider sass-extract as a replacement for herman-export/sass-json-export. Consider sass-extract or theo as a replacement for herman-export/sass-json-export. Mar 11, 2018
@mirisuzanne
Copy link
Member

Another option would be the salesforce-ux/theo approach – with design tokens in YAML…

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

No branches or pull requests

4 participants