-
-
Notifications
You must be signed in to change notification settings - Fork 1.4k
Add limited support for named exports. Add docs relating to this support. #825
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
Conversation
Codecov Report
|
…ined component name
One of the tests fails on one of the builds but passes on the others. It seems that the I tried refactoring the test to avoid reliance on the enumerable properties of |
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.
Thanks, this is interesting and I hope will make Styleguidist more flexible.
In the existing implementation of globalizeComponent, there are references to component.props.path.
I think it's safe to remove if everything still works.
I tried refactoring the test to avoid reliance on the enumerable properties of global but still no joy. Would appreciate any input on this.
Maybe try to put afterEach
inside describe
? Just a guess ;-/
docs/Components.md
Outdated
// will fall back on the file name, convert it to PascalCase | ||
// and expose globally as ComponentFour | ||
``` | ||
|
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.
There's one more use case: folder name when the file name is index.js
.
docs/Components.md
Outdated
// and expose globally as ComponentFour | ||
``` | ||
|
||
### default vs named exports |
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.
Default
docs/Components.md
Outdated
|
||
### default vs named exports | ||
|
||
Styleguidist defaults to exposing the `default` export from your component file. It understands functions exported as CommonJs `module.exports` as default exports. |
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 “Stylegudist will use ECMAScript module’s default
export or CommonJS module.exports
if they are defined”?
docs/Components.md
Outdated
// will be exposed globally as ComponentEight | ||
``` | ||
|
||
If you export several React components as named exports from a single module, Styleguidist is likely to behave unreliably. If it cannot understand which named export to expose, it will fall back to exposing the module as a whole. |
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.
it will fall back to exposing the module as a whole.
Not sure what exactly that mean, but most likey you'll not be able to access components, so we can say that instead ;-)
|
||
Styleguidist _loads_ your components and _exposes_ them globally for your examples to consume. | ||
|
||
### Identifier |
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.
Would be nice to make this section shorted and easier to scan. Maybe use one big table instead?
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.
Resorting to HTML table format here to play nicely with the code blocks. It makes this file a little ugly but the output is good.
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.
Could be simpler:
| foo | bar |
| --- | --- |
| `foo`<br>`bar` | bar |
Also you can remove the last column and use the same component name everywhere, and merge displayName and fallback columns since they are mutually exclusive.
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.
Ah yeah nice. Done.
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.
Wow, it's like 10 times smaller now ;-)
* @param {string} name | ||
* @return {function|object} | ||
*/ | ||
export default function getComponent(module, name) { |
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 guess your understanding of this code is very good now, could you please add comments to each variation? Preferably with code examples. This is one of the most obscure parts of the code base ;-/
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.
Nice! Please add a blank line before each comment to make it easier to read.
@@ -1,18 +1,30 @@ | |||
import globalizeComponent from '../globalizeComponent'; | |||
|
|||
jest.mock('../getComponent'); |
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.
Can we avoid mocking here? Doesn't look necessary.
@@ -1,18 +1,30 @@ | |||
import globalizeComponent from '../globalizeComponent'; | |||
|
|||
jest.mock('../getComponent'); | |||
// eslint-disable-next-line import/first | |||
import getComponent, { returnValue } from '../getComponent'; |
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.
ESM imports are hoisted to the top of the file, so disabling ESLint here is unnecessary and misleading.
Thanks for the feedback :) I'm out this weekend but I'll get to this on Monday. |
@sapegin I think that's everything. Let me know if you're happy with those changes :) |
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.
Thanks, almost!
|
||
Styleguidist _loads_ your components and _exposes_ them globally for your examples to consume. | ||
|
||
### Identifier |
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.
Could be simpler:
| foo | bar |
| --- | --- |
| `foo`<br>`bar` | bar |
Also you can remove the last column and use the same component name everywhere, and merge displayName and fallback columns since they are mutually exclusive.
* @param {string} name | ||
* @return {function|object} | ||
*/ | ||
export default function getComponent(module, name) { |
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.
Nice! Please add a blank line before each comment to make it easier to read.
* @return {function|object} | ||
*/ | ||
export default function getComponent(module, name) { | ||
// |
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.
Had to leave this little 'comment' in here to stop Prettier complaining about the blank line...
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.
Sorry, I wasn't clear enough: blank lines to separate code “paragraphs”, not just empty line before each comment ;-)
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.
So you mean changing this
// If the module defines a default export, return that
// e.g.
// ```
// export default function Component() { ... }
// ```
if (module.default) { ...
to this
// If the module defines a default export, return that
// e.g.
//
// ```
// export default function Component() { ... }
// ```
//
if (module.default) { ...
Or something else? :)
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.
Exactly! Just to separate different sections of code.
@sapegin Thanks - yeah that table was ugly. Think it's much cleaner now. |
|
||
Styleguidist _loads_ your components and _exposes_ them globally for your examples to consume. | ||
|
||
### Identifier |
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.
Wow, it's like 10 times smaller now ;-)
@sapegin Sweet - comments spaced out better now :) |
👋 **[Support Styleguidist](https://opencollective.com/styleguidist) on Open Collective** 👋 ## New features ### Page per section 🚧 This is a huge improvement for large style guides: now you can show only one component at a page instead of all components.  To enable: ```js module.exports = { pagePerSection: true }; ``` This is an experimental feature and we need your feedback to make it better and really useful. For example, right now there’s no isolated mode. So feel free to share your ideas [in issues](https://github.com/styleguidist/react-styleguidist/issues). (#835 by @bitionaire and @stepancar, closes #494 and #768) ### “Fork me” ribbon One more step to make Styleguidist usable for documenting open source projects:  New config option to enable the ribbon, define the URL and change the label: ```js module.exports = { ribbon: { url: 'http://example.com/', text: 'Fork me on GitHub' } }; ``` And two new [theme variables](https://github.com/styleguidist/react-styleguidist/blob/master/src/styles/theme.js) to change colors: `color.ribbonBackground` and `color.ribbonText`. (#861 by @glebez and @wkwiatek, part of #195, closes #647) ### Options to change CLI output on server start and build Two new options, `printServerInstructions` and `printBuildInstructions`: ```js module.exports = { printBuildInstructions(config) { console.log( `Style guide published to ${ config.styleguideDir }. Something else interesting.` ); } }; ``` (#878 by @roblevintennis, closes #876) ### Option to modify props A new option, `updateDocs` to modify props before rendering. For example, you can load a component version number from a JSON file: ```js module.exports = { updateDocs(docs) { if (docs.doclets.version) { const versionFilePath = path.resolve( path.dirname(file), docs.doclets.version ); const version = require(versionFilePath).version; docs.doclets.version = version; docs.tags.version[0].description = version; } return docs; } }; ``` (#868 by @ryanoglesby08) ### Limited support for named exports Styleguidist used to require default exports for components. Now you can use named exports too, though Styleguidist still supports only one component per file. I hope this change will make some users happier, see more details [in the docs](https://react-styleguidist.js.org/docs/components.html#loading-and-exposing-components). (#825 by @marcdavi-es, closes #820 and #633) ### Allow arrays of component paths in sections More flexibility in structuring your style guide: ```js module.exports = { sections: [ { name: 'Forms', components: [ 'lib/components/ui/Button.js', 'lib/components/ui/Input.js' ] } ] }; ``` (#794 by @glebez, closes #774) ### Sort properties by `required` and `name` attributes This change should make props tables more predictable for the users. Instead of relying on developers to sort props in a meaningful way, Styleguidist will show required props first, and sort props in each group alphabetically. To disable sorting, use the identity function: ```javascript module.exports = { sortProps: props => props }; ``` (#784 by @dotcs) ## Bug fixes * Allow `Immutable` state in examples (#870 by @nicoffee, closes #864) * Change template container ID to prevent clashes (#859 by @glebez, closes #753) * Better props definitions with Flow types (#781 by @nanot1m)
🎉 This PR is included in version 6.5.0 🎉 The release is available on: Your semantic-release bot 📦🚀 |
Summary
This responds to the need expressed in #820 and #633
It preserves the base case of Styleguidist loading
default
exports by default, while adding some limited support for exposing named exports where a module exposes no default export and either:I think these cases are non-controversial. In each case, it is almost guaranteed that the developer intends these named exports to be interpreted as the exported component.
I have added documentation covering this. The documentation is careful to emphasise that this is not a complete solution for named exports - Styleguidist will do its best but in complicated cases will just fall back to exposing the module as a whole, as it currently does.
Super happy to take questions and feedback on this. I love what you guys are doing with this tool.
Question
In the existing implementation of
globalizeComponent
, there are references tocomponent.props.path
. I couldn't get this property to show its face with a bunch of different configurations/attempts. I suspect maybe it's a legacy thing which is still hanging around.If I'm missing something here please let me know and I'll take account of this in the PR.