ctrlplusb / react-universally

A starter kit for universal react applications.
MIT License
1.69k stars 243 forks source link

Plans/Thoughts for V11. #201

Closed ctrlplusb closed 7 years ago

ctrlplusb commented 7 years ago

UPDATE:

If you follow this thread you will see we basically bash out some ideas and then backtrack quite a bit. It may be confusing to some. :)


Want to get a bit of a discussion going here.

@strues @carsonperrotti @enten @bkniffler

After the major cleanup parse and release of v10 I definitely want to move into a CLI and separate toolchain model.

In regards to the toolchain, @enten has been doing some work privately and has come up with a very interesting project called tension which would support the requirements for react-universally. I haven't been involved in it's architecture so I can't speak in depth about it, but it should be taken under consideration when moving into the next evolution of this project.

@bkniffler has been the heading up the CLI movement. I think it will be super helpful and allow us to bring together the branching strategy we have been evolving. We could display a list of technology options to the user and based on their selection generate an appropriate boilerplate template.

Have you guys used @gaearon's create-react-app? It is pretty amazing how he has set the project up. I have been going through it and have been thinking of adopting some of his ideas. It wouldn't be a verbatim implementation as I want to crank up the configurability somewhat but his structure is pretty amazing. I am not sure if this would touch on some sort of licensing issue though. I wouldn't be using his exact code, but the intellectual ideas would have definitely stemmed from his work. Do you guys think this would be an issue?

What do you think about his approach? Do you think it would be appropriate for what we would like to achieve?

strues commented 7 years ago

I really like the sound of where this is headed. Taking steps toward a CLI and toolchain method offers up a ton of options for the end user. Of course, that leaves lots of work to be done. I think it would be in our best interest to lay out and prioritize different aspects of the options we'd like to provide.

Stylesheets:

Test Frameworks:

Server:

State:

Additionally, I would imagine we'd want to get some form of website and demo online. Hosting it somewhere other than a Heroku free plan, in my opinion, is best in terms of speed. I don't mind offering up resources on one of my servers if there's a need.

ctrlplusb commented 7 years ago

I added glamor to the styles. :)

ctrlplusb commented 7 years ago

Added hapi to the servers list.

ctrlplusb commented 7 years ago

Looking at that technology list as it stands I would be happy. It provides a fairly good blend of very popular technologies.

Agreed that we will need a website to better represent the product. We'll need to source a designer if and when. :)


edit: actually we need some data stores too IMO

strues commented 7 years ago

The first iteration of this looks like a lot and it might be unwise to offer up more than preconfigured implementations. As opposed to a fully functional almost Yeoman-esque generator. Maybe in the second release we can consider adding functionality generators based on user input. Thoughts?

ctrlplusb commented 7 years ago

To be honest I think you are right. Let's phase this out, start off with a base implementation for v11 and then look towards tech stack options for a future release. I guess the key will be in allowing for user configuration and extension, which is way more important.

With that in mind lets agree on the base tech stack, my vote is for:

ctrlplusb commented 7 years ago

Another idea...

After the first implementation we can create seperate example repo's showing off how to create a project using redux/mobx/apollo etc

ctrlplusb commented 7 years ago

We should then consider deprecating the existing branches.

enten commented 7 years ago

What is the purposes of the CLI? It's important to determine its scope. If is it used to bootstrap a new application: a yeoman generator is more suitable.

Have you guys used @gaearon's create-react-app?

Once time if I remember correctly. I didn't like the lack about SSR support. I thought it wasn't a tool adapted for universal applications. And then I got there :smile: .

strues commented 7 years ago

You should add Gitter integration to this repo or we should get in a Slack/Discord some time. Can be easier to hash some of these brainstorming ideas out in real time instead of a massive comment trail

ctrlplusb commented 7 years ago

Gitter room created.

@carsonperrotti - it struggled to send you an invite. You may need to open gitter and check it out manually.

ctrlplusb commented 7 years ago

@enten it also appears to have struggled to send you an invite.

ctrlplusb commented 7 years ago

https://gitter.im/react-universally/Lobby

bkniffler commented 7 years ago

Hey guys, @ctrlplusb, why think about this as a CLI? We could try and package everything into dependencies, that wrap the whole webpack, babel and bootstrapping (app and server) into sane packages (react-universally, react-universally-sass, react-universally-mobx), so creating a new application doesn't need boilerplate or generators or else, only installing the dependencies (which would be easy to update as well!).

react-universally-sass for example would hook into webpack config and add the appropriate loader, react-universally-apollo would contain the basic app creator function and maybe some helpers

// Browser
import createApp from 'react-universally-apollo';
const app = createApp({ uri: 'http://my-api.graphql.com' });
ReactDOM.render(app, root);

// Server
import createServer from 'react-universally-apollo/server'
const app = createServer(config);
app.listen();

The biggest challenge here would be to not sacrifice too much flexibility. Then again, everyone could create their own react-universally modules if the default ones don't suite their needs.

There is so many generators, CLI tools, boilerplates, but in the end, I'd just like to abstract away all the complexity of webpack and boilerplate into somewhere I don't need to look at constantly, and at the same time be able to implement new features without having to change all my projects.

What do you think?

enten commented 7 years ago

I suggest meddleware (from the great krakenjs) to manage express middlewares in a better way. It's not a requirement but only a suggestion.

I was sad to see that the great electrode-server (used to manage hapi server as like meddleware do with express) expose a promise instead of the http server.

This highlight the issue with server exposing.

@bkniffler

These approachs (cli or runtime packages configuration) will create a huge abstraction layer. And @ctrlplusb said:

Webpack already scares people enough as it is I am scared to abstract an abstraction Because it becomes hard for users to imagine their webpack configuration when it no longer looks similar to the webpack docs and that their webpack config is split across modules/projects.

ctrlplusb commented 7 years ago

@bkniffler @enten some solid ideas there. There is obviously a ton to consider here. I am going through a round of doing research on all of this. Hopefully come back soon with some more ideas.

codepunkt commented 7 years ago

@enten i don't see the benefit of meddleware. its configuration based instead of imperative - thats it?

@ctrlplusb tech stack looks good. i'd rather have glamor than css, but thats just a matter of taste. going with express, react-router v4 and jest lgtm. other than glamor, i'm mostly interested in redux and apollo.

ctrlplusb commented 7 years ago

@bkniffler I think your ideas have a lot of merit. It opens itself nicely towards providing some extensibility points too. I still think it could work well in combination with a CLI though (or yeoman generator).

Playing with your idea a bit below...

// src/client/index.js

import { createApp } from 'react-universally';

// The following could be a boilerplate created example with some basic 
// routes implemented as an example.
import Routes from '../shared/components/Routes'; 

// Return back an object so that it opens up potential to return other items
// in the future? e.g. redux store / meta object etc
const { App } = createApp(config);

ReactDOM.render(<App><Routes /></App>, root);

The above would assume react-router v4 with my code-split-module etc all configured.

To be honest as we are going down this approach I am slightly apprehensive in addingreact-router v4 and my code-split-module as prebaked items. It gives user's less power, however, the server rendering options for router stacks are vast and complex so it may be best for us to commit to using certain technologies.

An alternative approach is to move specific technologies into separate packages (or sub folders) as you suggest and then user's can import and pass them as configuration.

e.g.

// src/client/index.js
import { createApp } from 'react-universally';
import reactRouterV4 from 'react-universally/routers/rr4';
import Routes from '../shared/components/Routes'; 
const { App } = createApp({ router: reactRouterV4 });
ReactDOM.render(<App><Routes /></App>, root);

But I think this will open up all sorts of unforeseen complexities moving forward. Perhaps it is best to have some base/fixed technologies, and everything else is then up for grabs.


Update

Also, the other cool thing about the create-react-app type of approach is that it provides an "eject" command which tears out everything allowing you to then customise the project at will.

This type of approach could then allow us to be fairly prescriptive in base technologies but still give people outs.


Sorry, this is all just ramblings for now. Not sold any single idea as of yet.

enten commented 7 years ago

@code-punkt

Yes is it. But there are some cool additions like app events and mostly the flow control (to run middlewares in parallel for example). And we can varying the server configuration depending to the environment easily (when it's associated with a config store like confippet, config, confit, etc).

The main advantage come if there exists a default meddleware configuration: so the developer will be able to easily enable/disable or change a middleware configuration (or a group of middlewares) through a simple configuration file.

It's not a necessity but only a suggestion.

enten commented 7 years ago

@ctrlplusb

There are already some good "bootstrapers". Are you sure that you want to turn react-universally (called RU in next sentences) into another one of them?

These people make a fantastic work with a different approach. But they are often restrictive or too abstract to hack them.

I made the choice of RU because you propose a boilerplate 100% hackable, comprehensive (by your relevant comments) and ready to use (and branches like redux are very useful).

I can accept to kickstart a project with a yeoman generator because I know that I will keep the control of the stack. But if I need to learn how to deal with another abstraction layer: I'm more reluctant.

Decoupling the toolchain is important to help developer which want to benefit of its latest updates (without deals with irrelevant merging conflicts). But we must do it without create another API layer: we must reuse and marrying API's tools which we used.

Create a CLI to help with npm's scripts relatives to the development and building process: it's okay. But a CLI to manage a plugged system scares me.

Definitely, create a plugged ecosystem is a big amount of work. And there already exists some. And this moves away from RU's initial purposes.

I'm afraid that the real strengths of RU (the awesome toolchain and universal application configuration) disappear (drowned in the middle of a redundant plugged system).

Please read this blog post: Why frameworks are evil.

Okay RU isn't a framework yet. I feel that it takes the way. If it's your wishes, I will respect that (but I will be sad to lost a really effective codebase for an universal react project).

I think it's important to say that when a project prepare a huge refactoring. Be careful not to get away from initial purposes: at the risk of devoting a monstrous time on unnecessary features.

The illustration below summarizes my thoughts about why I'm scared by pseudo-framework: Frameworks do not compose

bkniffler commented 7 years ago

@enten I see your points, and yes, what I propose would effectively make react-universally a framework. But then again, it will really help structuring the code in a way that makes it easily extendable and decoupled from the application itself. There is nothing holding people off (and indeed, we could have a CLI for that) to copy the react-universally code into a project folder universally and have full control over it, we could even encourage people to do so. Having an update mechanism wouldn't be to hard neither, the CLI would just overwrite the files and you could use git to make sure your own changes to files will remain and cherry-pick changes. You're also free to never update.

I agree @ctrlplusb that react-router and codesplit can be a part of the core package, and we could have different packages for app-boilerplate (mobx, apollo, redux), server-boilerplate (express, hapi, koa) and webpack config (e.g. styles via less/scss/glamour).

In my opinion this approach wouldn't be too complicated to maintain and it could offer everyone what they need.

bkniffler commented 7 years ago

@enten, you are right about that we shouldn't try to abstract everything away in a new API. Thats not what I imagine neither. But extending the webpack config through some kind of middleware shouldn't be a huge issue here. And the API surface to bootstrap your app doesn't need to be hugely complex, just some kind of createApp (which calls the /src/browser/index with some component) and a createServer (which calls the /src/server/index) that returns e.g. the express server with all the nifty react-universally features, and you could then add some middleware and start listening.

enten commented 7 years ago

@bkniffler

I keep thinking that yeoman generators are more suitable.

If a developer need to change a technology in its stack: it will always has more stuff to do that only call a cli command (which will just make "basic" hidden setup). For the good at all developers, they need to see how we used libraries in the stack. So, when they open the documentation of a library (that we have chosen to use): they easily understand our intentions.

RU isn't a simple boilerplate only: it's a source of learning for developers. And learning how to use libraries in a good way will be harder if we wrap the concrete implementation in several packages. Otherwise, we will be better to collaborate on existing similar tools.

I should want to avoid that we lost a lot of time on issues already solved or work by other projects and keep RU's initial purposes unbroken.

Note: once again, it's just the opinion of a RU's friend.

Update: a response wrote by @bkniffler has disappeared. I add that response below because it's useful for a better history.

@bkniffler commented on Nov 30, 2016, 3:22 PM GMT+1

I've got a few projects that could easily be managed in such a way. But different people have different requirements and different philosophies for solving problems, and thats okay.

As I said, I'm fine with this repo being a starting point for people who look for the state-of-the-art stack, but in the end I imagine it'll mostly be @ctrlplusb dedicating time to this project, and as he made clear at some point, this project is born out and living of his own need.

I think you've made some excellent points and I've also given some arguments and thoughts, @ctrlplusb will be experimenting with the ideas and I'm sure react-universally will remain a great repository that I'll use as a base, whatever he decides the future of it looks like.

@bkniffler I can remove it if you don't want that it shown

ctrlplusb commented 7 years ago

Some amazing points gents. I am loving this discussion. Thank you. x

bkniffler commented 7 years ago

I just added https://github.com/styled-components/styled-components to the list!

ctrlplusb commented 7 years ago

FYI, my current thoughts are not to create an CLI or rip out the toolchain as it creates an abstraction that goes against the goals of this being a starter kit.

But we have been working in some of the amazing ideas from @enten, @carsonperrotti, @strues and @bkniffler into the current tooling configuration.

Hopefully we can achieve a happy medium where the current project is structured in such a manner to provide just enough configuration abstraction and extensibility via the config folder, allowing for much easier merge/upgrade paths.

My other hope is that a separate CLI tool (in another repo) can be created which targets this repo and creates packages that can be used in a similar way as described by @bkniffler in his personal projects. This main repo wouldn't need to be changed at all I think, which again is great for keeping this repo in alignment with it's goals. We may perhaps need to consider strict semantic versioning strategies though, which shouldn't be too bad to manage as the project is definitely heading towards a bit more stability/maturity in my opinion.

Kimel1 commented 7 years ago

In my opinion here are need Browsersync support

ctrlplusb commented 7 years ago

@Kimel1 - do you mind elaborating on that?

ctrlplusb commented 7 years ago

Closing - archived.