ericmdantas / simple-yo

MIT License
0 stars 0 forks source link

Structure #1

Open ericmdantas opened 8 years ago

ericmdantas commented 8 years ago

@georgeedwards I'll update it later today, but feel free to fork this.

ericmdantas commented 8 years ago

@georgeedwards, alright, I removed all the noise and only let the important stuff, here's how it goes:

app/index.js is the entry point for yeoman

That means everything else will have to be linked there to be called.

We start off extending our main generator class with Yeoman Generator, see https://github.com/ericmdantas/simple-yo/blob/master/app/index.js#L7 and https://github.com/ericmdantas/simple-yo/blob/master/app/index.js#L9 - that'll give us all the base API to copy files, directories and other public stuff, but it's mostly copying.

methods are called sequentially

That means that if I have something like:

class X {
  doIt1() {}
  doIt2() {}
  doIt3() {}  
} 

It'll be called as doIt1, doIt2 and doIt3, respectively. That's good to know because some bugs happen when you depend on a certain order to be called - it's rare, but happens sometimes.

log()

https://github.com/ericmdantas/simple-yo/blob/master/app/index.js#L12 will show the yeoman logo with the message and nothing else, it'll skip to the next method, which is prompting().

prompting()

https://github.com/ericmdantas/simple-yo/blob/master/app/index.js#L16 This is where the question is shown, type is default for "input", where the user has to type something. We use a default string to help the user to know what he has to do.

When the user chooses, we save the result in a prop in the generator instance, in this case, this.myName.

writing()

https://github.com/ericmdantas/simple-yo/blob/master/app/index.js#L31 I guess this can the called the core of yeoman generators - where files and folders are copied left and right, with this and that parameter.

This is how it works: yeoman knows you're in the app folder. It's kinda obligatory that such folder have a template folder inside of it. Everything that has to be copied left and right should be inside this template folder. In this generator case, it's a simple dummyfile.txt.

Having said that, we run this.template with the following params: filePath, destinationPath and options. It's pretty straight forward, templatePath will be the path to the file inside your template folder and the destinationPath is where such file will be created, by default it's in the root of your app. Lastly, the options param is used to pass stuff to such file. In our case, we're passing the name the user chose to the dummyfile.txt and we're putting the info there somewhere, see: https://github.com/ericmdantas/simple-yo/blob/master/app/templates/dummyfile.txt#L1.

install()

https://github.com/ericmdantas/simple-yo/blob/master/app/index.js#L35

This is responsible for installing the deps in package.json and bower.json in the user computer. It's the last thing run.

testing

There are different ways to test stuff with yeoman. I usually use two: Acceptance and unit.

Acceptance tests will take care of file creations, it'll check if paths and extensions are correct and such things. It's pretty straight forward, see here: https://github.com/ericmdantas/simple-yo/blob/master/test/app.js#L6.

Unit tests are much easier, it's what you're used to, really - import, mock and assert.


I guess that's the core idea, let me know if I made myself clear.

georgeedwards commented 8 years ago

Thanks so much for this. It is making much more sense now - thanks! I am just trying to link through to the original generator, where is sayHello() defined from the index.js?

georgeedwards commented 8 years ago

@ericmdantas Oh I think I have found it, are they used from the subcomponent generators?

ericmdantas commented 8 years ago

@georgeedwards not really.

What happens in the sayHello() method is the following:

First, I create a property called generator and instantiate a class called MainGenerator. https://github.com/ericmdantas/generator-ng-fullstack/blob/master/app/index.js#L12

That decouples yeoman way of handling all the stuff and my code - it makes things incredibly easier to test, mock, etc.

So, everything you see as this.generator.something() inside this app/index.js file is based on that MainGenerator class.

And when you go to _ng/full/generator.js, the constructor does the following: https://github.com/ericmdantas/generator-ng-fullstack/blob/master/_ng/full/generator.js#L12, which is simply: "Give me this context - which is the yeoman generator - and assign it to wrapper", it could be any name, but wrapper made sense.

So, all the methods you'll see in app/index.js are inside _ng/full/generator.js, as you can see - sayHello(), writing(), install(), etc.

That makes the yeoman layer incredibly thin and gives me all the power to control the behavior of the application, be it on tests or anything else.

ericmdantas commented 8 years ago

@georgeedwards same will happen with component/index.js - the only difference being it's not gonna use the MainGenerator class, it'll use the class responsible to generate the stuff for components.

https://github.com/ericmdantas/generator-ng-fullstack/blob/master/component/index.js#L10

georgeedwards commented 8 years ago

@ericmdantas Thanks very much. Where in the original generator is the bulk of the client / server files generated? I can see the karma.conf.js and tasks/index.js etc. but where are the other bits?

ericmdantas commented 8 years ago

@georgeedwards They are separated in other folders, suchs as client_ng1, client_ng2, server_go, server_node, etc.

And the main generator and sub generators copy them like this:

Copying the whole directory: https://github.com/ericmdantas/generator-ng-fullstack/blob/master/_ng/full/generator.js#L51

Copying only a single file: https://github.com/ericmdantas/generator-ng-fullstack/blob/master/_ng/full/generator.js#L49

Same goes for sub generators:

https://github.com/ericmdantas/generator-ng-fullstack/blob/master/_ng/client/angular.js#L12

https://github.com/ericmdantas/generator-ng-fullstack/blob/master/_ng/client/angular.js#L48

georgeedwards commented 8 years ago

Yes I saw the tests, but where are those Client folders copied?

ericmdantas commented 8 years ago

This is called in the main Generator: https://github.com/ericmdantas/generator-ng-fullstack/blob/master/_ng/full/generator.js#L62, which calls this https://github.com/ericmdantas/generator-ng-fullstack/blob/master/_ng/client/client_factory.js#L14 and call the Angular Factory https://github.com/ericmdantas/generator-ng-fullstack/blob/master/_ng/client/angular.js#L184 aaaaand then copies the files https://github.com/ericmdantas/generator-ng-fullstack/blob/master/_ng/client/angular.js#L99

ericmdantas commented 8 years ago

The factory pattern is used so that if we decide to add anything other than Angular, all we have to do is basically implement the copyClient method.

georgeedwards commented 8 years ago

@ericmdantas Is there anyway to test the generator locally?

ericmdantas commented 8 years ago

Yes, in the generator folder, run npm link.