vuejs / vue

This is the repo for Vue 2. For Vue 3, go to https://github.com/vuejs/core
http://v2.vuejs.org
MIT License
207.46k stars 33.65k forks source link

Establish a standard way to document component and its props #7186

Open octref opened 6 years ago

octref commented 6 years ago

What problem does this feature solve?

https://github.com/vuejs/vetur/issues/276

Currently, Vetur offers auto-completion & hover info for custom components defined in ElementUI, OnsenUI and Bootstrap-Vue. However, hand-maintaining such json files seem to be a lot of work. Also not co-locating the doc and the component definition can make updating component challenging.

Helper-json repos at:

This feature makes it possible to write the doc in the SFC / js component file, and auto-generate a helper json that can be used for enhancing editing experience or auto-generating API / doc website.

What does the proposed API look like?

Two more optional attributes on the default export:

export default {
  name: 'v-card',
  description: 'A card component',
  props: ['width', 'height'],
  propsDescription: [
    'width of the rendered card component',
    'height of the rendered card component'
  ]
}

I was thinking maybe using a custom block for it, but then that only applies to SFC, not js components. jsdoc might be another option. Other ideas welcome.

Another idea is similar to the typings in package.json, have a vueTypings for component libraries. It'll point to the generated helper-json file and editors could pick it up to enhance editing experience.

/cc

@Leopoldthecoder for ElementUI @masahirotanaka for OnsenUI @pi0 for Bootstrap-Vue @rstoenescu for Quasar @johnleider for Vuetify

Would you be interested in using this feature in the Vue component libraries that you are maintaining? Would you be interested in helping spec'ing a format for the generated json file and the editing experiences that should be enabled by using that file?

posva commented 6 years ago

Wouldn't it be more interesting to add description to the props:

props: {
     width: {
        type: Number,
         description: 'Width of the modal'
    }
}

Libs usually use the object syntax already

As long as it can be stripped off from build productions, I think it could be nice to add something like this. But maybe prepending those attributes with a special character could be even better, something like '#description' or $description to clearly make the distinction

yyx990803 commented 6 years ago

Does this have to be part of the component options / API? It seems they don't serve any particular purpose for Vue's own runtime behavior. In that case, would a comment-based syntax be more reasonable (as it is stripped by default)?

Using a component option would require extra toolchain changes to properly strip them.

posva commented 6 years ago

Is it possible to read comments with the language server? 😮

pi0 commented 6 years ago

Hey. For specific BootstrapVue we needed component typings from a long time ago. The first iteration was exactly using component's runtime instance to extract props and auto-generating documentation. Here is componentdoc.vue implementation.

PROS:

CONS:

So we added a custom meta descriptor for components inside package.json which can be used for making a full set of docs and hintings. (Example)

Both of above methods are both used for our nuxt based docs and also for generate-vetur-helpers.js (Written by @alexsasharegan)

Maybe we can unify metadata structure which is used by BV, Onesen and Vuetify and hand-craft or auto-generate meta for any component library in either package.json or vue.json file.

This way, just like any other part of Vue's ecosystem tooling can be delegated to library authors. We may also provide some helpers making the process easier and not forcing to use specific syntax like JSDocs.

(vue-xxx/package.json or vue-xxx/vue.json)

{
  "vue": {
     "library": true,
     "components": [
         {
             "name": "b-table" // Use for hinting of <b-table> tags
             "props": [  
                 {
                   name: "title",
                   type: "Boolean",
                   description: "Table title"
                 }
             ],
          }
     ],
     directives: [
       // ....
     ]
  }
}

/CC @tmorehouse @egoist @mosinve @alexsasharegan

pi0 commented 6 years ago

Something cool I've discovered so far is Project polymer's component documentation spec.

They have a nice CLI which analyzes components JSDocs and extracting meta json:

polymer analyze > analysis.json

Then using a similar component like our ComponentDoc we can use iron-component-page to visually render the docs. or exporting Via package.json for vue-language-server usage.

Akryum commented 6 years ago

It would be great t have vue-language-server parse the JSDoc inside the components 😄

chrisvfritz commented 6 years ago

@yyx990803

Does this have to be part of the component options / API? It seems they don't serve any particular purpose for Vue's own runtime behavior. In that case, would a comment-based syntax be more reasonable (as it is stripped by default)?

I disagree. I can imagine a lot of cases where Vue's warnings and devtools could be improved by this extra information. Here are some examples.

Using a component option would require extra toolchain changes to properly strip them.

Yes, but I think the changes would be quite simple, since we're already manipulating the options exported from SFCs. It's possible there's a complexity I'm not realizing though, so please correct me if that's the case.


@pi0 I'd really like to avoid having to manage a separate types file, as I find these can fall out of date very quickly when their accuracy is not enforced by a compiler. Plus, remembering to check another file every time you want to update a component is pretty significant cognitive overhead.

yyx990803 commented 6 years ago

@chrisvfritz SFCs only manipulate the options at runtime, so all the big description strings will be included in the bundle and cannot be minified. They can only be dropped with a special babel plugin or hacked buble transform.

octref commented 6 years ago

@posva

Is it possible to read comments with the language server? 😮

It won't be easy, but it's possible, since TypeScript server supports analysis of JSDoc.

@pi0

So we added a custom meta descriptor for components inside package.json which can be used for making a full set of docs and hintings.

I agree with @chrisvfritz -- one of the strength of Vue SFC is a sensible way of organizing related information by colocating html/css/js. It'd be very un-vue-like to put this component specific information to some centralized place.

The idea is to make it possible to write components that's self-documenting, in the same spirit of JSDoc / JavaDoc / etc. This also helps reading Vue libraries' source code.

https://www.polymer-project.org/2.0/docs/tools/documentation

👍 This is something we can look into & learn from.

@yyx990803

Does this have to be part of the component options / API? It seems they don't serve any particular purpose for Vue's own runtime behavior. In that case, would a comment-based syntax be more reasonable (as it is stripped by default)?

Doesn't have to be, and I agree it doesn't help runtime and would be a bloat for code size. It has to be compiled away at build time. I think it's achievable through babel plugin though.

However, after thinking through this, I think JSDoc might be a better approach. Either way, I can't have the runtime info easily so I need to parse the script myself and find the descriptions. The parser can be reused in the vue-template-compiler 2.0 redesign: https://github.com/vuejs/vue-component-compiler/issues/28#issuecomment-333139601, where the descriptions go into descriptor.metadata or descriptor.descriptions.

Another idea is to make this a custom block in SFC like so (chose yaml since it looks cleanest)

<script>
export default {
  name: 'v-card',
  props: ['width', 'height']
}
</script>

<description>
description: A card component
props:
  width: width of the rendered card component
  height: height of the rendered card component
</description>

For libraries that's using js components, they can convert to this format by putting their js file into a <script> tag and the extra description info into this custom tag. It can be compiled away in compile time. This also makes it super easy to extract the description data.


As I mentioned this info can be used by Vetur, component doc generator, etc for better DX, but it can go beyond that. One example is ElementUI's subtags:

https://github.com/ElementUI/element-helper-json/blob/master/element-tags.json#L4

{
  "el-row": {
    "attributes": ["gutter", "type", "justify", "align", "tag"],
    "subtags": ["el-col"],
    "description": "A row in grid system"
  }
}

We can just use this info to enhance eslint-plugin-vue to warn the user, but we can do runtime check too.

mosinve commented 6 years ago

I like the idea with custom block, as this pattern already used by some VueJS-ecosystem libraries, like @kazupon vue-i18n . And we sure can easily strip this block away at compile time.

demsking commented 6 years ago

I wrote @vuedoc/parser to generate SFC doc.

It supports:

Sample:

<template>
  <label>
    <input :disabled="disabled" type="text" v-model="checkbox">
    <!-- Default slot comment -->
    <slot></slot>
    <!-- Use this slot to set the checkbox label -->
    <slot name="label">Unamed checkbox</slot>
  </label>
</template>

<script>
/**
 * A simple checkbox component
 * 
 * @author Sébastien
 */
export default {
  name: 'checkbox',
  props: {
    /**
     * The checkbox model
     * @model
     */
    value: {
      type: Array,
      required: true
    },

    /**
     * Initial checkbox value
     */
    checked: {
      type: Boolean,
      default: true
    }
  },
  data () {
    return {
      initialValue: null
    }
  },
  computed: {
    id () {
      return `checkbox-${this.initialValue}`
    }
  },
  created () {
    /**
     * Emit when the component has been loaded
     */
    this.$emit('loaded')
  },
  methods: {
    /**
     * Check the checbox
     */
    check () {
      /**
       * Event with identifier name
       */
      this.$emit('check', true)
    }
}
</script>

Will generate something like:

{
  "header": [
    {
      "entry": {
        "name": "checkbox" // The component name
      },

      // The component description
      "comments": [
        "A simple checkbox component"
      ],

      // Attached keywords
      keywords: [
        { name: "author", "description": "Sébastien" }
      ]
    }
  ],
  "props": [
    {
      "entry": {
        "v-model": {
          "type": "Array",
          "required": true
        }
      },
      "comments": [
        "The checbox model"
      ]
    },
    {
      "entry": {
        "checked": {
          "type": "Boolean",
          "default": true
        }
      },
      "comments": [
        "Initial checbox value"
      ]
    }
  ],
  "data": [
    {
      "visibility": "public",
      "description": null,
      "keywords": [],
      "value": null,
      "name": "initialValue"
    }
  ],
  "computed": [
    {
      "visibility": "public",
      "description": null,
      "keywords": [],
      "value": [Object],
      "name": "id",
      "dependencies": [
        "initialValue"
      ]
    }
  ],
  "slots": [
    {
      "name": "label",
      "comments": [
        "Use this slot to set the checkbox label"
      ]
    }
  ],
  "events": [
    {
      "name": "loaded",
      "comments": [
        "Emited when the component has been loaded"
      ]
    },
    {
      "name": "check",
      "comments": [
        "Event with identifier name"
      ]
    }
  ],
  "methods": [
    {
      "entry": {
        "check": {
          "type": "FunctionExpression"
        }
      },
      "comments": [
        "Check the checbox"
      ]
    }
  ]
}
chrisvfritz commented 6 years ago

@yyx990803 Thanks for clarifying. 🙂 I just did a little research to see how difficult a Babel plugin would be and much to my amazement, I accidentally created a working proof-of-concept! 😄 I'm definitely not a Babel expert, so there could be issues with it, but it seemed to work on the 2 codebases I just tested it against without breaking anything. It could even be expanded to strip out other properties not needed in production, like required and validator for props.

Does this change your thoughts on feasibility at all?

chrisvfritz commented 6 years ago

However, after thinking through this, I think JSDoc might be a better approach. Either way, I can't have the runtime info easily so I need to parse the script myself and find the descriptions. The parser can be reused in the vue-template-compiler 2.0 redesign: vuejs/vue-component-compiler#28 (comment), where the descriptions go into descriptor.metadata or descriptor.descriptions.

@octref Just saw this comment. When you say you can't access this information easily, how difficult are you thinking it would be and is there any way I could help explore possibilities? I ask, because I'd personally prefer to avoid JSDoc. We already have some meta information as properties (like component name and prop types) and with comments, we'd lose the ability to use additional information in the Vue's warnings or devtools.

As for the custom block, it would solve the 2nd problem assuming Vue's template compiler could parse it into a JavaScript object, but there's still the issue of component meta information being fragmented (some included as a component option, some in a new custom tag). Some other things that bother me about it:

octref commented 6 years ago

@chrisvfritz I was thinking along the line of using TypeScript to extract the data and use it to supplement the html completion, but actually it doesn't have to be this way.

We can:

  1. Have one independent tool that takes commands such as vue-component-doc ./src/**/*.vue
  2. The tool generates a manifest file
  3. User edit vue files to add documentation
  4. manifest file is regenerated
  5. Vetur reloads the manifest file to enhance html editing

Task 1 and 2 should exist independent of Vetur, so they can also be used for other tools.

tmorehouse commented 6 years ago

Might want to include non SFC components and functional components (i.e. .js files)

chrisvfritz commented 6 years ago

@octref I like the idea of tooling to create a manifest file! Then Vetur, eslint-plugin-vue, and other tooling would never have to worry about parsing that information themselves - but we still have it available for Vue's warnings and devtools. Best of all worlds. 🙂

Having a separate tool like vue-component-doc might have some issues though, since having these properties in JavaScript means they could be runtime dependent (e.g. description: myDynamicDescription()). To solve this problem, I wonder if vue-loader could build a manifest file (or perhaps a manifest file per component) at runtime? If we stored these manifest files in a standardized location, then Vetur and other tools would be able to check that location for extra information. As an added bonus, the parsing would be agnostic to syntax (e.g. Babel, TypeScript, CoffeeScript, etc). @yyx990803 Is this remotely possible? 😄 What are your thoughts?

chrisvfritz commented 6 years ago

@tmorehouse It could be tricky for the Babel plugin to detect non-SFC Vue components, since files unrelated to Vue could export similarly-shaped JS objects. Also, functional components can now exist as .vue files as well, so there isn't really a reason not to use SFCs for any kind of component if you're using a build system (which you would be, if you're expecting a Babel plugin to strip out these properties in production).

tmorehouse commented 6 years ago

When generating ES style builds (transpiling to a es directory module structure) there is currently no vue-template compiler that will handle this situation. One shouldn't conclude that every one is using SFCs.

We ran into this issue when generating ES module build for Bootstrap-Vue (to allow user's to have better tree shaking), and .vue files were causing SSR errors, due to differences in vue-loader options. So we converted to using render functions instead of .vue files

pi0 commented 6 years ago

@tmorehouse According to @chrisvfritz idea we can still have both ES style builds and SFCs as the source with custom props. And stripping/extracting those comments using babel during build into meta.json.

pi0 commented 6 years ago

Just as a summary to all of the nice comments until now, Something I think all of us agree on it is that we need a final manifest (Something like @demsking suggested) which can be used for both documentation and IDE hintings. The big questions are where to declare typings and how to extract it. SFCs seems the best place and we can put it inside:

And we've got some possible methods for extracting this manifest:

But IMO if we enforce any combination of above methods, we are still forcing a toolchain and methodology for this task. What if we just agree on a standard manifest structure and let developers make and choose the best tooling? We can then recommend and add support for the best method which is probably SFCs + vue-loader or something else ...

PS: Sorry if talking a lot. I'm just little excited about this enhancement 😆

HerringtonDarkholme commented 6 years ago

I want to add some observations from Vetur's report.

Most users use third library as global plugin. E.g. element-ui/bootstrap-vue provide global components. It would be hard for Vue-language-server to find all components in a third lib if we don't specify library component manifest. So declaration extraction is also crucial in the spec.

Another problem is how to ship component library. We should support shipping component in SFC format as well as compiled JS.

@pi0 has already done an awesome summary. Thanks!

znck commented 6 years ago

Another problem is how to ship component library. We should support shipping component in SFC format as well as compiled JS.

SFC should be preferred over JS as component render functions are built in two ways now – a javascript function (in browser build) and string concatenation (in SSR build).


I'm experimenting with a utility library to define prop validation rules. I'm shimming all utility functions for the production build, then using prepack, extra meta is dropped. I think similar techniques can be used for documentation. Maybe a babel plugin can analyze AST and export meta at compile time.

samayo commented 6 years ago

I agree with Evan this does not seem to serve any particular purpose. If you want to allow this feature however I like @pi0 idea of adding it inside the prop

leopiccionia commented 6 years ago

Some time ago, I was interested in creating a Vetur integration with Quasar framework by @rstoenescu (which I delayed as it approaches 0.15 and 1.0). As Quasar is deliberately huge, I toyed a very simple JS-to-Vetur-like JSON converter to make things more sane.

From this (brief) experience, my two cents is that, if the community is going to settle on the custom block approach, JS (e.g. export default some object + some import custom logic) seems like a better alternative to structured-text formats (like YAML or JSDoc), due to some use cases where it'll avoid duplication, thus improving maintainability, like the following:

Disconsider this message if this is doable otherwise and I'm missing something.

geni94 commented 6 years ago

One can also use propdocs which presents a pretty neat (although maybe not original) way to write documentation for Vue components. You can add descriptions, notes (even explanatory code), flags, etc. as props and even render this documentation as a separate component.

octref commented 5 years ago

I made a proposal: https://github.com/octref/vuetypes. Feedback welcome!

My proposal is only about the "JSON format" and the "Editor Behavior" part. I don't know how each library is building the current helper json files for Vetur, so I hope I can get some feedback from @alexsasharegan @rstoenescu @asial-matagawa @jtommy @QingWei-Li @nekosaur.

Also, would any of you be interested in collaborating with me to build the JSON of this new format for your library? We can add documentation to your library's source code & work on the tool to extract the metadata into a JSON. I can do most of the work, but I probably would need help from the library authors.

There are still open questions as to where & how to author the data. @leopiccionia has a point: If 10 components all have the width attribute, it feels messy to have 10 descriptions scattered in 10 Vue files.

alexsasharegan commented 5 years ago

I see this thread mentioned for continuing the proposal discussion. Is this where we want to comment, or should we encourage issues to be raised on the proposal repo?

octref commented 5 years ago

There are 3 things:

  1. How / Where to write the typing data in source code
  2. How to store & distribute the data
  3. What the data should look like & what editor should do based on the data

For 1, continue the discussion here. For 2/3, open issues at https://github.com/octref/vuetypes,

alexsasharegan commented 5 years ago

Regarding How / Where to write the typing data, I'm in favor of the first way the proposal illustrates where to put typing data:

Put it in the NPM module you are publishing, and add a key vueTypes that points to the path of the file. Benefit is the JSON always has the right version.

In effect, this just following the existing behavior of things like main, module, and types. Familiarity is good, and I haven't seen any side-effects to this approach.

A package.json approach also means library authors can use build-time scripting to generate an up-to-date set of component definitions. There are no permissions to manage for publishing apart from what is required for publishing a library in general.

The second option listed is:

Publish it a VerilyTyped, which can automatically publish it to vuetypes. (I don't know if this is worth the hassle)

The only benefit to a separate repository (not mutually exclusive to a package.json distribution) is that it allows community members to produce component defs for libraries that don't have them available. This is definitely valuable, but far less pressing.

The relationship between the two distribution methods is exactly what we see already in the typescript community with embedded library definitions and community-contributed definitions to DefinitelyTyped. I think this is a good balance, but embedded publishing is the primary concern and a community registry a secondary one.

octref commented 5 years ago

@alexsasharegan That is about topic 2. I should have made it more explicit — topic 1 is how / where to write the data in your source code (JSDocs, fields of default export, custom block, etc).

alexsasharegan commented 5 years ago

Ah, my bad. Should I move my comment to proposal repo then? I don't mind.

Zenser commented 5 years ago

I like jsDoc or TS. Here is the reason:

  1. Use jsDoc don't break the code.
  2. It has been dev long time.

Use props seem to be easy, but i think it isn't a good design for vue.

piotrtomiak commented 4 years ago

Hi all! Based on ideas around a format for vue.js components metadata (@octref's vue-types, bootstrap-vue, quasar and vuetify metadata), at JetBrains we've came up with web-types, which are supposed to be a generic format for any web components framework (https://github.com/JetBrains/web-types), but for now is focused on Vue.js only. IDE developer can provide support for tags and attributes completion/documentation only, or, for a particular framework, support more advanced features like slots, events, etc. The format is still under development but a support for Vue.js with it has been added to the latest WebStorm 2019.2. The web-types JSON might be published under @web-types on NPM, or preferably included with the package. So far we have published web-types for vuetify, bootstrap-vue, quasar and vue itself based on our generator, which tries to extract as much data as possible from the published package (source in the repository). We are waiting for PRs to improve the format, so that it covers needs of every Vue.js library. If you are a library developer, please have a look at web-types repository and let's cooperate on improving the format and integrating web-types JSON into your library build.

dflock commented 4 years ago

I just wanted to point out that Vue Styleguidist also extracts this sort of information from Vue components, as already has a tool, called vue-docgen-api to do the extraction:

vue-docgen-api is a toolbox to help extracting information from Vue components, and generate documentation from it. Use @babel/parser to parse the code and analyze the contents of the component extracting methods, props events and slots. The output is a JavaScript object.

Perhaps @elevatebart has some input to this discussion?

elevatebart commented 4 years ago

Hey @dflock, you are right, vue-docgen-api has a standardized format for this kind of documentation. It is not the only one, but it has the advantage of using JSDoc format.

Check out this article on vue-comunity to know more possible documentation engines.

I will be working soon with @shilman on storybook docs to base the automated documentation of vuejs components on the vue-docgen-api. We could see about adopting other formats in the future if it feels necessary.

I hope to hear from this soon as @octref is right, it would be great to know the recommended way to document components.

elevatebart commented 4 years ago

Additionally, vue-docgen-api and @demsking parser @vuedoc/parser are both using about the same syntax loosely based on JSDoc. So there is that ;-).

octref commented 4 years ago

@elevatebart vue-docgen-api seems pretty good. Would you be interested in working together to define a spec / JSON format?

Meanwhile I'm also working on https://github.com/microsoft/vscode-custom-data that allows you to declaratively define data to enhance HTML/CSS language servers. I think for Vue, there would be two different specs for two different use cases:

elevatebart commented 4 years ago

@octref I would absolutely love to.

Do you know the best way to document this specification?

It would be a great opportunity to document what docgen is returning now. It would also allow us to check for inconsistencies.

I have been preparing the next major version of the ecosystem for a few months now. I am waiting for Vue 3.0 beta to launch. I would like to avoid my users to have to upgrade twice. We could piggyback on this new release to document and, if necessary, fix the API.

Please reach me on vue-land at ElevateBart#1057

piotrtomiak commented 4 years ago

@elevatebart @dflock @octref Could you please elaborate what do you find missing in web-types format? The format is designed so that any IDE (or tool) can take advantage of it, including VSCode. With the recent changes it seems to be pretty complete. It has support for typescript types only at the moment, but there is no problem with adding JSDoc types to it. I've chosen typescript, because many Vue libraries already uses TS. One of the things I was looking at when designing the format was vue-docgen-api, so IMHO web-types is it's superset (with exclusion of some very specific JSDoc elements).

@octref The format is also designed in such a way that any component library (like Web Components) could use it, thus allowing IDEs to have a generic support for content assist within HTML. I've looked at VSCode solutions for supporting libraries and each of them requires installing some plugin. Having a common format acceptable by all IDEs, which can be shipped within the library, seems to me a more efficient way to go.

octref commented 4 years ago

My feedback for web-types is:

VSCode solutions for supporting libraries and each of them requires installing some plugin

This was not the case until Jan 2019 when we bundled custom data format into VS Code, and we marked it as stable last month.

piotrtomiak commented 4 years ago

There's no clean separation between metadata specific to Vue and the data format needed to drive LSP methods (such as completion, hover).

The format of data is designed in a way to satisfy not only IDE, but other tooling as well, such as documentation generators. I have used several existing formats, like vue-docgen-api, quasar docs, VSCode formats, etc. and created something, which should satisfy most needs and enclose all of the related information (tags, attributes, components, directives, etc.) in a single file.

As far as Vue specific items are concerned in the format, all of such are prefixed with "vue" in the metadata. So there is a lot of generic information available. I.e. slots are generic concept present in Web Components, or Angular; however scopedSlots with types, etc. are specific to Vue and thus prefixed.

There is some mapping required to extract list of available tags, or attributes; or to provide list of available scopes, because format is data oriented, not IDE feature oriented.

It's unclear to me what data is used in what editor features, and it seems all the features are Jetbrains product specific.

Nothing in the format is JetBrains specific. It is up to IDE developer to transform data and fetch it into IDE specific feature like LSP. You can check how it's bootstrapped in WebStorm Vue plugin here https://github.com/JetBrains/intellij-plugins/blob/2617aca68c9086d07a2927df9ce41d0a95a1c78a/vuejs/src/org/jetbrains/vuejs/model/webtypes/VueWebTypesEntitiesContainer.kt

elevatebart commented 4 years ago

@piotrtomiak you got me curious.

Do you have an example of what a documented Vue components code looks like? Can it document both the <template> and the <script> part? Google is not being very cooperative. It's giving me the 12 different types of websites when I search for web-types.

Additionally, is it implemented today in any other IDE than in JetBrains?

elevatebart commented 4 years ago

I have found that it is harder to maintain the documentation of a component in a separate JSON file than in the components code itself. It can not only be updated more quickly if the feature changes but also can help an onboarding developer understand the objective of the documented function.

I just opened the link to web-types and it seems that for each library, someone had to create the JSON files describing the library.

Did I understand it correctly?

tmorehouse commented 4 years ago

On would use a script to generate the JSON file (preferably), based on information pulled out from the library (and possibly other meta files).

With source code JSDOC, one would need to pull that info out into some file during build. For component definitions, the actual component definition most likely wouldn't have any description fields for props (as that would greatly bloat the compiled component size with text that is not used at runtime)

elevatebart commented 4 years ago

@tmorehouse the JSON files would be generated then, that makes total sense.

I do not think it does not answer the issue itself though: establish a standard way to document a component. I believe the question to be more about authoring (writing the code of the) documentation.

About the description field of the prop, I agree. The dev documentation should not be available for end users in production. It would needlessly bloat the final package. The use of HTML comments and JSDoc is preferable.

piotrtomiak commented 4 years ago

@elevatebart I think there are two sides to the problem. One is documenting the source code (and I am 100% with you that code should be self documented) and the other is sharing documentation of a compiled library with others. As a tooling author I am more interested in the latter and that's what web-types format aims on providing solution for. Having a common metadata interchange format allows various source code documentation styles, which by their dedicated tooling are compiled into common format and than pulled by various other tools like web documentation creators, validators or IDEs.

elevatebart commented 4 years ago

Thank you @piotrtomiak, I completely missed this part of the subject. Since the web-types files would be generated, what script would generate it? Does an NPM package that compiles web-types already exist? If it does, do you have an example of the conventions it is using in the sources?

I cannot help much on the tooling standard as I am not supporting any IDE myself.

piotrtomiak commented 4 years ago

@elevatebart As far as I know, there is no standard ways for documenting source code and every library provider is writing their own generator at the moment. Just 2 weeks ago quasar has merged PR to include web-types (https://github.com/quasarframework/quasar/pull/4749) and the feature should be released soon (dev branch was merged yesterday). Bootstrap-vue and vuetify have opened PRs to generate web-types. On my side I've written a generic generator which extracts information during runtime and combines it with static code analysis (https://github.com/JetBrains/web-types/tree/master/scripts/vue), which is used for extracting web-types for older versions of libraries already published on NPM. There are still some missing pieces of information in the format (e.g. https://github.com/JetBrains/web-types/issues/7) and thanks to reports from the community the format is being improved.

Some of WebStorm users are surprisingly generating web-types for their own source files to have a better code completion when working with their own components.

I am interested on working to support web-types output format for whatever tool will support the standard Vue components source code documentation.

mesqueeb commented 4 years ago

Just my humble opinion, but since JSDoc already has ways to generate documentation from comments, I want to experiment just writing JSDoc style comments and then worry about having that comment show up in VSCode later.

My question is, does anyone have a recommended way, or ever experiment with prop documentation extraction, if your props has JSDoc comments? ↓

export default {
  props: {
    /**
     * The state you want the component to have. Can be 'on' or 'off'.
     * @type {'on' | 'off'}
     */
    state: {
      type: String,
    }
  }
}

I'd love to be able to generate some docs based on the above!

elevatebart commented 4 years ago

@mesqueeb have you looked into vue-styleguidist. I believe it does all you want... and more.

Https://vue-styleguidist.github.io