-
Notifications
You must be signed in to change notification settings - Fork 843
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
Export scss vars as json during compilation #642
Export scss vars as json during compilation #642
Conversation
@weltenwort Thanks for doing this! I won't be able to review this so I'm tagging in @mattapperson and @snide. |
scripts/compile-scss.js
Outdated
const splitFileName = fileName.split('.'); | ||
const baseFileName = splitFileName[0]; | ||
const cssFileName = `dist/eui_${baseFileName}.css`; | ||
const varsFileName = `dist/eui_${baseFileName}.json`; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I know you didn't write this code, but since we are at it, perhaps replace all filename logic with path.parse. You can get it mostly with a one-liner, and it'll work cross platform (I don't think Windows likes the forward slashes):
const { name: baseFileName } = path.parse(file);
scripts/compile-scss.js
Outdated
}); | ||
}) | ||
) | ||
); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe a catch
at the bottom, so errors doesn't get swallowed?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: I think this would benefit from async/await.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am curious if it is better to save as a JSON file or a js file exporting an object. JSON will have parsing overhead at runtime as webpack will bundle as a string then JSON.parse on each require (at least last time I checked)
This is really great. Thanks for doing this!! 👍 |
Thanks for the very valuable feedback, @sqren! I have flattened the Let me know what you think. |
@weltenwort I am curious if it is better to save as a JSON file or a js file exporting an object. JSON will have parsing overhead at runtime as webpack will bundle as a string then JSON.parse on each require (at least last time I checked) |
I thought about that. But as soon as it's a |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
lgtm
@weltenwort Well, yea writing to SRC is bad. So what if we then create an export on EUI for the JSON file that pre-parses it one time, preventing multiple parsing? |
Another added perk to exporting the configs is it gives it an API rather then just a file. This way we can change the implementation without breaking compatibility if we need to down the road |
I agree that exposing a javascript interface would be nice, but... That adds the assumption that any consumer of the commonjs or es module can import json. AFAIK that is the case for node, webpack and browserify, but I don't know if that's sufficient. We could put the json import in something like |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This will certainly work, and as the consumers of the variables you three will probably know best about what you need so I'll leave it to you if this solution works for you.
All that said, when actually composing our styles on a day to day basis, you can see @cchaos and I are using mixins pretty heavily. Bringing over the variables is just part of it. Without the mixins, you'll likely be duplicating a lot of the work and eventually going off pattern for larger projects. A simple example would be dealing with shadows. Right now those are all mixins. You'll likely need to rebuild them by hand (and again, could be different per theme!).
I'd eventually like to use something like https://github.com/4Catalyzer/css-literal-loader/blob/master/README.md#experimental-component-api which seems much more wholistic with its import, allowing you to directly import sass into your JS (mixins included). Unfortunately I haven't had time to really build out a decent test of it, but in concept it seems to cover more of what we'd want.
There's no reason we can't move there eventually, and since the vars shouldn't change this would hopefully just be an import switch when we do. If this is a quick stepping stone to unblock you all I'm fine with it, but thought I'd bring it up in case you have time.
One question though. If I change the name of a var in Sass now, would you consider that a breaking change that needs documentation? It would likely break your consumption no? It doesn't happen too much on the core global_styling
variables, but likely happens on the inner modules from time to time (For example, we've rewritten the forms SCSS a few times now).
Beyond all that commentary, if you all decide this is the way you want to handle the JS vars, then please add some documentation for how this works. Specifically I'd expect...
- Some comments in the Readme / wiki
- Some comments in the how to consume EUI docs.
- Possibly a documentation page in Utilities that shows an example.
Again, all of these are short term solutions. Long term I think the whole system will be in some form of CSS in JS system with a more contained, modularized approach. I've tried to write the SCSS that way so that when the transition comes, it should be easy to port over without too much detangling!
thanks for sharing your thoughts, @snide breaking changes: That is already the case with just mixins: Somehow "importing" the Looking at So the question seems to be whether we can live without reusing the mixins in components outside of EUI. @sqren, having used styled-components in production while trying to match EUI styling, did you miss the ability to access the sass mixins so far? |
I didn't miss sass mixins, since mixins feel very natural in js (example from the styled-components docs): import { truncate } from '../style-utils';
// Make this div truncate the text with an ellipsis
const Box = styled.div`
${ truncate('250px') }
background: papayawhip;
`; If a lot of work has been put into creating sass mixins, it will of course take time to redo that in js (if needed). But until now I haven't really missed EUI mixins. I mostly use EUI's react components and configure them through props. So from my POV we can get by without the mixins - at least for now. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Cool. Like I said, you all are the audience most aware of the needs. I do like the looks of that library (it does support mixins somehow) but I'm not hung up on it.
Seems like an OK solution for the moment.
@felix-lessoer I am fine with adding it to alternatively though, what if we add something like the solution outlined here webpack/webpack#6572. That way the JSON is just included in the bundle as an object? |
I would like to avoid cluttering the build process with more and more loaders... especially since the "bundle" is only one of three ways to consume EUI. Kibana is probably using the es-module variant straight from (also, wrong Felix 😉) |
But it’s not adding the need for another loader. If you have the loader you get better perf then just loading the json and parsing at runtime... graceful degradation. We can still put the access to the api inside arc/themes/index.js or whatever you like for that |
scripts/compile-scss.js
Outdated
}); | ||
}) | ||
) | ||
); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am curious if it is better to save as a JSON file or a js file exporting an object. JSON will have parsing overhead at runtime as webpack will bundle as a string then JSON.parse on each require (at least last time I checked)
a589a01
to
d5b06d6
Compare
d5b06d6
to
5d29f83
Compare
I have added a small documentation segment with an example for using the exported json files with `styled-components'. Furthermore, I added a simple typescript definition to satisfy the compiler. I'd like to defer the following items to a follow-up PR:
If the reviewers could take another look at these latest changes to ensure it doesn't change the approval they graciously gave? 😉 |
WOOT! Thanks for this @weltenwort! |
This PR enhances the script
scripts/compile-scss.js
to export also extract and export the sass variables from each theme into a corresponding json file indist/eui_theme_${THEME}.json
. The values in this file are in a format suitable for use in styled-components themes to keep the scss files as a single source of truth.It also converts the script to use async I/O to improve parallelism.
The export of ready-to-use themes could be considered in a subsequent step.