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

✏️Discussion: The direction & future of create-react-app #4590

Closed
philippefutureboy opened this issue Jun 8, 2018 · 16 comments
Closed
Labels

Comments

@philippefutureboy
Copy link

philippefutureboy commented Jun 8, 2018

Hello to all the wonderful people behind this project!

Thank you for making our development experience better and more accessible to everyone ❤️

Today I would like to open a discussion on the direction of create-react-app. I saw the issue opened up by @shelldandy, and I took interest in the future of create-react-app.

You see, the current landscape of programming is changing rapidly. Not too long ago, most programmers managed their dependencies themselves. Being a veteran meant that you had seen the ins and outs of all the tools that supported your tech stack. While there was pride in knowing the complex labyrinths of configs, there was also a lot of energy spent on things that did not produce a tangible impact on the end-user.

And this is where the major shift is occurring: Over the last years, especially in the web field, programmers have shifted from being people that make things work to people that create experiences. As programmers, we want to produce tangible output in the most efficient ways possible. In the web tech landscape, this shift was characterized by the Javascript renaissance, accompanied by the Javascript fatigue. This brought about the trend towards 0cJS, serverless services, and tools like create-react-app.

I believe this to show that what we want as programmers is to create experiences efficiently, and handle only the details that truly matter to us.

In light of this, I believe that the tools of the future will be tools that abstract away all the unnecessary details to bring an experience to life, while providing enough modularity to expose certain details on-demand. These tools shall be:

  • zero-config by default
  • always at the bleeding-edge (performance, packages, SEO, PWA, etc)
  • modular
  • extensible
  • have an easy-to-use cli that can provide access to multiple boilerplates

Here's how I see it:

Imagine a cli for create-react-app that can read configuration files like vue-cli meta.js files and infer from there a series of command it has to undertake to scaffold an entire create-react-app repository, complete with extended config and pre-installed plugins.

Imagine being able to load THE boilerplate configuration you want from a list of awesomely-curated meta.js-like github gists.

Imagine being able to automatically export YOUR boilerplate configuration to a github gist via an export command so that you can share your setup with others.

Imagine a create-react-app repository that does not need to be ejected to do partial, custom configurations, but still hides the non-customized configuration from its user.

Imagine a create-react-app that benefits from a plugin architecture, a bit à la Gatsby (but better), where all you need to install a dependency to your favourite service or dev feature is one command away.

Want SCSS in CSS Modules? Load cra-sass-css-modules-plugin and you are good to go.

Want to have firebase support? Sure thing, just install cra-firebase-plugin. It will run you through a series of inquirerJS questions to do a first config. It will expose new files to the create-react-app config files, which you will be able to modify just like any other custom config.

Now, imagine that you are a plugin developer. All you'd have to do to create a plugin is to use a config extend API provided by create-react-app that allows you to install packages, modify configs, and more.

Your comprehensive, efficient, extensible, concierge-like development experience with react will only be a single command away.

Welcome the docker of server configuration, the npm of module registry, and the serverless of scaling, all for your favorite front-end library, React.

Welcome to the future of web development.

This is what I believe to be the future. What are your thoughts?

🚀

@unzico
Copy link

unzico commented Jun 8, 2018

Interesting thoughts! I've been thinking about this myself, since I'm using cra with TypeScript and SASS and now plan to include Semantic UI. Obviously, I had to eject cra to make this happen.
In my opinion, a cli would be really helpful to achieve this without ejecting and many projects start with the same questions:

  1. JavaScript vs TypeScript
  2. CSS vs LESS vs SASS
  3. Bootstrap vs Semantic UI
  4. ...

At the current state beginners or those, who are new to e.g. TypeScript need to mess around with cra ejection or need to find an existing fork, without actually understanding what's happening. A cli could make use of a central config file, which could also be changed once the 'cra app' has been build.
A script could then read that config file and create/update the corresponding webpack config files.
As a result, the cra user has a chance to update his config file based on his personal needs and doesn't need to eject.

I'd like to help making this possible, however, I've never committed to OSS and am quite new to programming.

PS: I expect many answers to be: 'cra is about zero-configuration'. It should definitely be this way for building a basic react app. However, many users might end up with ejecting their app and the need to do messy configuration on their own, which leaves the question: is zero configuration actually better?

@gaearon
Copy link
Contributor

gaearon commented Jun 8, 2018

Look at the scope of the changes it takes to upgrade a major version of a tool.

Webpack 4: #4077 (and other PRs)
Babel 7: #3522 (and other PRs)

Many of these changes are cross-cutting.
Now, the promise of CRA the way I see it is to:

  • Free the developer from the burden of making those changes, and instead make upgrading really simple.
  • Ensure all these things keep working together well after each upgrade (which is not trivial).

Of course this only works if you don't eject. But plenty of projects (about half) don't, and so far we've been successfully expanding the use case coverage that comes by default (and will keep expanding it, e.g. you can try 2.x alphas which support Sass and lots of other stuff).

Turning CRA into a plugin ecosystem pretty much kills both advantages above:

  • Upgrading is no longer easy because you have to track every “plugin” and which versions it’s compatible with.
  • The whole thing is fragile because no plugin can “survive” significant changes in the base configuration (again, look at above PRs). So plugins will be broken by updates, will be clashing with each other, and are not guaranteed to work well together.

The advantages of having shared “base” conventions and feature set (which lets beginners easily switch between examples and feel familiar in different projects based on CRA) also disappear because now we have 1000 unique setups again.

Ultimately my impression is that following this path will just turn CRA into a worse webpack. Why build plugin systems on top of plugin systems?

I think that primarily you want this because some of the features you care about are not supported yet. If they were supported I’m not sure configuring everything (and losing existing benefits like easy upgrades and guaranteed well-done integration) would be worth it. In that case I think our philosophy is still valid. We’ll keep covering more use cases with each release, and try to make 80% users really happy by applying our tradeoffs as a lever instead of ending up with a generic generator with a fragile ecosystem based on mutating configs.

What am I missing?

@unzico
Copy link

unzico commented Jun 8, 2018

I agree.
I started with create-react-app-typescript and noticed, that only a 'few lines' have been changed within the webpack config file, which made me think, that some configuration might be possible using a modular approach to extending the webpack config based on an accessible config file with a few booleans. However, I absolutely agree with your standpoint, when it comes to the plugin-like structure. #4412 is probably a better approach to it, if possible. This will shift the responsibility for granular configuration to the user and give cra the space it needs, to be the top-notch tool, that it is.

@yufengwang
Copy link

When is it ready for webpack4 ?

@philippefutureboy
Copy link
Author

Thanks for sharing @gaearon. Definitely some good insights coming from your experience as member of the project.

My experience with plugins is limited to that of Gatsby (which I admit, was pretty poor), and with Babel. I did feel like Babel was a relatively seamless experience, but then again, I wasn't there in the dark era where things like babel-eslint weren't working properly. Your points are definitely valid, and I must agree that the whole plugin ecosystem may take more from an utopia than the real world.

I do think however that if we remove the plugin part of this idea, the rest of the vision is still as relevant. I believe a modular configuration like that presented in #4412 would greatly benefit cra as a zero-config / minimalist-config project, while leaving the responsibility of keeping the configuration working with the new updates of cra up to the user.

Likewise, I think that the list of awesomely-curated boilerplates gists would also greatly benefit the cra ecosystem. Indeed, while I admit that having a list of boilerplates may sound deterring at first, a simple search page in which one can specify what they are looking for in terms of added features could definitely solve the problem. The said search page would return a list of boilerplates with all the added features listed (with their version beside), as well as the latest cra they are compatible with. This could allow more advanced users to easily start more fully-featured cra-based projects, without you having the need to keep always expanding the cra codebase to increase use-case coverage. As such, rather than having a monolithic-does-it-all cra, the cra team could build a core cra and maintain a short list of cra boilerplates, still cover 80% of use cases while decreasing the future efforts to maintain everything in a single module.

What do you think?

@gaearon
Copy link
Contributor

gaearon commented Jun 8, 2018

What would you be looking for in such “boilerplates”?

Splitting things like Sass or Jest into their own packages would make things harder for us, not easier.

Or do you mean just sample code?

@audiolion
Copy link

this seems to mostly be deriving from vue-cli and looking at what they are doing.

image

Evan You was on a workshop.me podcast with Ryan Florence recently and talked about why he went that route and decided to build a plugin system on top of babel.

It is still in beta and time will tell but that is probably the reference point for comparison here, should we be copying vue in this regard or not

@philippefutureboy
Copy link
Author

@gaearon:

My definition of boilerplate is a basic setup with minimal amount of code necessary to exemplify the dependencies and features loaded in the boilerplate. Does that correlate with your definition of boilerplate or with that of sample code?

As @audiolion pointed out, this idea stems a lot from the vue-cli model/ecosystem. Examples of features in boilerplate that could be interesting are:

Typings:

  • Typescript
  • Flow typing

CSS:

  • CSS in JS
  • CSS Modules
  • SASS Preprocessing
  • styled-components
  • reas

Testing:

  • Jest
  • AVA
  • Puppeteer
  • Mocha (some people are still old school)

Misc:

  • Firebase
  • Redux + Redux-X (thunk, saga, promise-middleware, etc.)
  • GraphQL + Apollo + ...
  • optimized lodash for webpack
  • functional programming setup w/ ramda, list, etc.
  • release and devops setups like release-it, commitizen

These are just examples of what comes to mind, I'm sure there are even more relevant examples out there.

@arvigeus
Copy link
Contributor

I think @TheLarkInn mentioned something about support for presets in future versions of webpack. One day we might be able to use CRA like this: { presets: ["react-app"] } (one single line in webpack.config.js).

@philippefutureboy
Copy link
Author

That's a super cool idea :O
So then that preset could be extended?

@yordis
Copy link

yordis commented Jun 24, 2018

I used vue-cli@v3 with React code and so far works like a champ. Probably some of the plugins from Vue team wouldn't work with React but at least typescript, babel, pwa works.

vue-cli/ui doesn't work right now because it requires some Vue specific setup but probably it could be adjust a little bit and it would work with React projects.

Based on the needs of the CRA right now and what people are requesting I strongly recommend to team up with Vue team rather than tackle the exact same issues by yourself ( @gaearon
@yyx990803 ) , even when they are completed different frameworks the needs and requirements for the CLI are completely 100% the same.

They definitely figured out a clever way to extend the configurations and how to ship zero-config setups and a full plugin based ecosystem around it which is really beneficial.

related to #3786 #3917

@darktasevski
Copy link

@gaearon Any plans on making PostCSS configuration extendable? I see that Sass is going to be included in next CRA version, but I would love to see a possibility to extend PostCSS with some custom plugins.

@affanshahid
Copy link

Is the ability to allow extending webpack configs in a similar way Vue CLI 3 does on the roadmap?

@loliver
Copy link

loliver commented Jul 11, 2018

I saw this the other day and think it might be a useful approach here. My use case is changing the exclude for babel so it compiles our scoped component library components that are inside node_modules as we're not doing that on publish at present.

E: Made the decision to refactor our component library so it packages up compiled code instead, so don't really need the change personally anymore.

@shelldandy
Copy link
Contributor

@affanshahid from what @gaearon says, no

@stale
Copy link

stale bot commented Nov 2, 2018

This issue has been automatically marked as stale because it has not had any recent activity. It will be closed in 7 days if no further activity occurs.

@stale stale bot added the stale label Nov 2, 2018
@Timer Timer closed this as completed Nov 2, 2018
@lock lock bot locked and limited conversation to collaborators Jan 9, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

No branches or pull requests