Skip to content
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

Function based code cannot be separated into logical groups #1

Open
skurger opened this issue Jan 12, 2017 · 10 comments
Open

Function based code cannot be separated into logical groups #1

skurger opened this issue Jan 12, 2017 · 10 comments

Comments

@skurger
Copy link

skurger commented Jan 12, 2017

Thanks for the invite and excited to see where this goes! Reposting from the previous forked repo of esdoc.

I use Redux to manage the state of my applications. There are actions associated with any state change and reducers that process those actions. Let's say that some UI component has 5 actions associated with it and one reducer file that may also contain 1 or more functions. As my library of actions and reducers grows the documentation keeps growing as well.

Esdoc currently dumps anything that isn't a class into one main page under the "esdoc/function" URL. A way to group functions in a file under a unique URL per group would go a long way in organizing code. This would make it very easy to browse the API available to a developer while only focusing on one set of functionality.

Example: A group of actions that manipulate the state of modal dialogs.

actions/modal.js


/**
 * @module modal-actions
 */

/**
 * Modal action object
 * @typedef {Object} ModalAction
 * @property {number} id Unique ID of the modal
 * @property {string} type The action type
 */


/**
 * Close a modal
 * @param  {String} modalId Closes a modal
 * @return {ModalAction}
 */
export function closeModal(modalId = '') {
	return {
		id: modalId,
		type: CLOSE_MODAL
	};
}

/**
 * Open a modal
 * @param  {String} modalId Opens a modal
 * @return {ModalAction}
 */
export function openModal(modalId = '') {
	return {
		id: modalId,
		type: OPEN_MODAL
	};
}

The 2 functions above would be grouped under a single page. I'm using the @module tag from jsdoc that provides the kind of grouping functionality I'm looking for.

Let me know if further explanation is needed and willing to test the changes if / when implemented.

@typhonrt
Copy link
Member

Excellent, glad to have you onboard!

Indeed, this is on the radar for an early refactor before public release. The good news is that the @module tag won't be needed as things are going to be reorganized to support all documentation for an entire ES6 module / file as a single group having a module / file overview page linking to the specific class / functions stored separately, etc. So no more single functions.html page!

@raveclassic
Copy link

raveclassic commented Jan 13, 2017

My 2 cents here - if we aim at supporting TS then there is a concept of a module or a namespace as well as plain es6 modules (files) and typedoc gracefully supports both modes of view: files and modules. I believe tjsdoc should have similar functionality. What do you think?

@typhonrt
Copy link
Member

That does indeed seem like something to take into consideration such that the TS left-hand navigation should have two modes, file based and TS namespace / modules. Not having worked with TS much can you nest modules? Ex:

module Animals 
{
   module Reptiles 
   {
      export class Lizard
      {
         constructor() {}
      }
   }
}

Or suppose Animals above was a namespace. Again from not having used TS is it possible to nest multiple namespace / module scopes?

If this SO discussion is correct it still looks like one needs to re-export multiple files to create a single importable target regardless of namespace / module usage in TS: http://stackoverflow.com/questions/31983209/using-namespace-spread-over-multiple-files-in-typescript

This can be taken into consideration with a dynamic left-hand navigation component. It should be plenty possible as my esdoc-plugin-dependency-graphs plugin outputs a data file which then can be viewed in many different ways, but that is due to JS and D3 doing the rendering.

In the long term I'd like to create a separate tjsdoc publisher module that generates a web app instead of static HTML files. The bulk just being raw data and all dynamic rendering.

@raveclassic
Copy link

raveclassic commented Jan 13, 2017

Nesting - of course. This is just the same as namespaces in C# or packages in Java.
But ts modules/namespaces are a terrible mess, especially when nested and combined with es6 module syntax.
All examples in official ts doc are written using new es6 module syntax but we should consider there is a large ts codebase which uses namespaces (aka internal modules) mostly as ambient declarations.

UPD: Historically all TS files were supposed to be compiled in one scope without any references between files (well, there was a <reference path=""/> tag). So namespaces with same name were merged (as expected).

UPD2: The key point is that when transpiling to JS, nested namespace and module structure is preserved as plain js object and it's important for js <-> ts interop.

@typhonrt
Copy link
Member

typhonrt commented Jan 13, 2017

But ts modules/namespaces are a terrible mess, especially when nested and combined with es6 module syntax.

Indeed, this is what I thought would be the case re: mess when doing just a cursory poking around. It seems like something like JSPM is definitely needed in this case to remap imports. I wonder if there is a tool out there that can dynamically create the independent re-export intermediary files then remap them to Animals, Animals.Reptiles, etc. Such that one can automatically do import * as Reptiles from 'Animals.Reptiles'; Seems possible, but tedious on the tool making.

Regardless of namescape / module support out of the gate the file based view w/ as complete as possible TS support for other language features will be valuable to finish first.

As an aside I've been able to rewrite the AbstractDoc doc tag processing / dispatching so that it is no longer hard coded or order dependent as far as invocation goes. For the TS version it will just have to take into account module_file, module, and namespace for tag generation.

@raveclassic
Copy link

raveclassic commented Jan 13, 2017

There's no direct interop between exporting namespaces from different files and importing them in one file with import * es6 syntax because, well, namespace is not a file. It is a way to group things in a say "project" where all files are bundled together in one scope (old way to build ts projects). So if you export a namespace in one file then it is immediately available in all other files. This is the way TS modules initially worked and it can't (afaics) be mixed with es6 import * syntax.

Actually the more I dive into this interop the more I think that supporting such cases may be out of scope because the goal is ES and, well, its module system is based on files, not "virtual" namespaces.
The only way of supporting namespaces/modules/jsdoc-module-tags in a file that I see is treating them as nested objects (submodules) without possibility to import * because when transpiled they actually are nested objects.

For the TS version it will just have to take into account module_file, module, and namespace for tag generation.

Sounds awesome!

@typhonrt
Copy link
Member

typhonrt commented Jan 13, 2017

Yeah... Definitely aware there is no direct interop by default. This thread is getting slightly sidetracked with the TS talk, but what I was mentioning as probably possible is for an intermediary tool to automatically create the re-export files w/ the namespace / module configuration (doesn't have to be directory based just a ./virtual/animals-reptile.js (or ts?) file created then have JSPM remap those files to Animals.Reptiles, etc and other virtual namespace / module scopes for import. So definitely an intermediary step, but with automatic tooling; which is also well beyond the scope of TJSDoc. ;P

TJSDoc could still show the TS namespace / module groupings regardless if that intermediary tooling was available. Lots to do before getting this alternate TS view working though.

@typhonrt
Copy link
Member

As a curiosity though I'd like to ask you opinion @raveclassic about the usefulness of viewing the TS virtual namespace / module hierarchy. In regard to static HTML generation it would be a bear to output discrete resources for the two alternate views. Would it be adequate or good enough for this TS variation just to be for the left-hand navigation such that it would only provide an alternate navigation view with the virtual layout, but if you clicked on a function or class it would take you to the ES module / file based generated HTML resource shared between both the file view and the virtual view? If this was adequate then this alleviates the trouble of having to generate static HTML pages with both types of groupings and just makes it a feature of the left-hand navigation view for showing an alternate layout which is much easier to accomplish.

@raveclassic
Copy link

raveclassic commented Jan 13, 2017

I don't see any reason for implementing such intermediary generator as long as import * is just an invalid way of importing namespaces. You can achieve this functionality but only because of interop with actual js after transpilation. Well, agree this is all going offtopic :)

TJSDoc could still show the TS namespace / module groupings regardless if that intermediary tooling was available
In regard to static HTML generation it would be a bear to output discrete resources for the two alternate views. Would it be adequate or good enough for this TS variation just to be for the left-hand navigation such that it would only provide an alternate navigation view with the virtual layout, but if you clicked on a function or class it would take you to the ES module / file based generated HTML resource shared between both the file view and the virtual view?

I think it's fine for now to leave namespaces only in subnavigation under current file in the nav sidebar.
As long as tjsdoc will produce raw generic data (es module can be just a file with zero submodules, when ts module can be nested) it will be easy to implement different publishers for all needs.

@typhonrt
Copy link
Member

typhonrt commented Jan 13, 2017

Sounds good. As another aside / implementation detail I'm modifying how the publisher is loaded and a new config parameter publisher will be exposed and by default it will target the static html publishing module (eventually this will be a standalone NPM module; nice thing is that in the meantime the plugin system can load local files as mock modules too). Want to replace the publisher then just add the publisher config parameter pointing to another NPM module. IE it won't be necessary to programatically invoke TJSDoc.generate() with a publisher instance as is the case w/ ESDoc.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants