-
-
Notifications
You must be signed in to change notification settings - Fork 26.9k
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
Plugin System #670
Comments
I like Karma test runner. It scans your package space and automatically picks up all packages named as So, for |
I personally like idea with a hack'y usage of superPluginImport({base: ['https://ajax.googleapis.com/ajax/libs/'], include: 'all'});
// use include option to select what we need, example: 'react,react-dom',
// maybe with versions like 'react@15.3.1,react-dom@15.3.1'
// and later we can use it:
ReactDOM.render(<h1>Hello, world!</h1>, document.getElementById('example')); Looks like direct https://rawgit.com/ but for multiple sites. |
plugin system... don't you encounter the risk of becoming another "grunt" thing with thousands of wrappers to use even the simplest of the libraries? |
@just-boris Brunch does similar, instead of looking through the folders though, it just looks in the The experience of simply doing |
I like webpack's plugin system. All internals are implemented as plugins. It lets you hook into any part of the system. If you're at the point in which you need that level of flexibility, you might be better off learning how to use the underlying tools. What are examples of scenarios which would be well served by plugins? I think helping improve the underlying tools would go a long way towards solving many of the use-cases which come to mind. There have been docs writing up ideas about concord for a while. If it were supported, what would be the remaining gaps? |
@cesarandreu for one, loaders. If adding a loader to create-react-app- was as simple as |
@goshakkk Wouldn't concord solve that use-case? To some degree, at least. You'd still have some stuff to configure. I like the idea of having a thing you can just drop in and it works. But I don't know how it can be achieved, once you start considering how it interacts with other plugins. Will it work when someone writes a plugin for HMR? Extract stylesheets for production builds? Pass em through autoprefixer? Setup the aliases for jest? Will it work when someone adds a plugin for css modules? I don't write this to be contrarian; I want frontend tooling to be great and approachable. |
I used to love http://mimosa.io/ (sane defaults for all the plugins, very little mandatory configuration).
There's also a similar thing for grunt: https://www.npmjs.com/package/load-grunt-tasks |
Would love to be able to extend create-react-app 😍 . I'd like to add babel plugin system as a nice example here, particularly the presets. In any plugin system, I believe presets are what would make it easy for newcomers to start hacking right away. Eventually create-react-app would come with the preset recommended by you, and others will create their own flavors. Just as thought experiment (That I haven't explored all the way yet): What if instead of a plugin system, we create a system that exports most of it smaller parts so others can just use them and compose them in a different way? It may not be as a robust solution as a plugin system, but It would make updating the core less dependent on the created plugins. The smallest example of what I mean: If I have function |
This is the direction I want to move towards in the future, after we land #419. |
@gaearon I was just going to create an issue suggesting a "babel-preset-facebook". A quote from that:
There is a need to hide configuration from users because they are complicated and confusing. Instead of hiding the ugly truth, we can prettify the truth and stop hiding it. Then people could mess with their configs without going crazy and there wouldn't be a need for a plugin system. |
I think there are probably a few lessons to be learned from Meteor's build plugin system -- although webpack and Meteor's build tool have some pretty different starting assumptions, I think CRA's "zero-config"-ness is going to run up against a lot of the same problems we've seen in Meteor. For instance, although it's a great developer experience just installing an npm-package and having a plugin work, it's inevitable that people are going to want to configure plugins (for instance, setting autoprefixer browser support is pretty hard to generalize!). So if there's no system for plugin configuration, plugin authors will improvise, which leads to a problematic and inconsistent developer experience.
On a more concrete topic, I think this is the best way to move forward if/when you decide to go 0->1 with the config. When creating saturn (an experiment in a webpack based framework, similar in aims to CRA), we tried to make it as simple as possible to consume parts of the framework or even copy them into your app, to provide a less binary escape hatch than I'm still not sure if that was a good idea (I'm sure you've thought about it a bunch), but it does seem like a much more flexible alternative to "eject if you want to configure anything" :) |
I particularly like kotatsus layer over webpack. Less config overall and plugins specified via cli Args optionally |
Proof of concept implementation for this: 344893b The idea is that instead of completely opening up config to plugins (at which point someone will write a |
I like the idea of a "zero-configuration" build tool. So even with a plugin system, I think that should still be hidden behind its own "zero-configuration" tools. What I'd like to see is a package like // bin/cli.js
const cli = require('create-react-core')
const config = require('./config')
cli(config)(process.argv) Then add that file as a bin script in your package.json and publish it. The nice thing about this is that people can create their own zero-configuration build tools for things like "create-electon-app", "create-react-lib", etc. using the "create-react-core" as the glue for everything. In terms of the actual plugin system, if you're able to describe the entire functionality of the build tool from a single configuration object, then everything can be handled via composition :) |
1. Automagically enable plugins based on 2. Each plugin should do only one thing and do it well. UNIX philosophy. 3. Ban violators of UNIX philosophy using black-list. The same way 4. Most of the plugins want to modify webpack config. But some of them want to modify other files, like Jest config or flowconfig. 4.1. To modify webconfig we can use webpack-config, webpack-configurator, webpack-configurator, webpack-merge, webpack-blocks 4.2. To modify other configs we can use jscodeshift or 4.3. Question: is there a chance we can come up with one config format for JS tools? 5. The problem is when plugins need to know about each other. Example:
Other example
The only reasonable solution is to create one more plugin for each interaction e.g. Immediate questions arise:
It is very complicated to target this problem with most general compatibility in mind. My suggestion is to start with small steps, like one project at time and see how it goes. For example SASS or CSSModules because they are popular. Start with question: what minimal api it would take to be able to implement |
Everybody wants feature set of webpack, but don't want to get into development environment setup/configuration:
Plus a lot of people want more out of box integration with different component libraries
But to do some integrations to work out of the box sometimes you need more than current defaults. I want to get out of the box integration with react-toolbox. The reason I want it over other material design implementation for react: it is actually made out of separate components, instead of creating react wrapper around existing library (which you need to import all at once). I generally disappointed with this attitude "throw everything in". Isn't JS applications monstrous enough yet? |
I just want to reiterate -- I like the idea of a zero-configuration build
|
I like where this is going 😜 |
I think there is real value in having a plugin system that abstracts away underlying build tools such as webpack. I could very well see my dev-toolkit being superceded by a version that uses create-react-app with the necessary plugins. After all, all these create-react-app alternatives (including dev-toolkit) want to achieve a common goal. Removing as much boilerplate as possible to let us focus on creating our apps. One of the biggest improvements going from grunt to gulp and from gulp to webpack was the ability to use more javascript, with webpack it was javascript by default. Going back to grunt-style static configuration and cli-tools with their own configs would be a big step back.
That is one thing that gulp nailed. It was super simple to plug things together, but every now and again you had this one plugin that was so complex that nobody understood the gulp-task. I still remember the toolkit's old javascript task with browserify and watchers and whatnot. If this plugin system spawns such complexity (let alone webpack-style complexity), then I see little point in using it over using and improving webpack directly.
personally I never want to see such config as a developer. I'd rather have a config that explains through text what it's trying to do: import style from 'config/style';
import devEnvironment = 'config/devEnvironment';
style.cssModules = true;
if (devEnvironment === 'production'){
style.hashedModules = true;
style.hashType = 'base64:5'; // can be omitted for sane default
}
export style; |
@stoikerty I'm personally not happy with this code too:
But this is how webpack currently works. We can wrap/hide this behind code you wrote, but this is not a case as of now. Or I missing something? |
My example is pseudo-code (imagining how you might configure a plugin). The main question from my point of view would be what direction the plugin system should have. Would plugin-creators be working with exposed webpack-config from CRA? How much of webpack if any would be exposed to the developer using the plugins? What happens if webpack is replaced in the future, is this a possibility? If so, is the plugin-system still meant to work? |
This topic is taking a dangerous direction trying to re invent webpack 😥 |
@FezVrasta I like webpack feature set, but I don't like it's configs. I suppose I'm not the only one. It's just I have no idea (right now) how to do it better. I do not like grunt configs either. Gulp a bit better, but still not very portable across projects. I'm looking for convention over configuration approach. And CRA is great example of CoC. But I want just a pinch of configs over it. Yes talking about reinventing webpack here would be offtopic. |
The last thing we need is a system where you need plugins to do every single thing. |
Actually, I've just realized that this might put an end for #779 (Forking react-scripts). But I'm not sure if it is better.. |
Just tossing this into the conversation. I built this when create-react-app first came out - https://github.com/timarney/react-app-rewired It's a hack but it's pretty flexible It basically loads the config from react-scripts and allows overriding see https://github.com/timarney/react-app-rewired/blob/master/scripts/start.js
@anthonysapp - used the idea to create a boilerplate with Sass + TypeScript No fork of react-scripts just having access to the config to allow overrides |
Why "hell"? You are just modifying two Webpack configs. If you are talking about modifying more than that, you are still at advantage because without forking you wouldn't be able to that at all.
I am not against the idea of a very simple plugin system. It is just not that simple. Imagine this plugin: export default (config, paths) => {
config.resolve.alias.app = paths.appSrc;
}; Currently, this is what module.exports = {
/* ... */
resolve: {
/* ... */
alias: {
'react-native': 'react-native-web'
}
},
/* ... */
}; If CRA decides to not alias "react-native-web" and removes If you start covering these cases, the system stops being simple. |
I think that's the advantage of having versioned plugins though, because the plugins could specify "I work with CRA 0.7.0" and if those versions change, you get an error at npm/yarn install time and not at runtime. It's not great though, I agree. That particular case could be worked around -- maybe the plugin system could wrap the plugin calls in a try/catch and just discard that plugin's changes -- but I get your point. I do also worry a bit about causing a "plugin-hell" ecosystem like Grunt and Gulp have. I don't think this is quite the same case though, because CRA has many sane defaults while Grunt and Gulp run configs that are built from the ground up with plugins. Plugins are in their blood. You can't get much done without them. On the other hand, CRA works quite well on its own. @timarney I really like your solution. In fact I tried something like that at first, but I didn't know about |
Also worth pointing out a system like Slate (https://github.com/ianstormtaylor/slate) where even the core is essentially a plugin as well, and could work as an alternative to scheme proposed in #670 (comment). |
What if there was a 'create-web-app with plugins' project, and 'create-react-app' was that with basic react plugin.This would let people do other cool stuff too. (I'm just working on a d3 app starter for a friend, basing it on create-react-app project, just getting rid of react :( |
@jkarttunen using CRA because don't want to configure Webpack? Seen before. But there are also different zero-config development servers, like budo |
More like I like how the webpack is configured here |
Over the holidays, I was messing around and came up with a project that hopes to solve this whole forking problem. It's a pattern for building tools like |
How about instead of plugin system we let users extend the webpack config, // backpack.config.js
module.exports = {
webpack: (config, options) => {
// Perform customizations to config
// Important: return the modified config
return config
}
} |
@Hurtak Doing that here already https://github.com/timarney/react-app-rewired @gaearon has been very clear with pitfalls with doing this namely #99 (comment) (see other refs in that ticket). In the react-app-rewired repo there are some 'pre-wired configs which kind of work around this but yes people could still mess them up. |
would love to create an React + Electron app with CRA had asked the same question on the atom board but it more of a wishlist was pointed to ember-electron, not sure if that helps |
If it could support. We could added custom plugins like: Offline, Testing, ... I think it would be more flexible for developing app. It would be nice if you open api for this case. |
Hi, Just started to use
For one of the app I did the I would vote for any concept of the extending the default configuration without EJECTING all of it. @gaearon |
@PavelPolyakov I've already provide such PR #1357 but:
And possible future for app with experimental features:
Making "eject" you donate all of the all new CRA features in order to add custom babel plugins or update webpack conf (in most cases such update is a few lines of code). webpack / babel and any other configuration will make CRA very fragile. And CRA team cannot guarantee perfect experience and stability. |
While updating Awesome CRA found react-scripts version that supports plugins - https://github.com/thtliife/create-react-app/tree/react-scripts-pluggable/packages/react-scripts Seems relate to this thread |
@tuchk4 Thanks, interesting, would play with those pluggables then! |
@tuchk4
at the end, I still think that there should be a solution when you do not need to refuse from the CRA feature, but, at the same time is able to configure webpack a little. Obviously, if you do anything on your own fear - you do not expect that community is responsible for your changes. |
@tuchk4 Thanks for mentioning react-scripts-pluggable :) @PavelPolyakov
The entire idea is to allow adding webpack plugins in the same zero-config manner as create-react-app is designed upon. As an example, try the following to add sass support to your cra project: create-react-app test-project --scripts-version react-scripts-pluggable
cd test-project
npm install --save pluggable-sass-loader rename $font-stack: sans-serif;
$background: #222;
body {
margin: 0;
padding: 0;
font-family: $font-stack;
}
.App {
text-align: center;
}
.App-logo {
animation: App-logo-spin infinite 20s linear;
height: 80px;
}
.App-header {
background-color: $background;
height: 150px;
padding: 20px;
color: white;
}
.App-intro {
font-size: large;
}
@keyframes App-logo-spin {
from { transform: rotate(0deg); }
to { transform: rotate(360deg); }
} Now in import './index.css'; to: import './index.scss'; The idea is that you use the plugins, (As they are developed), to enable features with zero config required. Same as how create-react-app allows to build React apps on webpack with zero config required. |
Oh also... @gaearon
Check out my take on a plugin system for create-react-app based on the 0.9.x branch as per your comment #779 (comment)
react-scripts-pluggable |
Neutrino has concept of presets that are simple node.js modules implementing function transforming its configuration. Notably it allows for configuring webpack configuration by modifying I wish create-react-app adapted similar approach :) |
Wrote up a little tweetstorm here if you're interested: https://twitter.com/dan_abramov/status/855843921385201664 I agree about Neutrino's approach being nice (you can use one preset at a time, right?) |
You might want to take a look at |
There are no plans to do this right now. If you're interested in more flexibility, check out Neutrino. |
I know we said we don’t offer any configuration but...
If Create React App had a plugin system, what would it be like? Can you briefly describe build tooling plugin systems that you’ve used and liked in this thread?
If it was supported, what would you build with it?
The text was updated successfully, but these errors were encountered: