-
Notifications
You must be signed in to change notification settings - Fork 844
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
[EuiIcon] Convert generated icon .js
assets to .tsx
files
#5212
Conversation
- to get the latest features and perf improvements
- xmlns attr location changed for some reason :| - looks like it added xlink
- to match fs.readFileSync and .writeFileSync
- now that the files are .tsx, it's linting for the license NOTE: I could have added a eslint --fix command to yarn compile-icons, but doing so added another 30-40s of runtime to the command. Doing it in the writeFileSync keeps the command around 5-6s instead.
- by leaving a hint as to what file generator name to open/look for - now that these are actual .tsx files, it's going to be even less obvious to not edit them directly, and it's a nice developer affordance to say which file to look at rather than having to grep through the repo
yay, it works
@@ -27,7 +30,7 @@ iconFiles.forEach(async (filePath) => { | |||
|
|||
const hasIds = svgString.includes('id="'); | |||
|
|||
let jsxSource = await svgr( | |||
let jsxSource = svgr.sync( |
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.
Optional refactor, I just saw the documentation for it in https://react-svgr.com/docs/node-api/#usage and thought .sync
matched fs.readFileSync
and fs.writeFileSync
better
@@ -42,15 +45,17 @@ iconFiles.forEach(async (filePath) => { | |||
xmlns: 'http://www.w3.org/2000/svg', | |||
}, | |||
titleProp: true, | |||
typescript: true, |
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.
Documentation: https://react-svgr.com/docs/options/#typescript
const comment = '// THIS IS A GENERATED FILE. DO NOT MODIFY MANUALLY\n\n'; | ||
fs.writeFileSync(outputFilePath, comment + jsxSource); | ||
const outputFilePath = filePath.replace(/\.svg$/, '.tsx'); | ||
const comment = `\n// THIS IS A GENERATED FILE. DO NOT MODIFY MANUALLY. @see scripts/compile-icons.js\n\n`; |
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.
Optional generated comment enhancement: now that the icon files are .tsx
, it's even less obvious that you shouldn't edit them, so I figured it's nice to provide a @see
link and filename for devs to jump to directly rather than having to grep through the repo
@@ -730,7 +730,7 @@ exports[`EuiIcon props type arrowDown is rendered 1`] = ` | |||
> | |||
<path | |||
d="M13.069 5.157L8.384 9.768a.546.546 0 01-.768 0L2.93 5.158a.552.552 0 00-.771 0 .53.53 0 000 .759l4.684 4.61c.641.631 1.672.63 2.312 0l4.684-4.61a.53.53 0 000-.76.552.552 0 00-.771 0z" | |||
fill-rule="non-zero" | |||
fill-rule="nonzero" |
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.
Typescript caught this attribute issue, proving it works 🎉
Preview documentation changes for this PR: https://eui.elastic.co/pr_5212/ |
I tested this out in a simple create-react-app project, and icons fail to load: And thinking about this all again, that makes sense. The icon files will get compiled to js during the build, so the tsx lookup doesn't find the file. |
Ahhh 🤦♀️ Thanks for catching that Greg! I wonder if there's a way to detect "if compiled, looking for |
Or alternatively - is there a strong reason to import/load icons dynamically in the first place? Why not import them statically first and then find the right one via name/map later? 🤷 IIRC, tree-shaking isn't yet working in EUI/webpack so it's not really for perf reasons there, right? |
A build-aware or |
- webpack should be smart enough to attempt to load either a .tsx or a .js file automatically
@thompsongl So, earlier this morning I went down a 30min+ rabbit hole of seeing if I could convert the dynamic imports into static, and when I finally had it working and was doing some research on the perf implications, I had this epiphany... "Why are we even specifying either I'm 90% sure Webpack is typically smart enough to automatically import either TSX or JS modules over an Let me know if the latest commit works for you! I tested on local Kibana dev as well and it appears to be working there 🤞 |
Preview documentation changes for this PR: https://eui.elastic.co/pr_5212/ |
Preview documentation changes for this PR: https://eui.elastic.co/pr_5212/ |
Lots of warnings in the build log related to
|
Ahh gotcha, yeah I saw those on build as well but I actually wasn't sure if they'd always been there, and the built version appeared to work. I'll move the .tsx files into a separate folder to test that |
- so webpack doesn't get confused when trying to dynamically import an extensionless file that has both a .tsx and .svg folder in the same dir - also allows us to flatten the tokens/ folder
- was doing a grep for /assets/ and got a little confused by the location of this
- moved faceNeutral (used) to face_neutral (unused) to match other casing
Not seeing the warnings anymore on build after splitting out the |
Preview documentation changes for this PR: https://eui.elastic.co/pr_5212/ |
... oh wait, I forgot we tell people to access Going to push up a folder name change where I leave the generated files in |
- we can lint if we want to! we can leave your gitignore behind
Can you also then update this portion of the wiki https://github.com/elastic/eui/blob/master/wiki/creating-icons.md#prepare-the-pull-request? 😄 |
Yeah! I should've just done that here: 5ab0988#diff-54bd9836a1fd4490b5678c576189707530d0b5fc051feb9cecc09c42a3595848 |
As of latest commit, EUI's |
Preview documentation changes for this PR: https://eui.elastic.co/pr_5212/ |
This is looking good now! |
Tree-shaking EUI does work (last I checked at least), but it requires enabling the |
We use the dynamic import to avoid including the icons in the core bundle, as it's unlikely most applications would use them all. Even in Kibana they are not all present on one page, and we see the benefits of not downloading all the svgs at once, which would otherwise add to the initial bundle download & parse times. |
Super helpful to get that context - thanks Chandler! I was thankfully able to avoid changing the icon component from using dynamic import in the final solution. |
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.
Changes LGTM! Extensionless import is fine, and I don't believe would have any effects.
Preview documentation changes for this PR: https://eui.elastic.co/pr_5212/ |
Summary
A nice capstone to my #5044 work - with this PR, all
.js
files insrc/
are officially gone! 💥I recommend following along by commit, and skimming commits that indicate they're primarily running
yarn compile-icons
😅 I also left some code comments walking through specific changes, w/ documentation links.QA
Checklist
- [ ] Checked in mobile- [ ] Props have proper autodocs and playground toggles~- [ ] Added documentation
- [ ] Checked Code Sandbox works for any docs examples- [ ] Checked for breaking changes and labeled appropriately