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

Composable scaffolds #32

Open
ericelliott opened this issue Aug 15, 2015 · 27 comments
Open

Composable scaffolds #32

ericelliott opened this issue Aug 15, 2015 · 27 comments

Comments

@ericelliott
Copy link
Contributor

One of the primary reasons that Yeoman generators suck is that they include a ton of crap that most projects simply don't need.

It would be cool if ours was a bit different.

For instance, it would be really cool if our app package was modular enough that it would default to a recommended stack like react + redux, but also be capable of configuring react + cerebral.

It would also be cool if we could easily add relay to the mix, or swap out the router.

It would be great if we could figure out an easy way to compose scaffolds. I'm pretty sure this will have to come in the form of some predetermined directory layout... something like:

├── index.js
├── router
│   └── index.js
├── store
│   └── index.js
└── sync
    └── index.js

The index file could import them all and we could default to something simple and sensible and essentially render a "hello, world" view.

Thoughts?

@therealklanni
Copy link

What do you imagine the command would look like for this to be possible?

cf install react redux relay

?

@davegomez
Copy link
Contributor

I think both ways proposed by @therealklanni could work.

Using the CLI or with some config file that we could use with a simple cf install command.

@ericelliott
Copy link
Contributor Author

cf install react redux relay

Yes. That's exactly what I had in mind.

@nkbt
Copy link
Contributor

nkbt commented Aug 15, 2015

This could work out of box if all pieces are build with the same API in mind. On the other hand I do not clearly see how we can easily remove/add, for example, routing to the project. Though it is probably possible to make 2-3 modules with different routers, and choose one of them.

Similar to flux implementation. You could choose to use either vanilla flux, or redux, or fluxxor, or any one of 100500 other flux implementations of flux. But in this case they need to be properly wrapped to keep the same API as the rest of the app.

On high level I cannot see much value over old good npm, except some boilerplate-ish code that will glue all pieces together in a single working app. Which is an interesting technical challenge.

@nkbt
Copy link
Contributor

nkbt commented Aug 15, 2015

Ping @JedWatson

@halhenke
Copy link

Not sure if its quite the same idea you have in mind but i briefly flirted with brunch and one of the things I thought was kind of neat was the way they have a bunch of mini-generators with dependencies on other mini-generators - see here for an example:

https://github.com/exlee/brunch-on-asteroids/tree/master/generators

@ericelliott
Copy link
Contributor Author

Interesting. Thanks for the link. =)

@davegomez
Copy link
Contributor

Is there any scaffold already made to use it as an example to create another ones?

@ericelliott
Copy link
Contributor Author

@Hypercubed
Copy link

I want to say that I think this is an excellent (and ambitious) project. I will keep my eyes open for ways I can contribute.

Something I found troubling about yeoman is that after I find a generator that looks close to what I want I scaffold a project then customize (update dependencies, change some file structure, swap jshint for eslint, etc). Next time I start a similar project I either need to go through the same steps or fork my last project. What is the point of the generator if it is only used once? I might as well just fork a template.

It would be amazing if I could easily save my project changes back as a new scaffold template. Even better if it is made of composable scaffolds.
.

@halhenke
Copy link

Been having some thoughts about this today - specifically the idea of an ecosystem of small/composable/modular micro-generators which may have dependencies on one another. At any rate want to get it straight in my head and then would like to get @nkbt's feedback/thoughts. Not sure if what i'm imagining is feasible/worthwhile or if it would fit Cloverfield - ideally it would be as simple and flexible as possible though. Anyway - talk is cheap ;-) - will try to work on something.

@Hypercubed You raise an interesting idea - i guess ideally i would want a generator to be easy enough to understand/modify that you could customise it yourself. Otherwise you could persist some/all choices locally which would then become defaults I suppose. More than that would seem very difficult.

@nkbt
Copy link
Contributor

nkbt commented Sep 23, 2015

@halhenke for generator itself you should definitely look at cf-package. I am pretty sure it is simple enough to be taken as a base for others. Most of its code could be abstracted to a lean core, leaving only template and props file for a package itself.

First step to approach composable generators is cloverfield-tools/cf-package#23

I doubt all packages could be composed. You may have conflicting files/configs/options after all and automatically decide the way they are merged is non-trivial. To some degree that could be possible (like with package.json). But for many easier non-overlapping cases that should be OK.

@ericelliott
Copy link
Contributor Author

👍

@halhenke
Copy link

@nkbt Yeah I can definitely see that cf-package fits the Cloverfield goals. I guess what I am envisioning is something a bit different - as I understand it Cloverfield is primarily focussed on curation as a way of dealing with the "random crap"/discovery problem of Yeoman. I guess I'm thinking of something more low level that honestly might not be useful to Yeoman - or useful at all - (at this point I'm going back and forth on whether theres a really worthwhile idea in there or its all completely trivial/redundant).

Anyway so as not to derail things here too much might run some ideas past you later if thats OK...unless i decide the whole things is the result of drinking too much coffee ☕

@ericelliott
Copy link
Contributor Author

@halhenke I definitely want to modularize most of the pieces in cf-package. For instance, maybe you're working with an existing repo and you just want to add tape tests, it would be cool if you could just cf-install tape and get tape installed, a test dir added with a sample test, and a test script replaced in package.json.

There is definitely value in having some granular scaffolds for Cloverfield.

@nkbt
Copy link
Contributor

nkbt commented Sep 26, 2015

https://github.com/amwmedia/plop looks nice, worth checking

@ericelliott
Copy link
Contributor Author

Yeah, plop looks like a great base. Not a replacement for cf (I don't think it lets you add keys to an existing package.json, does it?) but it seems like we could replace a bunch of the code in cf-package with plop.

What do you think, @nkbt?

@nkbt
Copy link
Contributor

nkbt commented Sep 27, 2015

@ericelliott yes, that is exactly what I was thinking about. Did't find it before, otherwise would have used it. Pretty much ticks all the boxes.

But needs to be tried first, since there could be some design decision made not 100% compatible with cf.

@nkbt
Copy link
Contributor

nkbt commented Sep 27, 2015

PS: just in case, I have no personal attachment to the code and if some 3rd party tool is more appropriate - happy to scrap it.

@ericelliott
Copy link
Contributor Author

@nkbt If you'd like to take a crack at reimplementing cf-package with plop, I think that would be a great first step in the exploration. Up for it?

@halhenke
Copy link

@ericelliott @nkbt Plop looks very interersting - definitely a different approach then I had envisaged. Hadn't thought of modifying files as well as generating them for example.

At any rate as I was thinking more about it I decided it might be useful to try and use React itself as a tool to declare/compose scaffolds. Seems like it has a few built-in properties that would really help (re-using components, passing properties/variables to children, events to hook into etc). Then we could wrap/replace the render method to generate actual files, directories etc.

e.g. I'd envisage you could do something like this:

const contents = <div><h1>Welcome to my nightmare</h1></div>;
const deps = ['react', 'lodash', 'immutable'];
const devDeps = ['webpack', 'webpack-dev-server', 'react-hot-loader', 'jest', 'eslint'];
const nodePack = (
<Path name="src">
  <Path name="example">
    <NPMPackage name="generated" deps={deps} devDeps={devDeps}/>
    <File name="index.js" fileContents={contents} />
  </ Path>
</ Path>);

React.generate(nodePack, './');

And then have a CLI to configure/pass top level variables such as install path etc. Not really sure of the advantages/disadvantages of this approach (particularly the use of React) vs something like plop off the top of my head so am doing some playing around with it. But if you guys can see any obvious problems would love to hear about them (and also be sad to hear about them 😉)

@nkbt
Copy link
Contributor

nkbt commented Sep 27, 2015

@ericelliott I'll give it a try then.

@halhenke Though using React/JSX as a composition tool looks really appealing to me, I must say it adds additional complexity to the end-user. I'd try plop (to be honest it actually does "composition" in a way I imagined it for myself) and see how it goes.

@halhenke
Copy link

@nkbt Fair enough - I definitely don't want it to be a "gimmick" or something that makes things more complex rather than simpler or more powerful. And I haven't really made up my own mind yet how useful its going to be or if there are some sticking points that might make it fundamentally unsuited to the task. Will play around a bit more and if it seems to have merit will throw up a repo - might not fit Cloverfield & I don't want to derail the conversation any more than i have so will save further discussion for elsewhere.

@nkbt
Copy link
Contributor

nkbt commented Sep 27, 2015 via email

@ericelliott
Copy link
Contributor Author

Any progress on this, yet?

I'd love to be able to install isolated bits of functionality, such as tape tests, eslint, etc... individually as needed.

@jesselee34
Copy link

I've been reading through these threads and I'm thinking I might be able to take a crack at this. This would be the first time I've taken code from another project to use as a base. @ericelliott can you provide some pointers on the correct etiquette? Would a fork of plop be appropriate, or would I just make a copy of the source into a new repo?

@ericelliott
Copy link
Contributor Author

I would think you may be able to do this using plop as a dependency. I haven't looked into it very deeply, though.

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

7 participants