bencodezen / vue-enterprise-boilerplate

An ever-evolving, very opinionated architecture and dev environment for new Vue SPA projects using Vue CLI.
7.78k stars 1.32k forks source link

Component organization #17

Closed jnarowski closed 6 years ago

jnarowski commented 6 years ago

I did have a question related to #6. Not necessarily each component to a sub directory, but more about component organization overall.

With both reusable and non reusable components, it gets a bit tricky.

1) How should we organize non-reusable components related to a specific domain? Let's say there are a dozen components that are specific to the UserShow page. How and where should they exist? In my apps, I've ended up making a folder for the UserShow and then a components directory there which feels ok.

EG: src/router/views/UserShow/Layout.vue src/router/views/UserShow/components/A.vue src/router/views/UserShow/components/B.vue src/router/views/UserShow/components/B.vue ....

2) in the src/components directory, I only house shared and reusable components

How do you go about this, once components and sub components become larger and more complex? This is another thing that is never shown in boilerplates, what happens when the files grow beyond the simple, single component organization.

I've used atomic design before in some of my react apps with mixed results, since it's not always clear what goes where.

3) Bonus question: Curious why you added the views and layouts underneath the router folder? I guess I always saw the router as an organizational tool, but the page itself as it's own entity, separate from the router. In my past projects, I've created "src/pages" directory for all page level components (or views).

chrisvfritz commented 6 years ago

1 + 2

I can't speak for every team, but I personally prefer to avoid splitting components out into subfolders, even with dozens or hundreds of them. The reason is it makes refactoring more difficult when you realize you actually want to share a component that was previously scoped to a specific section of your app.

Plus, quickly switching between files can ironically become more difficult with nested directories, as the file names no longer have to be unique so people get lazy and less descriptive. For example, I've seen nested component directories with a bunch of Input.vue or Modal.vue components. In many editors, the name of the component is the primary focus and the folder is often grayed out.

And finally, seeing a list of related components in the sidebar (which is one of the primary reasons I hear for nesting components in subdirectories) actually takes much longer that way! When scoping with filenames, I can use the quick file searcher to bring up any group of components - whether it's all my base components or all my input components - in about a second, no matter how large the app gets.

3

I organized views and layouts under router because they aren't really their own entities. View/page components actually accept router-specific options and layout components can only exist inside of views, so they're all part of the routing side of the app.

Does that make sense?

jnarowski commented 6 years ago

Yes that does, thanks for the explanation on both.

So you have something like src/components/ExperimentForm src/components/ExperimentFormGroup src/components/ExperimentFormGroupInput src/components/ExperimentFormGroupSelect

alongside all of your shared components like src/components/BaseTable src/components/BasePagination etc...

Is that how you do it? Even with hundreds to thousands of components?

A couple more questions:

I do see your point about refactoring. I'd love to hear other's opinions b/c I find that as your app grows, it becomes quite hard to find something even with fuzzy searching, and it's much easier and more focused to have a folder with just the components you need, right where you need them.

chrisvfritz commented 6 years ago

Is that how you do it? Even with hundreds to thousands of components?

Yes, though I haven't personally worked on an app with thousands of components, ๐Ÿ˜… but I've heard that Facebook uses the same strategy (and I believe they do have thousands).

Do you always prepend the parent component to the file name ie Experiment in this case?

For tightly coupled components, yes. I even made it a Style Guide rule. ๐Ÿ™‚

Do you have different naming conventions for different type of components, like Index, Show, - Form/Edit/Create etc?

I have some patterns I often use, but nothing too special. I think the most important thing is that the language makes sense to the team and fits in with how they're already describing parts of the app.

chrisvfritz commented 6 years ago

I'd love to hear other's opinions b/c I find that as your app grows, it becomes quite hard to find something even with fuzzy searching, and it's much easier and more focused to have a folder with just the components you need, right where you need them.

Like I said, this is what I personally find most helpful, but many very smart and experienced people disagree with me. I'd say go with whatever makes you happy. ๐Ÿ™‚ And in general, I think it's a good policy not to follow rules that don't make sense to you. Sometimes it bites and you end up learning a hard lesson, but if you never take that risk, you never get to do that learning. ๐Ÿ˜„

chrisvfritz commented 6 years ago

Also, people can continue commenting here, sharing experiences, asking questions, etc, but I'm closing for now just so I know the issue is off my todo list. ๐Ÿ˜„

jnarowski commented 6 years ago

Ok sounds good, thanks for the feedback and dialog.

escapedcat commented 5 years ago

Not sure if this is the right place to ask but I'll try anyway. Happy to move it somewhere else or create a new issue if needed.

Would you group views in such directory way? Like:

src/router/views/UserShow/index.vue (list)
src/router/views/UserShow/detail.vue
src/router/views/UserShow/edit.vue
src/router/views/UserShow/create.vue

Or stick to something like this?:

src/router/views/UserShowList.vue
src/router/views/UserShowDetail.vue
src/router/views/UserShowEdit.vue
src/router/views/UserShowCreate.vue

I appreciate any feedback.