-
Notifications
You must be signed in to change notification settings - Fork 499
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
doc(jsdoc): jsDoc for Component & connector documentation #1435
Conversation
Some conflicts |
export default function() { | ||
return function(files, metalsmith, done) { | ||
const categories = {}; | ||
forEach(files, (data, path) => { |
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.
Minor comment: I tend to just use Object.entries(map, [path, data] => {})
(in other parts of plugins).
}); | ||
}); | ||
|
||
forEach(files, (data, path) => { |
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 add a small comment on why do we need to loop twice?
if (file.stats && file.stats.ctime) { | ||
return Date.parse(file.stats.ctime) > lastRunTime || Date.parse(file.stats.mtime) > lastRunTime; | ||
} else { | ||
return 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.
Maybe later in the file can we reuse hasChanged since it now handles the case where there's no stats?
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.
Ok I fixed what went wrong here in the code that checks the availability of stats. I also kept a check on the value used anyway (boyscout rule cc @pixelastic)
nav_groups: | ||
- core | ||
nav_sort: 1 | ||
category: core |
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 category: core means it's a guide? Maybe we could express this by using category: guide
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.
Good point!
@@ -17,6 +17,7 @@ builder({middlewares}, err => { | |||
|
|||
// then we watch and rebuild | |||
watch([ | |||
rootPath('packages/react-instantsearch/src/**/*.js'), |
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.
Do you remember why you had to add this line? The devServer is supposed to handle this part (watch webpack build, rebuild, reload)
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.
Now there is content in the js files, that's why we should trigger the build of the jsdoc (which is in the metalsmith build)
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 yes the jsDoc needs to be re-read, got it.
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.
Previously this was handled by the markdown files updates
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 we can remove the line watching markdown files then
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.
done
"lodash": "4.16.2", | ||
"marked": "0.3.6", | ||
"material-ui": "0.15.4", | ||
"memoizee": "0.4.1", |
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 "react-docgen" is no more needed also
@@ -182,4 +191,31 @@ class InstantSearch extends Component { | |||
} | |||
} | |||
|
|||
InstantSearch.propTypes = { |
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.
Is this needed because of jsdoc parsing limitation? (static vs .)
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.
yep!
Yes I know, I'm working on them :P |
|
||
onHistoryInternalStateUpdate = state => { | ||
onHistoryInternalStateUpdate(state) { | ||
this.aisManager.onExternalStateUpdate(state); |
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.
How does that work? The state =>
notation automatically binds to the current instance. In that case, since the onHistoryInternalStateUpdate
method is passed by reference, it looses its context, so we need to have it bound to the InstantSearch
instance somehow.
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 does not. :(
Fixed
93a72af
to
b5df378
Compare
b5df378
to
1db96ad
Compare
this._aisContextCache = { | ||
ais: { | ||
onInternalStateUpdate: this.onWidgetsInternalStateUpdate.bind(this), | ||
createHrefForState: this.createHrefForState.bind(this), |
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.
Usually you'd just bind/reassign them in the constructor.
constructor(props) {
/* ... */
this.onWidgetsInternalStateUpdate = this.onWidgetsInternalStateUpdate.bind(this);
// etc.
}
Is there a particular reason we want to avoid the method = () =>
construct?
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.
Yes but bind is only mandatory because we export those. So this way makes the bind more explicit and localised. I didn't choose to do it the way you propose because I thought that it wasn't needed.
We avoid the assignment construct in class because jsdoc is as of now unable to parse it :(
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.
Is there an issue on the jsdoc project speaking about this? I am curious.
@@ -56,6 +56,7 @@ | |||
"google-map-react": "^0.20.0", | |||
"insert-css": "^1.0.0", | |||
"jest-cli": "^16.0.0", | |||
"jsdoc-parse": "^1.2.7", |
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 we use the latest jsdoc-parse version? (now 2.) Or is there any blocker?
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 on v2 is very scarce, and I don't get the intent is for this next version as it mentions right away the use of jsdoc2md, and we don't want the markdown transformation https://github.com/jsdoc2md/jsdoc-parse
This looks good, only worried about having to change our coding style given limitations of the jsdoc parsing. Would be awesome to fix that. The not so easy part to grasp is that we are documenting everything with jsDoc comments, there seems to be no documentation inferred from the code itself (Am I right?). So ultimately the way we write code should not even interfere. Technically we could just do a regexp that extract a jsDoc comment then work from there, if it requires us to just add The parts we had to reformat (.bind(this)) are not used as for the documentation so I hope we can workaround this. If that's still not doable, the jsdoc-parse author being very responsive we could maybe get something working with him, cc @75lb ;) |
hi @vvo .. this is a big PR with a lot going on - what do you need me to look at? What is the question? |
Parsing things like https://github.com/algolia/instantsearch.js/pull/1435/files#diff-872aa81dff71f8151ef16821d4e665f4L22 seems not OK with jsdoc-parse@1. @bobylito will provide more context tomorrow if that's not sufficient. Thanks for jumping in! |
does the source code parse correctly with jsdoc? If not, your issue is with that tool as jsdoc-parse sits downstream.. |
import connect from './connect'; | ||
import CurrentFilters from './CurrentFilters'; | ||
import CurrentFiltersComponent from './CurrentFilters'; |
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 we say that any capitalized token is a Component otherwise it's just a function/HOC?
I am not sure suffixing Component everywhere brings more context/value to the code?
For sure we need to understand that some component are connected, some are not but do we actually need to express it everywhere?
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.
Interesting point! Previously we were constructing the widgets in an anonymous way. In every file we had Connected
as the variable name. Instead now, we are writing down the name of the widget / component as it is documented. So if you look in the code for Hits you will find matches in the index.js as well, the code is more explicit about the intention and, the @name is now inferred from the code.
Not sure, still I am curious, from reading the jsdoc-parse I cannot see anywhere we are actually requiring/using the jsdoc module. How does that works? Did you reimplement part of it. What I was proposing is that since we do not infere anything (it seems) from the code itself but we are just parsing jsDoc comments then there should be no need to actually try to parse the code. Just being able to extract a jsDoc block comment should be sufficient (in our case). And would allow us to keep our coding style. |
i wrote a simplistic description of how jsdoc2md works here. The raw jsdoc data is passed into jsdoc-parse, which transforms it into something more useful for passing into handlebars. jsdoc2md works downstream of jsdoc. If you only want to parse jsdoc comments (and not source code, as jsdoc does) then your best option is doctrine. |
There is some inference from the code: names and types.
This is part of stage-2, and basically we have this preset only to support this syntax. Can we work with that and move forward? (the only file being impacted is InstantSearch.js). We can also workaround that by using babel to process the files prior to using jsdoc-parse. Since this is only syntax sugar, that could work.
doctrine only works on extracted comments which adds yet another step... |
I cannot find where do we infer types from the code, can you detail?
If this allows us to keep the same syntax (Static, bindings) then that would be better yes. Mostly so that the PR is easier to read and so that we know we do not have to code in a particular way for the documentation generation to work. |
First step for the way we manage the documentation of the components and the connectors. I'm sure we'll find lots of stuff to add :) (I need to rebase or something :) )