General feedback #11

Closed
gaearon opened this Issue Jul 17, 2016 · 152 comments

Projects

None yet
@gaearon
Contributor
gaearon commented Jul 17, 2016

Let’s use this thread for a general discussion.

Does the flow feel good?
Did we pick the right plugins, presets, and loaders?
Do you see areas for improvement?

This project is in a very early stage so there’s plenty of all hanging fruit if you’d like to make React experience better.

Thanks for taking a look at this project!

@gaearon
Contributor
gaearon commented Jul 17, 2016

cc @insin @mxstbr @eanplatter @ericclemmons, thank you so much for your time & ideas

@ericclemmons
ericclemmons commented Jul 17, 2016 edited

Should we encourage or support something like nvm? Or will we specify a minimum version of Node that we can test against to ensure consistent behavior/performance?

@gaearon
Contributor
gaearon commented Jul 17, 2016

I'd add node >= 4 to engines. The CLI script actually already checks against this field (we took it from RN).

@gaearon
Contributor
gaearon commented Jul 17, 2016

We definitely want to support n / nvm.

@eanplatter
Member

I'd be interested to hear what people thought about eliminating 100% of the boilerplate code. We tried to do this we enclave but made up for it with a small amount of configuration. (telling enclave where to find the index.html / React entry point).

@gaearon I know you mentioned not wanting to have the user configure anything, so I am thinking more of an implicit kind of thing.

While it might not be totally pragmatic to hide the index.html file, it might make sense to just let the user know that they need to create a Main.js file in the root of their app. (similar to something like Elm).

While boilerplate is a helpful way to show a new user how to get started, it can be hard for beginners to know what they can touch.

Also, sometimes when a user is using something with boilerplate, it can make community resources (like tutorials) a bit harder to grok because they're having to dance around code written by the tool.

I'm willing to be swayed either way :P but in my experience I've found that beginners appreciate the ability to understand all the code written in their application.

@keyanzhang
Member

I was about to ask you if we want multiple scaffolds/boilerplates, but I'm not sure if that aligns with the design decision here. Maintaining multiple scaffolds is also an overhead. As a solution, I thought about this a while ago and I imagined a npm init-like interactive cli initialization experience -- something like:

Do you want to use CSS Modules? (Y/n)

My motivation behind this is, CSS Modules is popularly adopted and a lot of people would want to use it in their project. But if I'll need to "graduate" in order to add the config, then it feels more like a yet-another boilerplate again. Do you think this fits with our design goal?

@gaearon
Contributor
gaearon commented Jul 17, 2016

@gaearon I know you mentioned not wanting to have the user configure anything, so I am thinking more of an implicit kind of thing.

While it might not be totally pragmatic to hide the index.html file, it might make sense to just let the user know that they need to create a Main.js file in the root of their app. (similar to something like Elm).

Isn't this what we do? The location and names of index.html and src/index.js are conventional, you can't change them. The HTML file was added because people really want to customize it (for example meta tags or google analytics) but it doesn't let users change anything related to bundling.

I was about to ask you if we want multiple scaffolds/boilerplates, but I'm not sure if that aligns with the design decision here

To me, this is an explicit non-goal. People have attempted to do this, but this creates a combinatorial explosion of different incompatible tools and approaches. Beginners won't know what to choose, and advanced users will be frustrated there is not enough choice.

My motivation behind this is, CSS Modules is popularly adopted and a lot of people would want to use it in their project.

Are they good enough and easy enough to explain that we can make them a default for everyone? Every other single tool that we use, in my opinion, passes this test, but CSS Modules, as much as I like them, don't yet, in my opinion.

This is why we don't include them, and this is our philosophy in general. If we can't recommend something to everyone using React, or at least consider it a sane default while keeping in mind that for many people this is the first exposure to React, we don't add it.

Perhaps in a year CSS Modules will be obvious to everyone and we will get many requests from beginners to support them. Then we ship a codemod as yet another script that ports everyone's projects to use CSS Modules, and they become our default recommendation. I totally see this happening but not today. We need to pick our battles.

@insin
Contributor
insin commented Jul 18, 2016 edited

Likely first issues:

"Where's the hot reloading?"

One of the issues opened on the same day reactpack was posted on Show HN was related to not using the default ESLint presets they chose - how easy is it to disable it or use your own with the current setup? Code style can be a controversial topic, even if people have specifically asked for more opinions.

@gaearon
Contributor
gaearon commented Jul 18, 2016

We might eventually add hot reloading when it is stable enough but I don't think it should be a part of the official starter if it's hacky right now.

I do expect some people to ask for custom lint configuration but I'd rather not do it. Give in just a little, and you'll end up with a lot of configuration. It will be hard to draw the line where to say "yes" and where to say "no". React has never been opinionated so I think we have a right to release one very opinionated tool.

@eanplatter
Member
eanplatter commented Jul 18, 2016 edited

I do expect some people to ask for custom lint configuration but I'd rather not do it.

What is your thinking behind adding linting to begin with? It might make sense for it to be lint agnostic.

@mxstbr
Member
mxstbr commented Jul 18, 2016

It's a nicer dev experience, and the react community is pretty set on using airbnb. Imo that's fine!

@gaearon
Contributor
gaearon commented Jul 18, 2016

In my experience linting catches many mistakes. Beginners who are just getting started often don’t bother to configure a linter, and suffer from errors caused by simple typos.

Having control over linting also gives us the ability to introduce custom rules and potentially add API deprecations.

@eanplatter
Member

👍 is there a lint script in the users new project?

@gaearon
Contributor
gaearon commented Jul 18, 2016

No, we do linting as part of both npm start and npm run build. It’s done via eslint-loader.

So the user sees something like this when they save a file:

screen shot 2016-07-18 at 13 56 25

@gaearon
Contributor
gaearon commented Jul 18, 2016

If the project doesn’t crash, those warnings also show up in the console:

screen shot 2016-07-18 at 13 57 31

@eanplatter
Member

I guess they can always eject if they want to configure things themselves.

@lacker
Contributor
lacker commented Jul 18, 2016

I found the linting frustrating when I tried starting here and following along on other tutorials that don't follow the linting rules. Some of the rules like no-var and semi are in conflict with a lot of our own example code. What do you think about having lint hidden behind something like npm run lint?

In my experience of asking people, most folks do not use a linter. And most folks who say they use "airbnb lint" have actually customized it a bit.

@lacker
Contributor
lacker commented Jul 18, 2016

So right after I ran create-react-app, it had a file:/// dependency in the package.json. Is that supposed to happen when this is live, or is that an artifact of running it from npm run create-react-app? If it actually creates a project with a dependency on the creation tool which lives outside the repo, then I can't collaborate with other people on it.

@lacker
Contributor
lacker commented Jul 18, 2016

Also, I ejected pretty soon. Why not just eject right away? - I did not see any advantage of using the un-ejected version. The tool is already creating some boilerplate for me, it might as well create more.

@lacker
Contributor
lacker commented Jul 18, 2016

Also, how about rendering to a specific element rather than doing const rootEl = document.createElement('div'); document.body.appendChild(rootEl); render(<App />, rootEl);

That way you don't need to muck around with js code if you need to do something like add some custom html to your app.

@gaearon
Contributor
gaearon commented Jul 18, 2016 edited

So right after I ran create-react-app, it had a file:/// dependency in the package.json. Is that supposed to happen when this is live, or is that an artifact of running it from npm run create-react-app? If it actually creates a project with a dependency on the creation tool which lives outside the repo, then I can't collaborate with other people on it.

No, this is because packages are not on npm yet.
In the “normal” npm flow, you’d get a regular dependency.

@gaearon
Contributor
gaearon commented Jul 18, 2016 edited

Also, I ejected pretty soon. Why not just eject right away? - I did not see any advantage of using the un-ejected version. The tool is already creating some boilerplate for me, it might as well create more.

The number one complaint I heard about “JavaScript fatigue” is that there are tons of dependencies in package.json and you aren’t sure how/when to update them because they are often incompatible, each requires maintaining its own config, releases breaking changes, etc.

https://twitter.com/thomasfuchs/status/708675139253174273

Here is a good example of an issue like this. Somebody was trying to follow a “React for Beginners” starter guide but updated Babel and got a weird error: babel/babel-loader#255. If you hunt around, you’ll find hundreds of issues like this across different boilerplate projects, React, Redux, Babel, ESLint, etc.

If you’re comfortable configuring ESLint, Babel, and Webpack yourself, you can indeed eject right away. This is the level of utility already provided by the popular boilerplate projects. However, if you’re not used to those tools, having a bunch of complicated configs in your folder is very intimidating. I’m trying to provide a better experience for people who are just getting started with React and don’t want to customize anything—rather, they want somebody to hold their hand while they’re writing their first component. And providing the escape hatch turns it from a toy into a real tool.

Another intention is that we keep improving the default set of plugins over time. For example, we might switch to Webpack 2, or Babel 7, or ESLint 3, or whatever, at our own pace, at the same time ensuring they all work great together. This is something a user can’t easily do if they’re on their own unless they have an extensive knowledge of all those tools.

@gaearon
Contributor
gaearon commented Jul 18, 2016

Also, how about rendering to a specific element rather than doing const rootEl = document.createElement('div'); document.body.appendChild(rootEl); render(, rootEl);

That way you don't need to muck around with js code if you need to do something like add some custom html to your app.

I’m not sure what you mean. What kind of custom HTML? Why not do it in a React component instead? To be clear, this tool is targeted towards people creating greenfield single-page apps. React already has a good integration story; we just want to fix the “start from scratch” story.

We can change it for sure, but I’d like to better understand the use case you have in mind.

@lacker
Contributor
lacker commented Jul 18, 2016

I was thinking adding other libraries like analytics, where you often have noobs following some instructions of how to modify their html. It's a bit simpler to figure out what's happening if there is a div already in index.html that your app gets rendered to.

@lacker
Contributor
lacker commented Jul 18, 2016

Another intention is that we keep improving the default set of plugins over time. For example, we might switch to Webpack 2, or Babel 7, or ESLint 3, or whatever, at our own pace, at the same time ensuring they all work great together.

So the idea is that someone would be able to just upgrade their create-react-app-scripts dependency, and then they could get more modern stuff? That seems cool. If you can't upgrade this set of scripts, though, then it seems equivalent to saying "heres some boilerplate, just never update it".

@gaearon
Contributor
gaearon commented Jul 18, 2016

I found the linting frustrating when I tried starting here and following along on other tutorials that don't follow the linting rules. Some of the rules like no-var and semi are in conflict with a lot of our own example code. What do you think about having lint hidden behind something like npm run lint?

To be honest I would rather choose our own subset of rules that is more flexible about code style than remove linting altogether from the flow. In my experience of replying to issues on React and Redux repo, people often do mistakes that would be caught by a linter. A separate npm run lint wouldn’t help them because they wouldn’t run it.

In my experience of asking people, most folks do not use a linter. And most folks who say they use "airbnb lint" have actually customized it a bit.

I think there is a middle ground here: beginners and people who didn’t bother to use a linter because it is too complicated to set it up (e.g. ESLint didn’t work with ES6 until recently, babel-eslint integration was often buggy while it was necessary, etc).

Maybe my bet is off. I don’t know. But I feel like it’s better to start enforcing the lint, and later loosen it up, than start relaxed and later tighten it up. We can teach people that it is an opinionated tool, and this is what we think is the best way to start getting up to speed with React.

We use vars in the docs because our docs assume ES5. This is a different and separate issue: we do intend to update them, but we need a plausible “getting started” experience that includes ES6 for this. So it’s a bit of a chicken-and-egg problem.

I was thinking adding other libraries like analytics, where you often have noobs following some instructions of how to modify their html. It's a bit simpler to figure out what's happening if there is a div already in index.html that your app gets rendered to.

Perhaps. I thought the comment in index.html helps, does it not?

So the idea is that someone would be able to just upgrade their create-react-app-scripts dependency, and then they could get more modern stuff? That seems cool. If you can't upgrade this set of scripts, though, then it seems equivalent to saying "heres some boilerplate, just never update it".

Yes, the idea is that we release versions once in a while that track what’s going on in the ecosystem and put the best stable things together.

@lacker
Contributor
lacker commented Jul 18, 2016

To be honest I would rather choose our own subset of rules that is more flexible about code style than remove linting altogether from the flow.

Mmm that sounds good to me. I tried using the airbnb style on a sample app and found it was too strict for what I wanted - in particular I ended up disabling

"rules": { "arrow-body-style": 0, "new-cap": 0, "no-console": 0, "no-param-reassign": 0, "no-undef": 0, "no-useless-constructor": 0, "no-use-before-define": 0, "react/prefer-stateless-function": 0, },

Like, if we tell noobs they shouldn't use console.log, they will become sad.

I really like the idea that we can update these tools over time and thus not become dependent on eslint specifically.

Also I think it would be nice to try to use similar language presets for the default apps created by React and React Native - it'll just make it easier for anyone building or documenting a cross-environment library.

@gaearon
Contributor
gaearon commented Jul 18, 2016

Would you like to send a PR with the ESLint rule subset you find reasonable?

@lacker
Contributor
lacker commented Jul 18, 2016

Sure - not fair of me to gripe without offering to fix it ;-)

@vjeux
Collaborator
vjeux commented Jul 18, 2016 edited

I was going to say, we already have Facebook eslintrc on fbjs but it seems like every single of our open source project is using a different variation:

@kentcdodds
Member
kentcdodds commented Jul 18, 2016 edited

While you're at it, maybe you could add: "semi": [2, "never"] :trollface:
Sorry, someone had to say it. (But if that happened, I'd be pleased)

@gaearon
Contributor
gaearon commented Jul 18, 2016

I think our guideline should be: let’s ship ESLint warnings that help find bugs or avoid bugs in the future.

@lacker
Contributor
lacker commented Jul 18, 2016

Playing around, I find myself often deleting some of the autogenerated files, because I don't want some subset of App.js, App.css, index.css, logo.png. What do you think about simplifying the autogenerated stuff to just index.html and index.js in the main folder? (No src.) The pattern where you have your index files at the root and then other stuff is in a folder is how React Native typically works, for example. (E.g. https://github.com/fbsamples/f8app ) And that pattern seems fairly common for React apps too. E.g. https://github.com/reactjs/redux/tree/master/examples/todomvc That way people can decide if they want a "src" folder or what.

@gaearon
Contributor
gaearon commented Jul 19, 2016 edited

My intention was to bootstrap a project that shows:

  • How to create a component
  • How to import a component from another component
  • How to reference CSS
  • How to reference an image
  • How to render the root component to the DOM

Those are the most common questions I see about Webpack-based setups, and it is not obvious at all that you need to import CSS until you see it. So I think it’s important to explain it to people who never worked with Webpack.

If we don’t provide these, people will try adding images in local directory and expecting them to be available by paths like src='./logo.png', they will add CSS to index.html without realizing we already solve autoprefixing for them, and they will import components with named imports (import { App } from './App') while using default exports and be frustrated that this doesn’t work.

How do you think we could solve those problems without frustrating experienced users?

@gaearon
Contributor
gaearon commented Jul 19, 2016

FWIW I’m not completely opposed to CLI flags. create-react-app my-app --template empty is fine in my book because this lets us add more official examples later to get people started with something they can run and tweak.

@eanplatter
Member

I can't help but agree, it's easy to forget how valuable it is to see first hand how to do something like reference a CSS file in a React component.

Keeping the boilerplate as minimal as possible (like it currently is) is important. Perhaps some inline comments to help dispel any questions about the generates code itself?

@gaearon
Contributor
gaearon commented Jul 19, 2016

Let’s continue this discussion (on templates) in #24.

@lacker
Contributor
lacker commented Jul 19, 2016

So I am actually one of these webpack noobs, I haven't forgotten what it's like ;-)

Before using this tool I never included css and images with an import statement the way it works here. I'll admit it was helpful. I didn't realize there was "autoprefixing" going on, though. How exactly does that work? Is it just using the stuff in https://github.com/postcss/autoprefixer ? Perhaps just a brief comment explaining that would be helpful somewhere in the code.

Also, it was unclear to me whether the "src" directory is special in some way. I have used some webpack configs where you have to put everything in a certain directory, and some where it does not work that way. Is there any requirement besides the starting point being src/index.js? Like do other image / css files have to also be in the src directory? Personally I often prefer to not call the directory "src" because if you e.g. end up making a rails backend, your ruby code is also "src" and so it's confusing to call just one of your languages "src". Or for React Native.

@gaearon
Contributor
gaearon commented Jul 19, 2016

Before using this tool I never included css and images with an import statement the way it works here. I'll admit it was helpful. I didn't realize there was "autoprefixing" going on, though. How exactly does that work? Is it just using the stuff in https://github.com/postcss/autoprefixer ? Perhaps just a brief comment explaining that would be helpful somewhere in the code.

I think we need a “How To” document. It would explain the available features: ES modules, importing CSS, autoprefixing. It doesn’t need to be long, just needs to answer 10 common questions in a practical way.

Is there any requirement besides the starting point being src/index.js?

Having index.html and src/index.js is the only requirement. (Ideally we should check for their existence and crash with a descriptive message if either was not found.)

Like do other image / css files have to also be in the src directory?

All modules have to be there, src is where the code of your application is. We may want to introduce other top-level folders later, e.g. vendor for third party assets you want to reference directly from .html. This would be an escape hatch for scripts that aren’t on npm for some reason. We wouldn’t want webpack to look at those, so having a folder just for modules is useful.

Personally I often prefer to not call the directory "src" because if you e.g. end up making a rails backend, your ruby code is also "src" and so it's confusing to call just one of your languages "src". Or for React Native.

React Native is a very special case. I would probably go into direction of sharing code with React Native, so you’d still put your modules into src but “fork” components with build time flags. Other top-level directories could be used for RN-specific purposes (e.g. Xcode project). But I’m not very aware of RN project structure.

I don’t exclude that one day this will be ready to work with RN out of the box. We can rethink directory structure on that day, when we understand the constraints a little better.

As for Rails or Node, my intention is for the client to be treated as a separate “app” from its backend. So I would assume something like this:

my-awesome-app
  backend
    src
    config
    tasks
    email-templates
  frontend
    src
    vendor
    whatever
@insin
Contributor
insin commented Jul 20, 2016 edited

Do you have a longer-term scope in mind?

Assuming the first release is an opinionated starter, is a longer-term goal is to become the react-cli people keep asking for?

What I'd really like to see is something which handles the core development setup (and owns configuring the DX adds like HMR, auto-install) and can install opinionated project setups which build on top of that with their own configuration, starting you out from a skeleton, providing generators for whichever opinions it has, with codemods to keep code up to date as things evolve. It would also need to be configurable on top of that default where the opinions can be flexible.

The goal would be that the core development setup and opinionated project setup mean upgrading when dependencies change is just bumping a version number, with codemods when you need them as long as you've stuck with the opinions.

The way react-project provided glue code as a dependency rather than boilerplate was also really interesting to me.

@gaearon
Contributor
gaearon commented Jul 20, 2016

Assuming the first release is an opinionated starter, is a longer-term goal is to become the react-cli people keep asking for?

It is hard to say. I definitely don't want any plugin system (which is what Ember CLI is famous for). The intention is to free user from configuration and incompatibilities. It we replace this with another configuration system or another addon system with its own issues, we defeat the point. (No offense to Ember.)

What you describe sounds ambitious but it is very hard to pull off. I want to start small and see how it goes.

I don't think code generators are as valuable as people say they are. If you need to generate code it means your libraries aren't expressive enough. Stuff like "add new component" — what's wrong with just writing a function by hand? The only frustrating thing is remembering to import React when you use JSX but this would better be solved on the IDE level or with an "autofix" system.

I am definitely interested in "initial" templates as described in #24. They are not as flexible as code generators but are much less pain to maintain and create. These are just "examples" of integration with libraries.

So we will see how it goes. It's hard to say in advance. For now we want to solve the build configuration problem. If it is adequately solved, we can consider solving other problems (such as integrating runtime libraries) but we need to be careful not to inflate the scope of the project too much.

@insin
Contributor
insin commented Jul 20, 2016 edited

I definitely don't want any plugin system (which is what Ember CLI is famous for)

I don't think React even needs that in the same way Ember does - once Webpack is set up right, you just import and go instead of having to make stuff available to a template context. Largely the same thing with testing; once your tools are set up right, the actual tests are just import and use.

Stuff like "add new component" — what's wrong with just writing a function by hand?

I agree on generators for trivial things, I'm thinking more of when you have some conventions which are working for you, you need to do something which cuts across multiple modules and dependencies and you'd like to make it reusable across multiple projects. For example if I were to write an add section <path> <name> generator for the conventions I'm using in my main React project at work right now, it would:

  • Create src/routes/<path>/<name>.js, generating a component with a render() which will add <name> to the page title
  • Add a new <Route> definition to the appropriate place in src/routes/root.js which will code split the route component (so far, so Ember)
  • Going further, possibly have a few prompts:
    • "Does this section need a reducer?" - if so, take a name, create src/reducers/<name>.js as a duck module with the same layout as our other reducers, and also configure loading and injecting this reducer when the route first loads (and handling hot reloading setup), and create a suitable unit test skeleton.
    • "Does this section need a feature flag?" - (configure all the different places that needs to happen)
    • "Will this section appear on the main Navbar"? - (configure all the different places that needs to happen, including whether or not it's feature flagged)

Something like the above is a lot of work, but it mostly happens outside the global CLI and the module which solves the base build configuration problem, and it needs a way to hook into them or be hooked into by them. Just raising it now as the current template this project has is exactly as it should be IMO - here's your first component, the build stuff is handled for you, let rip - so it doesn't need these hooks.

@gaearon
Contributor
gaearon commented Jul 20, 2016

I think most of these points should be solved on the library level, not code generation level.
For example:

Add a new definition to the appropriate place in src/routes/root.js which will code split the route component (so far, so Ember)

This is a problem with having global configuration. Imagine React Router worked in a different “100% React” way and nested routes would be implemented as nested components, without centralized config. Then this wouldn’t be an issue because you’d just add a new route right in the component you are working on. (Something like this may or may not be in development right now—not by us though. I won’t spoil it further. 😉 )

"Does this section need a reducer?" - if so, take a name, create src/reducers/.js as a duck module with the same layout as our other reducers, and also configure loading and injecting this reducer when the route first loads (and handling hot reloading setup), and create a suitable unit test skeleton.

Again, this seems like a problem with React state model. Ideally I think we should make React more reducer-friendly so that it’s easy to describe local state with a reducer, and move a reducer across the components. Then you wouldn’t have to jump between the files.

To be clear, I’m not saying what you suggest is not valid. Somebody could implement a generator like this as another devDependency, and maybe we’d want to merge it in eventually. But I think the need for code generation is usually symptomatic of abstractions that are not expressive enough, and we might want to fix that instead.

@mxstbr
Member
mxstbr commented Jul 20, 2016

That's exactly what we do for our react-boilerplate generators – e.g. when you generate a container, it adds a bunch of files:

index.js     # Component itself, can either be function or class
actions.js
constants.js
reducer.js
test/        # The tests for all of those
  actions.test.js
  reducer.test.js
  component.test.js

Doing this manually every time is quite tedious, so having that automated and pre-populated with the correct data saves quite a bit of time!

@gaearon
Contributor
gaearon commented Jul 20, 2016

Redux is not a default way of using React. Quite the opposite, it is a very opinionated way of using it.
So we definitely won’t include any code generation for reducers / action creators / etc here.
We should improve React instead to address the shortcomings that make people go for Redux.

@gaearon
Contributor
gaearon commented Jul 20, 2016

That said nothing prevents somebody from creating react-redux-generator that would be another devDependency and generate this stuff.

@eanplatter
Member

Code generation can also fuel misinformation, it makes it easy for a user to be ignorant of the code in their app, this is especially an issue for beginners.

I think the need for code generation is usually symptomatic of abstractions that are not expressive enough, and we might want to fix that instead.

This is kind of the crux of it ☝️

If there are issues with React's usability we don't want to sweep them under the rug by just writing the code for you.

@mxstbr
Member
mxstbr commented Jul 20, 2016

Didn't mean to imply those generators should live here, sorry!

@gaearon
Contributor
gaearon commented Jul 20, 2016 edited

Haha no offence taken. 😄

@gaearon gaearon added the discussion label Jul 21, 2016
@montogeek
Contributor

What would be the testing library? Enzyme is a nice candidate :)

@gaearon
Contributor
gaearon commented Jul 22, 2016

Eventually, yes, but this will need more thought.

@SpencerCDixon

Are there any plans to eventually provide an "addon" abstraction like ember-cli has so that developers can build a community around the CLI or is that out of scope/not something this project should be concerned about?

@eanplatter
Member

There's been a little discussion on it here: #24

@mxstbr
Member
mxstbr commented Jul 22, 2016

See the discussions in #13, #24 and #55, I don't think we want to go down the route and make this a react-cli.

@gaearon
Contributor
gaearon commented Jul 22, 2016

I wouldn’t say it’s forever out of scope but definitely not this year. 😄

@roebuk
roebuk commented Jul 22, 2016 edited

First off, this is a great project, thank you for creating it.

Would it be worth outputting a webpack-stats.json file for ease of grabbing the built assets by other systems?

@gaearon
Contributor
gaearon commented Jul 22, 2016

@roebuk This sounds like a useful feature but we want to limit the ways we expose webpack so we could potentially replace it in the future. I’m not totally opposed to this though, especially if there was a more widely accepted simpler standard format for this.

@PhilipGarnero
PhilipGarnero commented Jul 22, 2016 edited

You guys are awesome ! I started react 3 days ago. I am really upset I didn't find this earlier. So much headaches and pointless questions would have been avoided.

This is very helpful ! Especially the readme. It would have saved me so much time if I read it when I begun. Keep improving it.

Keep your mind on newcomers, they'll be more than happy with what you provide.

The only thing is that I find a bit weird that the index.html and favicon.ico files are not inside src. I would have expected the root dir to be free of any sources or resources and only have conf files. But that's just me.

@kasperpeulen
Contributor

I just wanted to say that I love love love love this 💃 👍 🍰 🎉

@gaearon
Contributor
gaearon commented Jul 22, 2016

Thank you!
(By the way you didn't find this earlier because we released it a few hours ago)

@a-tarasyuk
a-tarasyuk commented Jul 22, 2016 edited

It is good starting point in standardization all react-boilerplate's. Thanks. I think would be very useful to have opportunity extend/override configs,. for instance for webpack, babel, eslint, and so on. I think community should discuss all features which this tool should have, and create good style guide.In my opinion we should have lightweight/extendable tool based on style guide, and extend it for own purposes

@pirelenito
Contributor

Interesting approach.

However I'm not sure it is a solution for the problem it is trying to fix. The way I see it, it is merely delaying it. As pointed by this thread, it will be much sooner than later that any project will require some minimum configuration, which will lead to an eject and the user is back to the "JavaScript fatigue" situation:

  • lot of files and configurations that are impossible to grasp;
  • very hard to keep the build system updated and with new fixes/improvements.

I think the problem we should try to solve are more geared towards "good configurable defaults". We sure can hide all the complexity of configuring tools behind a single dependency, but we must allow a level of configurability with formal escape hatches to disable and extend the default configuration.

Such approach does come with some drawbacks, as you will get more mileage if you stick to the proposed conventions (like the linting and the test tool), but once we look over the bike-shedding, the end result in a tool that just works.

And as has already been said in this thread, the point of such tools is not to provide a high level of customization, if you need so, you can use the underlying tools directly.

This is what I've been trying to solve in the past couple of months in a tool that I've iterated a couple of times already called Sagui. It is a single development dependency that is auto-bootstrapped (no global CLI) and provides all the requirements to build a modern JavaScript front-end application with Build, Optimization, Development Server with Hot reloading (with React support), Test, Coverage and more!

More importantly, it is already used in a couple of projects in production.

And the developers have the benefit of the continuous improvement of their working environment with a single npm install.

Would love to hear you thought on it as well, as I deeply respect your opinions! ❤️

tl;dr:

  • We can't run away from configurability: embrace good defaults but provide formal escape hatches;
  • Should be easily upgradeable: users can get constant improvements, like build speed, usability tweaks and bug fixes by just updating the dependency.
  • Reduce context overhead and leverage npm scripts: try not to introduce another global tool;
  • Don't try to create another plugin ecosystem: we already have Babel, Webpack and Karma;

@mxstbr: Your work on react-boilerplate has helped us a lot on building Sagui :)

@gaearon: You helped shape the current version of Sagui after a chat we have in React Europe, so thank you!

@gaearon
Contributor
gaearon commented Jul 22, 2016

There is a space for more than a single tool.
Let’s keep learning from each other’s work!

@PhilipGarnero

@pirelenito you should maybe try to be the next step after create react app. I'm pretty sure you could work something out with @gaearon to create a tool to migrate his tool to yours like eject but more like an upgrade.

@gaearon
Contributor
gaearon commented Jul 22, 2016

I think would be very useful to have opportunity easy extend/override configs,. for instance for webpack, babel, eslint, and so on.

Please see my reply in #99 (comment).

@pirelenito
Contributor

Interestingly, I was planning to do the same thing at one point, but abandoned it favor of some simple configuration options and formal escape hatches. Maybe you will end-up on a similar situation?

What do you think is the major drawback of a tool such as Sagui?

Thanks!

@kasperpeulen
Contributor
kasperpeulen commented Jul 22, 2016 edited

I think there is a real need for a project like this. I would keep the configuration as minimal as possible. One good reason, there doesn't exist much (or any) project like this. Maybe someone else makes some other starter project with more config options, but I think there should be a place in the javascript ecosystem for a minimal config tool like this.

I'm learning javascript for a couple of weeks, and I'm trying to write a project in ES2015/ES2016 + react, mainly for learning.

In this process of learning, I notice that I'm 75% learning about tools, and 25% learning about actual code and writing code. When I was learning iOS in Swift, this is what much different. I think 10% was about tools, but I felt productive right from the beginning, just coding and coding. Now I'm reading manuals about webpack, babel, autoprefixer, eslint, flow, live reloading etc. etc..

I know it is all helpful, because I love writing code in ES6 syntax, and I love catching errors at compile time. I love seeing my css changes right in a second in the browser, but it takes a lot of time before I actually get to write some code.

Then with boilerplate, this helps somewhat, but I don't feel comfortable having a boilerplate where 90% of the code I don't understand what is going on. All kind of test frameworks (I haven't spend any time learning javascript test frameworks yet). Karma, Mocha, gulp, rollup, commonjs, umd, whatever, ugh ... my brain just overloaded with names ... names that doesn't say anything to me, and where I feel like I should still read more about

So yes, I used react-scripts for a couple of hours, this, and I love it, it is clean, all the code in my own package I understand, that just feels good. Okay, there is probably some magic going on that I don't understand, but that is fine. I don't understand how chrome makes my html and javascript turn into a webapp, but that is none of my business. That is chrome's business. I don't understand how react-scripts makes my ES6 code work, how it gives me compile time errors, how it imports my css using javascript import, or how it add autoprefixers to my css, but it just works. And all that is now facebook's business. I just care about how to use it. Not how they made it work.

So this is one use case for react-scripts/create-react-app, people that are learning web programming in 2016 and learning ES2015/2016 syntax right from the beginning. What this provides is way to immediately start with learning how to code and don't worry much about tools yourself.

🎶🎶🎶
Let's start coding now,
everybody is learning how,
come on and safari with me.
🎶🎶🎶

https://www.youtube.com/watch?v=IMChBJZUDK8

@kirkaustin

Great project! Maintaining those configs is a real PITA. The only thing that's keeping me from embracing this is the lack of support for CSS Modules. I'm not sure I understand the objections, as it makes writing CSS rules much, much simpler for component-centric projects.

Also, I'd like more flexibility with the dev server. I'd like to add some proxy support to external web services using http-proxy, for instance.

@gaearon
Contributor
gaearon commented Jul 23, 2016

I'm not sure I understand the objections, as it makes writing CSS rules much, much simpler for component-centric projects.

Can you help me understand the problems they solve for you? Global class pollution, what else? Do you use composes?

@tlrobinson

Overall I love the idea of this project. I was sad @petehunt's rwb didn't seem to get much traction, so I'm glad to see a more official project with similar goals.

(Cross-posting the below from a HN comment. I haven't read through all the comments, apologies if this has been covered)

I think there will always be people who want to tweak ESLint rules or enable new Babel features, but would still like to take advantage of improvements to this project.

Perhaps exposing a subset of those tools' configuration options would be sufficient.

Alternatively, you could imagine a pretty simple system that allows you to pull newer versions of the "ejected" code and handle merge conflicts using your version control software.

I'd also suggest reducing the amount of non-configuration code that's generated by "eject". I think basically everything in "scripts" could be put into a package ("openChrome.applescript" seems like it should be a feature of opn anyway). That would also reduce the number of devDependencies that need to be added to your project's package.json (rimraf, chalk, opn, etc)

@kirkaustin

Global class pollution is the big win. Probably the best thing to happen to CSS since the beginning. Namespaces was one of the big wins when Java first appeared. I don't think anyone regrets that addition.

We have a few different groups writing reusable React components that can be shared. The problem of CSS collisions has led us down a path similar to BEM which requires verbose, nested class names.

The beauty of CSS Modules is that you not only avoid having to do that, but you end up using much simpler class names like ".icon" or ".content" which anyone can understand, not just engineers. We're trying to pull designers in the direction of using more CSS in the work that they provide, and we don't want to burden them with tools like SASS.

I haven't used composes myself, but it seems like it could be useful.

One other side benefit is that the development class names end up being verbose and easy to debug, while the production class names end up being very short and obfuscated.

@keyanzhang
Member

@gaearon CSS Modules is awesome. I have an example here that might be able to show you how it works in action: https://github.com/keyanzhang/repo.cat/tree/master/src/components/Main/Filters/SingleFilter

In the CSS file I no longer need to "BEM" my CSS selectors. I can simply name a selector .link and it's guaranteed to be local to the component that imports it.

For example, let's say I have 2 components Foo and Bar. Both of them have a link that needs to be styled but the 2 links don't share the same style.

Without CSS Modules I could import './styles.css'; in each component file, but I'll need to give them different classNames like fooLink, barLink to avoid global name collision. This doesn't feel quite right to me since I need to mentally track all my components and make sure I don't accidentally use the same className for actually different things.

With CSS Modules, a class name gets renamed to something like SingleFilter__link automatically at compile time. It effectively solves the global namespace issue and enables me to think locally from a true component perspective.

http://glenmaddern.com/articles/css-modules is another great article that explains this concept.

@kirkaustin

I think it's great that you're providing a less opinionated baseline for the configs, as I was never that comfortable with the airbnb solution. It might be worth considering allowing for some overrides, though. That way I could just add a small number of eslint rules that would be concatenated with your defaults if I wanted to customize.

@mxstbr
Member
mxstbr commented Jul 25, 2016

It might be worth considering allowing for some overrides, though. That way I could just add a small number of eslint rules that would be concatenated with your defaults if I wanted to customize.

We've actually disabled all stylistic eslint rules, so there should be no need to add custom config. If there's a stylistic rule warning you're seeing please let us know immediately and we'll disable it with the next release. (see e.g. #157)

@kirkaustin

Well, my point is that I would like to add my own stylistic rules. That means I would like to append those rules to the ones that are provided.

@gaearon
Contributor
gaearon commented Jul 25, 2016

Thanks, we’ll keep this feature request in mind. Unlike Babel/webpack extensions, allowing custom eslint config seems fairly straightforward and shouldn’t hurt us in the long run (I can’t really imagine we’d have a compelling reason to move away from eslint). In fact creating a custom .eslintrc that extends our config at react-scripts/config/eslint could already work. We’re not going to generate such config by default, but I think we might document a way of doing this some time in the future.

@kirkaustin

Great, that's exactly what I had in mind.

@Ethanjfriedman

As an instructor at a web dev bootcamp, just wanted to say this is great. 👍

The config swamp was a real hurdle for budding junior devs to get over in learning React -- understanding JSX, lifecycle methods, organizing their code into modules, etc. etc. is hard enough for someone with 2 months of coding under their belt without adding in messing around with Webpack and Babel. which topics we can layer in later.

@idibidiart

@gaearon

What is Facebook's position on using Shadow DOMnfor CSS encapsulation? Have you seen Maples.js? https://github.com/Wildhoney/Maple.js/

Would you consider moving to this approach at some point? Or why not now? :-)

@gaearon
Contributor
gaearon commented Jul 25, 2016

We are currently not planning to use Shadow DOM actively because it’s not supported by many our target browsers and requires global configuration. We may revisit this choice in the future.

@aweary
aweary commented Jul 25, 2016 edited

It'd be interesting if there was a potential extension/plugin system for creating apps with more specific use cases. Being able to do create-react-app --with-router or create-react-app --relay would be useful. Maintaining or supporting that kind of configurability might be difficult though, so an extension system where anyone could plug into the app build step and introduce dependencies/files/configuration would nice.

@gaearon
Contributor
gaearon commented Jul 25, 2016

@Aweary Please see #24

@KarolAltamirano

Awesome project guys, thanks for creating it. I have one question about the project structure. Wouldn't it be better to have index.html and favicon.ico inside src folder? I would personally prefer to have all react app files including index.html and favicon.ico inside src folder and directly in the root folder just files / folders related to dev process even though it will be just node_modules, package.json and README.md

@mxstbr
Member
mxstbr commented Jul 25, 2016

src contains all files that webpack treats as modules, which index.html and favicon.ico don't count towards!

@PhilipGarnero

@KarolAltamirano @mxstbr Does it prevent it from working ?

If not, the users aren't handling webpack at all so I don't see the problem. Sure from your point of view, it seems silly but from mine, having these two files laying there feels kinda weird.

This is not an issue anyway and just a matter of preferences.
If you think it is more logical that way, you're probably right.

Thanks for your job on this project, I love it.

@KarolAltamirano

@mxstbr @PhilipGarnero Yep, it depends on point of view and from both sides it can make sense. The reason why I prefer to have everything app related in the src folder is that when I start adding files like .gitignore, .gitattributes, .editorconfig to the root folder it will just feel a bit messy to me to have somewhere between these files also index.html and favicon.ico

Anyway I got your point about webpack modules and if you think it works better the way it is right now I'm okay with it. Just wanna share my point of view on structuring projects even though it's more about personal preference than an actual issue.

@gaearon
Contributor
gaearon commented Jul 25, 2016

I would personally prefer to have all react app files including index.html and favicon.ico inside src folder

It depends on point of view. If you look at it another way, neither index.html nor favicon.ico are “React app parts”. React app starts in your root component, the rest can be thought of as host environment.

You could twist it either way though. So for now the distinction we chose is that src only contain modules (things that import each other), and anything else goes into the top level. We may revisit this later.

@idibidiart

@gaearon

How do you approach style encapsulation for React components at Facebook? There is Radium which is for JS based style declaration and CSS Modules for creating isolated CSS scopes. Have you settled on a style encapsulation approach?

@vjeux
Collaborator
vjeux commented Jul 25, 2016 edited

@idibidiart take a look at the first part of this talk (the one about cx), this is how we deal with styles at Facebook on the web today: https://speakerdeck.com/vjeux/react-css-in-js

@mxstbr
Member
mxstbr commented Jul 26, 2016

@idibidiart also read #78 for a (long) discussion about this subject.

@idibidiart
idibidiart commented Jul 26, 2016 edited

@mxstbr thank you for pointing me to that discussion.

@vjeux @gaearon there is a subtlety to why something like CSS Modules (+React CSS Modules) is preferable to our (my team's) way of building apps, and it is based on some axioms our team has developed over time that are not universal.

So, at this point we're considering creating a live fork of create-react-app to add support for those tools.

Eject is an escape hatch (exactly what the name implies), not a customization option per se.

I realize what I'm suggesting is not an optimal answer but it's as close to one as we could find right now. :-)

@gaearon
Contributor
gaearon commented Jul 26, 2016

So, at this point we're considering creating a live fork of create-react-app to add support for those tools.

This is reasonable. (And we’ll keep an eye on popular forks.)

@trevordmiller
trevordmiller commented Jul 26, 2016 edited

My 2 cents on the philosophy and future of this project

TL;DR

🤘 React Create App rocks! I hope to see this project continue to be wary of "design by committee" and stick to only the officially standard tools as you have been doing :)


Full thoughts

group-hug

I just want to give you all a great big hug :)

I absolutely ❤️ ❤️ ❤️ React Create App. It is extremely valuable to have a minimal abstraction for config so that the React team can optimize under the hood and tie all the pieces together without breaking the public API (npm start, npm build, npm run eject). Thank you so much for building it!

While reading through some of the comments on this page and on Twitter, I completely agree that this project should stick with minimal + majority use cases and not get too bloated; for example, I'm happy to see the push back that has already happened on things like CSS Modules, Radium, or other non "standard" tools. Unless an approach / tool is a "blessed" (officially supported) way of doing things by the React team, it shouldn't be included with this project. Getting too bloated has been the downfall of every other boilerplate generator / CLI I've used. I think react-create-app should draw a line in the sand that it will only concern itself with what it already has done - the compilation process - Webpack, Babel, ESLint (lint preventing build/runtime errors only). Unless the React team is going to officially bless an approach for linting, testing, styles, state management etc, then it would make sense to be incorporated. I am happy to see this is already what is being done - the React team has a fantastic track record of great wisdom and restraint in their feature requests!

@trevordmiller
trevordmiller commented Jul 26, 2016 edited

My 2 cents on the customization problem

Obviously, people are going to have different needs for their projects; they can npm run eject but I think that ejecting should be viewed as a last resort because then your project loses the benefit of the config abstraction (access to continuous improvements, best practices, and updates from the CLI under the hood). I'd prefer to see react-create-app add a new feature for config composition of other configs to extend it's minimal out-of-the-box configs instead.

For example

The CLI could compose its configs with the user's package.json configs if it exists (ie if the eslintConfig property exists in the user's package.json, compose it with the react-create-app config). Same thing for the babel and webpack properties (might need to be a subset of setting properties).

@trevordmiller
trevordmiller commented Jul 26, 2016 edited

My 2 cents on linting

I think including ESLint as has been done is the right move as it helps prevent errors; however, this is a fine line to walk as linting can also be used for style etc. The rules being used now seem to be good, but why not just use the "extends": ["eslint:recommended", "plugin:react/recommended"] options instead of manually maintaining a list of rules in react-create-app? The requirements for a rule to be added to this recommended list by the ESLint team seem to be in-line with what react-create-app is looking for: "
image

As for allowing users to customize these rules, see my composition proposal in the My 2 cents on the customization problem comment above ^.

cc: @nzakas

@trevordmiller

@gaearon Would love to hear your thoughts on my last three comments above if you get a chance ^ :)

@PhilipGarnero

Which procedure to follow when putting a project on git (or any other vcs) ?
By that I mean, should we upload node_modules ? (I'm new to the js env and it looks like not everyone is thinking the same way)

If not, what do we do when we clone the project ?
I didn't find anything about this subject yet. For now, it seems like the only solution is to create a new project and then override it with files coming from git. It doesn't seem really convenient.

A new command would be nice to have or even a create-react-app .

What are your thoughts about this ?

I'm more inclined to not putting node_modules inside the git repo as we do in the python community but this doesn't seem like a good practice with js devs.

@lacker
Contributor
lacker commented Jul 27, 2016

@PhilipGarnero Don't upload node_modules to git. Instead, after cloning the project, run npm install immediately. I would recommend that workflow not just for create-react-app-based projects, but for any sort of version-controlled project using npm.

@Lakston
Lakston commented Jul 27, 2016

@PhilipGarnero I'll add to what @lacker said and recommend that you create a .gitignore file (either by hand or via github) and add node-modules to that file.

On github you can just click on add gitignore when creating your repo and chose node. You can also for exemple see my angular-twitch-viewer repo and copy/paste the gitignore file (it has a lot more than just node_modules).

@mxstbr
Member
mxstbr commented Jul 27, 2016

A .gitignore file will automatically be created with the new version. 👍

@gaearon
Contributor
gaearon commented Jul 27, 2016

why not just use the "extends": ["eslint:recommended", "plugin:react/recommended"] options instead of manually maintaining a list of rules in react-create-app?

We tried that 😉 . Some rules like no-console, no-empty, no-class-assign seemed too restrictive for beginners, especially considering the in-your-face nature of how we show the lint warnings. So we decided our own whitelist is easier.

@gaearon
Contributor
gaearon commented Jul 27, 2016

Same thing for the babel and webpack properties (might need to be a subset of setting properties).

Neither webpack nor babel configs compose well.

@Lakston
Lakston commented Jul 27, 2016

Some rules like no-console, no-empty, no-class-assign seemed too restrictive for beginners

And thanks for that !

I'm still having troubles configuring linting and syntax highlighting on Atom so I guess I' still don't quite understand how to link the app's config to my editor to have proper linting and hightlighting.

I'm guessing the linting rules apply only in npm ? I'm not sure to understand how to utilise the integrated lint rules into my editor.

@gaearon
Contributor
gaearon commented Jul 27, 2016

I'm still having troubles configuring linting and syntax highlighting on Atom so I guess I' still don't quite understand how to link the app's config to my editor to have proper linting and hightlighting.

Please see https://github.com/facebookincubator/create-react-app/blob/master/template/README.md#display-lint-output-in-the-editor.

This will be supported by default in projects created with 0.2.0 and higher (it’s not out yet).

In already created projects, you can paste this block into your package.json to get it working:

{
  // ...
  "eslintConfig": {
    "extends": "./node_modules/react-scripts/config/eslint.js"
  }
}

It will require that you use npm@3 though.

@elsigh
elsigh commented Jul 27, 2016 edited

Hey @gaearon =)

Trying this out this morning and love the idea and how it starts up and gets you immediately able/into writing code.

As someone intimately familiar with configuring and tweaking webpack, it's nice to not have to touch it to play around with it at all for a new project.

Can I add a +1 for flowtype integration? Do you guys have any stance on using typescript out of curiosity?

VSCode complains about the lack of an eslint config when I open the project dir, I tried the lines you pasted above but it still whines - is that package.json config going to output a projectdir/.eslintrc file?

@gaearon
Contributor
gaearon commented Jul 27, 2016

VSCode complains about the lack of an eslint config when I open the project dir, I tried the lines you pasted above but it still whines

Are you using npm 2 or npm 3?

@elsigh
elsigh commented Jul 27, 2016

$ npm --version
3.9.5

@gaearon
Contributor
gaearon commented Jul 27, 2016

Can I add a +1 for flowtype integration? Do you guys have any stance on using typescript out of curiosity?

One step at a time. Flow integration is already possible, it’s just a little awkward: https://github.com/facebookincubator/create-react-app/blob/master/template/README.md#add-flow. We’ll think more about static typing in the future but for now we need to solve more pressing issues.

@gaearon
Contributor
gaearon commented Jul 27, 2016

@elsigh Have you tried restarting VSCode? If it doesn‘t help I can download it and take a look.

@elsigh
elsigh commented Jul 27, 2016

Maybe it's worth a look for others, but not high-pri or anything - I don't know what VSCode adoption's like.

screen shot 2016-07-27 at 8 01 03 am

@gaearon
Contributor
gaearon commented Jul 27, 2016 edited

Does /Users/elsigh/src/dpxdt-config/node_modules/eslint-plugin-react exist? If not, is there a chance that when you first ran create-react-app, you were using npm 2? Could you please attach the npm ls output?

@elsigh
elsigh commented Jul 27, 2016 edited

image
I don't think I could've had npm2.

elsigh@Lindseys-MacBook-Pro-2:~/src/dpxdt-config $ npm ls


dpxdt-config@0.0.1 /Users/elsigh/src/dpxdt-config
├─┬ react@15.2.1
│ ├─┬ fbjs@0.8.3
│ │ ├── core-js@1.2.7
│ │ ├── immutable@3.8.1
│ │ ├─┬ isomorphic-fetch@2.2.1
│ │ │ ├─┬ node-fetch@1.5.3
│ │ │ │ ├─┬ encoding@0.1.12
│ │ │ │ │ └── iconv-lite@0.4.13
│ │ │ │ └── is-stream@1.1.0
│ │ │ └── whatwg-fetch@1.0.0
│ │ ├─┬ promise@7.1.1
│ │ │ └── asap@2.0.4
│ │ └── ua-parser-js@0.7.10
│ ├─┬ loose-envify@1.2.0
│ │ └── js-tokens@1.0.3
│ └── object-assign@4.1.0
├─┬ react-bootstrap@0.30.0
│ ├── babel-runtime@5.8.38
│ ├── classnames@2.2.5
│ ├── dom-helpers@2.4.0
│ ├── invariant@2.2.1
│ ├── keycode@2.1.2
│ ├── react-overlays@0.6.5
│ ├─┬ react-prop-types@0.3.2
│ │ └── warning@2.1.0
│ ├── uncontrollable@4.0.0
│ └── warning@3.0.0
├── react-dom@15.2.1
└─┬ react-scripts@0.1.0
  ├─┬ autoprefixer@6.3.7
  │ ├── browserslist@1.3.5
  │ ├── caniuse-db@1.0.30000506
  │ ├── normalize-range@0.1.2
  │ ├── num2fraction@1.2.2
  │ ├─┬ postcss@5.1.0
  │ │ └── js-base64@2.1.9
  │ └── postcss-value-parser@3.3.0
  ├─┬ babel-core@6.10.4
  │ ├─┬ babel-code-frame@6.11.0
  │ │ └── js-tokens@2.0.0
  │ ├─┬ babel-generator@6.11.4
  │ │ └─┬ detect-indent@3.0.1
  │ │   ├── get-stdin@4.0.1
  │ │   ├── minimist@1.2.0
  │ │   └─┬ repeating@1.1.3
  │ │     └── is-finite@1.0.1
  │ ├── babel-helpers@6.8.0
  │ ├── babel-messages@6.8.0
  │ ├─┬ babel-register@6.9.0
  │ │ ├── core-js@2.4.1
  │ │ ├─┬ home-or-tmp@1.0.0
  │ │ │ ├── os-tmpdir@1.0.1
  │ │ │ └── user-home@1.1.1
  │ │ └─┬ source-map-support@0.2.10
  │ │   └── source-map@0.1.32
  │ ├─┬ babel-runtime@6.9.2
  │ │ └── regenerator-runtime@0.9.5
  │ ├── babel-template@6.9.0
  │ ├─┬ babel-traverse@6.11.4
  │ │ ├── globals@8.18.0
  │ │ └─┬ invariant@2.2.1
  │ │   └─┬ loose-envify@1.2.0
  │ │     └── js-tokens@1.0.3
  │ ├─┬ babel-types@6.11.1
  │ │ └── to-fast-properties@1.0.2
  │ ├── babylon@6.8.4
  │ ├── convert-source-map@1.2.0
  │ ├─┬ debug@2.2.0
  │ │ └── ms@0.7.1
  │ ├── json5@0.4.0
  │ ├── lodash@4.13.1
  │ ├─┬ minimatch@3.0.2
  │ │ └─┬ brace-expansion@1.1.5
  │ │   ├── balanced-match@0.4.2
  │ │   └── concat-map@0.0.1
  │ ├── path-exists@1.0.0
  │ ├── path-is-absolute@1.0.0
  │ ├── private@0.1.6
  │ ├── shebang-regex@1.0.0
  │ ├── slash@1.0.0
  │ └── source-map@0.5.6
  ├─┬ babel-eslint@6.1.2
  │ ├─┬ lodash.assign@4.0.9
  │ │ ├── lodash.keys@4.0.7
  │ │ └── lodash.rest@4.0.3
  │ └─┬ lodash.pickby@4.4.0
  │   ├─┬ lodash._baseiteratee@4.7.0
  │   │ └── lodash._stringtopath@4.8.0
  │   └── lodash.keysin@4.1.4
  ├─┬ babel-loader@6.2.4
  │ ├─┬ loader-utils@0.2.15
  │ │ ├── big.js@3.1.3
  │ │ ├── emojis-list@2.0.1
  │ │ └── json5@0.5.0
  │ ├─┬ mkdirp@0.5.1
  │ │ └── minimist@0.0.8
  │ └── object-assign@4.1.0
  ├── babel-plugin-syntax-trailing-function-commas@6.8.0
  ├─┬ babel-plugin-transform-class-properties@6.10.2
  │ └── babel-plugin-syntax-class-properties@6.8.0
  ├─┬ babel-plugin-transform-object-rest-spread@6.8.0
  │ └── babel-plugin-syntax-object-rest-spread@6.8.0
  ├── babel-plugin-transform-react-constant-elements@6.9.1
  ├─┬ babel-preset-es2015@6.9.0
  │ ├── babel-plugin-check-es2015-constants@6.8.0
  │ ├── babel-plugin-transform-es2015-arrow-functions@6.8.0
  │ ├── babel-plugin-transform-es2015-block-scoped-functions@6.8.0
  │ ├── babel-plugin-transform-es2015-block-scoping@6.10.1
  │ ├─┬ babel-plugin-transform-es2015-classes@6.9.0
  │ │ ├── babel-helper-define-map@6.9.0
  │ │ ├── babel-helper-function-name@6.8.0
  │ │ ├── babel-helper-optimise-call-expression@6.8.0
  │ │ └── babel-helper-replace-supers@6.8.0
  │ ├── babel-plugin-transform-es2015-computed-properties@6.8.0
  │ ├── babel-plugin-transform-es2015-destructuring@6.9.0
  │ ├── babel-plugin-transform-es2015-duplicate-keys@6.8.0
  │ ├── babel-plugin-transform-es2015-for-of@6.8.0
  │ ├── babel-plugin-transform-es2015-function-name@6.9.0
  │ ├── babel-plugin-transform-es2015-literals@6.8.0
  │ ├─┬ babel-plugin-transform-es2015-modules-commonjs@6.10.3
  │ │ └── babel-plugin-transform-strict-mode@6.11.3
  │ ├── babel-plugin-transform-es2015-object-super@6.8.0
  │ ├─┬ babel-plugin-transform-es2015-parameters@6.11.4
  │ │ ├─┬ babel-helper-call-delegate@6.8.0
  │ │ │ └── babel-helper-hoist-variables@6.8.0
  │ │ └── babel-helper-get-function-arity@6.8.0
  │ ├── babel-plugin-transform-es2015-shorthand-properties@6.8.0
  │ ├── babel-plugin-transform-es2015-spread@6.8.0
  │ ├─┬ babel-plugin-transform-es2015-sticky-regex@6.8.0
  │ │ └── babel-helper-regex@6.9.0
  │ ├── babel-plugin-transform-es2015-template-literals@6.8.0
  │ ├── babel-plugin-transform-es2015-typeof-symbol@6.8.0
  │ ├─┬ babel-plugin-transform-es2015-unicode-regex@6.11.0
  │ │ └─┬ regexpu-core@2.0.0
  │ │   ├── regenerate@1.3.1
  │ │   ├── regjsgen@0.2.0
  │ │   └─┬ regjsparser@0.1.5
  │ │     └── jsesc@0.5.0
  │ └─┬ babel-plugin-transform-regenerator@6.11.4
  │   ├── babel-core@6.11.4
  │   └── babel-plugin-syntax-async-functions@6.8.0
  ├─┬ babel-preset-es2016@6.11.3
  │ └─┬ babel-plugin-transform-exponentiation-operator@6.8.0
  │   ├─┬ babel-helper-builder-binary-assignment-operator-visitor@6.8.0
  │   │ └── babel-helper-explode-assignable-expression@6.8.0
  │   └── babel-plugin-syntax-exponentiation-operator@6.8.0
  ├─┬ babel-preset-react@6.11.1
  │ ├── babel-plugin-syntax-flow@6.8.0
  │ ├── babel-plugin-syntax-jsx@6.8.0
  │ ├── babel-plugin-transform-flow-strip-types@6.8.0
  │ ├── babel-plugin-transform-react-display-name@6.8.0
  │ ├─┬ babel-plugin-transform-react-jsx@6.8.0
  │ │ └── babel-helper-builder-react-jsx@6.9.0
  │ ├── babel-plugin-transform-react-jsx-self@6.11.0
  │ └── babel-plugin-transform-react-jsx-source@6.9.0
  ├─┬ chalk@1.1.3
  │ ├── ansi-styles@2.2.1
  │ ├── escape-string-regexp@1.0.5
  │ ├─┬ has-ansi@2.0.0
  │ │ └── ansi-regex@2.0.0
  │ ├── strip-ansi@3.0.1
  │ └── supports-color@2.0.0
  ├─┬ cross-spawn@4.0.0
  │ ├─┬ lru-cache@4.0.1
  │ │ ├── pseudomap@1.0.2
  │ │ └── yallist@2.0.0
  │ └─┬ which@1.2.10
  │   └── isexe@1.1.2
  ├─┬ css-loader@0.23.1
  │ ├─┬ css-selector-tokenizer@0.5.4
  │ │ ├── cssesc@0.1.0
  │ │ └── fastparse@1.1.1
  │ ├─┬ cssnano@3.7.3
  │ │ ├── decamelize@1.2.0
  │ │ ├── defined@1.0.0
  │ │ ├── indexes-of@1.0.1
  │ │ ├─┬ postcss-calc@5.3.0
  │ │ │ ├── postcss-message-helpers@2.0.0
  │ │ │ └─┬ reduce-css-calc@1.2.4
  │ │ │   ├── balanced-match@0.1.0
  │ │ │   └─┬ reduce-function-call@1.0.1
  │ │ │     └── balanced-match@0.1.0
  │ │ ├─┬ postcss-colormin@2.2.0
  │ │ │ └─┬ colormin@1.1.1
  │ │ │   ├─┬ color@0.11.3
  │ │ │   │ ├── color-convert@1.3.1
  │ │ │   │ └─┬ color-string@0.3.0
  │ │ │   │   └── color-name@1.1.1
  │ │ │   └── css-color-names@0.0.4
  │ │ ├── postcss-convert-values@2.4.0
  │ │ ├── postcss-discard-comments@2.0.4
  │ │ ├── postcss-discard-duplicates@2.0.1
  │ │ ├── postcss-discard-empty@2.1.0
  │ │ ├── postcss-discard-overridden@0.1.1
  │ │ ├─┬ postcss-discard-unused@2.2.1
  │ │ │ ├── flatten@1.0.2
  │ │ │ └── uniqs@2.0.0
  │ │ ├─┬ postcss-filter-plugins@2.0.1
  │ │ │ └─┬ uniqid@3.1.0
  │ │ │   └── macaddress@0.2.8
  │ │ ├─┬ postcss-merge-idents@2.1.6
  │ │ │ └── has-own@1.0.0
  │ │ ├── postcss-merge-longhand@2.0.1
  │ │ ├─┬ postcss-merge-rules@2.0.10
  │ │ │ └── vendors@1.0.0
  │ │ ├── postcss-minify-font-values@1.0.5
  │ │ ├── postcss-minify-gradients@1.0.3
  │ │ ├─┬ postcss-minify-params@1.0.4
  │ │ │ └── alphanum-sort@1.0.2
  │ │ ├─┬ postcss-minify-selectors@2.0.5
  │ │ │ └─┬ postcss-selector-parser@2.1.1
  │ │ │   └── uniq@1.0.1
  │ │ ├── postcss-normalize-charset@1.1.0
  │ │ ├─┬ postcss-normalize-url@3.0.7
  │ │ │ ├── is-absolute-url@2.0.0
  │ │ │ └─┬ normalize-url@1.6.0
  │ │ │   ├── prepend-http@1.0.4
  │ │ │   ├─┬ query-string@4.2.2
  │ │ │   │ └── strict-uri-encode@1.1.0
  │ │ │   └─┬ sort-keys@1.1.2
  │ │ │     └── is-plain-obj@1.1.0
  │ │ ├── postcss-ordered-values@2.2.1
  │ │ ├── postcss-reduce-idents@2.3.0
  │ │ ├── postcss-reduce-initial@1.0.0
  │ │ ├── postcss-reduce-transforms@1.0.3
  │ │ ├─┬ postcss-svgo@2.1.4
  │ │ │ ├─┬ is-svg@2.0.1
  │ │ │ │ └── html-comment-regex@1.1.1
  │ │ │ └─┬ svgo@0.6.6
  │ │ │   ├─┬ coa@1.0.1
  │ │ │   │ └── q@1.4.1
  │ │ │   ├── colors@1.1.2
  │ │ │   ├─┬ csso@2.0.0
  │ │ │   │ └── clap@1.1.1
  │ │ │   ├── sax@1.2.1
  │ │ │   └── whet.extend@0.9.9
  │ │ ├── postcss-unique-selectors@2.0.2
  │ │ └── postcss-zindex@2.1.1
  │ ├─┬ lodash.camelcase@3.0.1
  │ │ └─┬ lodash._createcompounder@3.0.0
  │ │   ├─┬ lodash.deburr@3.2.0
  │ │   │ └── lodash._root@3.0.1
  │ │   └── lodash.words@3.2.0
  │ ├── postcss-modules-extract-imports@1.0.1
  │ ├─┬ postcss-modules-local-by-default@1.1.1
  │ │ └─┬ css-selector-tokenizer@0.6.0
  │ │   └── regexpu-core@1.0.0
  │ ├─┬ postcss-modules-scope@1.0.2
  │ │ └─┬ css-selector-tokenizer@0.6.0
  │ │   └── regexpu-core@1.0.0
  │ ├─┬ postcss-modules-values@1.1.3
  │ │ └── icss-replace-symbols@1.0.2
  │ └── source-list-map@0.1.6
  ├─┬ eslint@3.1.1
  │ ├─┬ concat-stream@1.5.1
  │ │ ├── inherits@2.0.1
  │ │ ├─┬ readable-stream@2.0.6
  │ │ │ ├── core-util-is@1.0.2
  │ │ │ ├── process-nextick-args@1.0.7
  │ │ │ └── util-deprecate@1.0.2
  │ │ └── typedarray@0.0.6
  │ ├─┬ doctrine@1.2.2
  │ │ ├── esutils@1.1.6
  │ │ └── isarray@1.0.0
  │ ├─┬ es6-map@0.1.4
  │ │ ├── d@0.1.1
  │ │ ├── es5-ext@0.10.12
  │ │ ├── es6-iterator@2.0.0
  │ │ ├── es6-symbol@3.1.0
  │ │ └── event-emitter@0.3.4
  │ ├─┬ escope@3.6.0
  │ │ ├── es6-weak-map@2.0.1
  │ │ └─┬ esrecurse@4.1.0
  │ │   └── estraverse@4.1.1
  │ ├─┬ espree@3.1.6
  │ │ └── acorn-jsx@3.0.1
  │ ├── estraverse@4.2.0
  │ ├── esutils@2.0.2
  │ ├─┬ file-entry-cache@1.2.4
  │ │ └─┬ flat-cache@1.0.10
  │ │   ├─┬ del@2.2.1
  │ │   │ ├─┬ globby@5.0.0
  │ │   │ │ └─┬ array-union@1.0.2
  │ │   │ │   └── array-uniq@1.0.3
  │ │   │ ├── is-path-cwd@1.0.0
  │ │   │ ├─┬ is-path-in-cwd@1.0.0
  │ │   │ │ └── is-path-inside@1.0.0
  │ │   │ └── pify@2.3.0
  │ │   ├── read-json-sync@1.1.1
  │ │   └── write@0.2.1
  │ ├─┬ glob@7.0.5
  │ │ ├── fs.realpath@1.0.0
  │ │ ├─┬ inflight@1.0.5
  │ │ │ └── wrappy@1.0.2
  │ │ └── once@1.3.3
  │ ├── globals@9.9.0
  │ ├── ignore@3.1.3
  │ ├── imurmurhash@0.1.4
  │ ├─┬ inquirer@0.12.0
  │ │ ├── ansi-escapes@1.4.0
  │ │ ├─┬ cli-cursor@1.0.2
  │ │ │ └─┬ restore-cursor@1.0.1
  │ │ │   ├── exit-hook@1.1.1
  │ │ │   └── onetime@1.1.0
  │ │ ├── cli-width@2.1.0
  │ │ ├── figures@1.7.0
  │ │ ├─┬ readline2@1.0.1
  │ │ │ ├─┬ code-point-at@1.0.0
  │ │ │ │ └── number-is-nan@1.0.0
  │ │ │ ├── is-fullwidth-code-point@1.0.0
  │ │ │ └── mute-stream@0.0.5
  │ │ ├── run-async@0.1.0
  │ │ ├── rx-lite@3.1.2
  │ │ ├── string-width@1.0.1
  │ │ └── through@2.3.8
  │ ├─┬ is-my-json-valid@2.13.1
  │ │ ├── generate-function@2.0.0
  │ │ ├─┬ generate-object-property@1.2.0
  │ │ │ └── is-property@1.0.2
  │ │ ├── jsonpointer@2.0.0
  │ │ └── xtend@4.0.1
  │ ├─┬ is-resolvable@1.0.0
  │ │ └── tryit@1.0.2
  │ ├─┬ js-yaml@3.6.1
  │ │ ├─┬ argparse@1.0.7
  │ │ │ └── sprintf-js@1.0.3
  │ │ └── esprima@2.7.2
  │ ├─┬ json-stable-stringify@1.0.1
  │ │ └── jsonify@0.0.0
  │ ├─┬ levn@0.3.0
  │ │ ├── prelude-ls@1.1.2
  │ │ └── type-check@0.3.2
  │ ├─┬ optionator@0.8.1
  │ │ ├── deep-is@0.1.3
  │ │ ├── fast-levenshtein@1.1.3
  │ │ └── wordwrap@1.0.0
  │ ├── path-is-inside@1.0.1
  │ ├── pluralize@1.2.1
  │ ├── progress@1.1.8
  │ ├─┬ require-uncached@1.0.2
  │ │ ├─┬ caller-path@0.1.0
  │ │ │ └── callsites@0.2.0
  │ │ └── resolve-from@1.0.1
  │ ├── shelljs@0.6.0
  │ ├── strip-bom@3.0.0
  │ ├── strip-json-comments@1.0.4
  │ ├─┬ table@3.7.8
  │ │ ├── slice-ansi@0.0.4
  │ │ ├── tv4@1.2.7
  │ │ └── xregexp@3.1.1
  │ ├── text-table@0.2.0
  │ └─┬ user-home@2.0.0
  │   └── os-homedir@1.0.1
  ├── eslint-loader@1.4.1
  ├─┬ eslint-plugin-import@1.10.3
  │ ├── builtin-modules@1.1.1
  │ ├── contains-path@0.1.0
  │ ├── es6-set@0.1.4
  │ ├─┬ eslint-import-resolver-node@0.2.2
  │ │ └── resolve@1.1.7
  │ ├── lodash.cond@4.4.0
  │ ├─┬ lodash.endswith@4.1.0
  │ │ ├── lodash._basetostring@4.12.0
  │ │ └── lodash.tostring@4.1.3
  │ ├─┬ lodash.find@4.4.0
  │ │ ├── lodash._baseeach@4.1.3
  │ │ ├── lodash._basefind@3.0.0
  │ │ └── lodash._basefindindex@3.6.0
  │ ├── lodash.findindex@4.4.0
  │ ├─┬ pkg-dir@1.0.0
  │ │ └─┬ find-up@1.1.2
  │ │   └── path-exists@2.1.0
  │ └── pkg-up@1.0.0
  ├─┬ eslint-plugin-react@5.2.2
  │ └── jsx-ast-utils@1.3.1
  ├─┬ extract-text-webpack-plugin@1.0.1
  │ ├── async@1.5.2
  │ └── webpack-sources@0.1.2
  ├── file-loader@0.9.0
  ├─┬ fs-extra@0.30.0
  │ ├── graceful-fs@4.1.4
  │ ├── jsonfile@2.3.1
  │ └── klaw@1.3.0
  ├─┬ fsevents@1.0.14
  │ ├── nan@2.4.0
  │ └─┬ node-pre-gyp@0.6.29
  │   ├─┬ mkdirp@0.5.1
  │   │ └── minimist@0.0.8
  │   ├─┬ nopt@3.0.6
  │   │ └── abbrev@1.0.9
  │   ├─┬ npmlog@3.1.2
  │   │ ├─┬ are-we-there-yet@1.1.2
  │   │ │ └── delegates@1.0.0
  │   │ ├── console-control-strings@1.1.0
  │   │ ├─┬ gauge@2.6.0
  │   │ │ ├── aproba@1.0.4
  │   │ │ ├── has-color@0.1.7
  │   │ │ ├── has-unicode@2.0.1
  │   │ │ ├── object-assign@4.1.0
  │   │ │ ├── signal-exit@3.0.0
  │   │ │ ├─┬ string-width@1.0.1
  │   │ │ │ ├─┬ code-point-at@1.0.0
  │   │ │ │ │ └── number-is-nan@1.0.0
  │   │ │ │ └── is-fullwidth-code-point@1.0.0
  │   │ │ ├─┬ strip-ansi@3.0.1
  │   │ │ │ └── ansi-regex@2.0.0
  │   │ │ └── wide-align@1.1.0
  │   │ └── set-blocking@2.0.0
  │   ├─┬ rc@1.1.6
  │   │ ├── deep-extend@0.4.1
  │   │ ├── ini@1.3.4
  │   │ ├── minimist@1.2.0
  │   │ └── strip-json-comments@1.0.4
  │   ├─┬ request@2.73.0
  │   │ ├── aws-sign2@0.6.0
  │   │ ├── aws4@1.4.1
  │   │ ├─┬ bl@1.1.2
  │   │ │ └── readable-stream@2.0.6
  │   │ ├── caseless@0.11.0
  │   │ ├─┬ combined-stream@1.0.5
  │   │ │ └── delayed-stream@1.0.0
  │   │ ├── extend@3.0.0
  │   │ ├── forever-agent@0.6.1
  │   │ ├─┬ form-data@1.0.0-rc4
  │   │ │ └── async@1.5.2
  │   │ ├─┬ har-validator@2.0.6
  │   │ │ ├─┬ chalk@1.1.3
  │   │ │ │ ├── ansi-styles@2.2.1
  │   │ │ │ ├── escape-string-regexp@1.0.5
  │   │ │ │ ├── has-ansi@2.0.0
  │   │ │ │ └── supports-color@2.0.0
  │   │ │ ├─┬ commander@2.9.0
  │   │ │ │ └── graceful-readlink@1.0.1
  │   │ │ ├─┬ is-my-json-valid@2.13.1
  │   │ │ │ ├── generate-function@2.0.0
  │   │ │ │ ├─┬ generate-object-property@1.2.0
  │   │ │ │ │ └── is-property@1.0.2
  │   │ │ │ ├── jsonpointer@2.0.0
  │   │ │ │ └── xtend@4.0.1
  │   │ │ └─┬ pinkie-promise@2.0.1
  │   │ │   └── pinkie@2.0.4
  │   │ ├─┬ hawk@3.1.3
  │   │ │ ├── boom@2.10.1
  │   │ │ ├── cryptiles@2.0.5
  │   │ │ ├── hoek@2.16.3
  │   │ │ └── sntp@1.0.9
  │   │ ├─┬ http-signature@1.1.1
  │   │ │ ├── assert-plus@0.2.0
  │   │ │ ├─┬ jsprim@1.3.0
  │   │ │ │ ├── extsprintf@1.0.2
  │   │ │ │ ├── json-schema@0.2.2
  │   │ │ │ └── verror@1.3.6
  │   │ │ └─┬ sshpk@1.8.3
  │   │ │   ├── asn1@0.2.3
  │   │ │   ├── assert-plus@1.0.0
  │   │ │   ├─┬ dashdash@1.14.0
  │   │ │   │ └── assert-plus@1.0.0
  │   │ │   ├── ecc-jsbn@0.1.1
  │   │ │   ├─┬ getpass@0.1.6
  │   │ │   │ └── assert-plus@1.0.0
  │   │ │   ├── jodid25519@1.0.2
  │   │ │   ├── jsbn@0.1.0
  │   │ │   └── tweetnacl@0.13.3
  │   │ ├── is-typedarray@1.0.0
  │   │ ├── isstream@0.1.2
  │   │ ├── json-stringify-safe@5.0.1
  │   │ ├─┬ mime-types@2.1.11
  │   │ │ └── mime-db@1.23.0
  │   │ ├── node-uuid@1.4.7
  │   │ ├── oauth-sign@0.8.2
  │   │ ├── qs@6.2.0
  │   │ ├── stringstream@0.0.5
  │   │ ├── tough-cookie@2.2.2
  │   │ └── tunnel-agent@0.4.3
  │   ├─┬ rimraf@2.5.3
  │   │ └─┬ glob@7.0.5
  │   │   ├── fs.realpath@1.0.0
  │   │   ├── inflight@1.0.5
  │   │   ├─┬ minimatch@3.0.2
  │   │   │ └─┬ brace-expansion@1.1.5
  │   │   │   ├── balanced-match@0.4.2
  │   │   │   └── concat-map@0.0.1
  │   │   └── path-is-absolute@1.0.0
  │   ├── semver@5.2.0
  │   ├─┬ tar@2.2.1
  │   │ ├── block-stream@0.0.9
  │   │ ├─┬ fstream@1.0.10
  │   │ │ └── graceful-fs@4.1.4
  │   │ └── inherits@2.0.1
  │   └─┬ tar-pack@3.1.4
  │     ├─┬ debug@2.2.0
  │     │ └── ms@0.7.1
  │     ├── fstream-ignore@1.0.5
  │     ├─┬ once@1.3.3
  │     │ └── wrappy@1.0.2
  │     ├─┬ readable-stream@2.1.4
  │     │ ├── buffer-shims@1.0.0
  │     │ ├── core-util-is@1.0.2
  │     │ ├── isarray@1.0.0
  │     │ ├── process-nextick-args@1.0.7
  │     │ ├── string_decoder@0.10.31
  │     │ └── util-deprecate@1.0.2
  │     └── uid-number@0.0.6
  ├─┬ html-webpack-plugin@2.22.0
  │ ├── bluebird@3.4.1
  │ ├─┬ html-minifier@2.1.7
  │ │ ├─┬ change-case@3.0.0
  │ │ │ ├── camel-case@3.0.0
  │ │ │ ├── constant-case@2.0.0
  │ │ │ ├── dot-case@2.1.0
  │ │ │ ├── header-case@1.0.0
  │ │ │ ├── is-lower-case@1.1.3
  │ │ │ ├── is-upper-case@1.1.2
  │ │ │ ├── lower-case@1.1.3
  │ │ │ ├── lower-case-first@1.0.2
  │ │ │ ├── no-case@2.3.0
  │ │ │ ├── param-case@2.1.0
  │ │ │ ├── pascal-case@2.0.0
  │ │ │ ├── path-case@2.1.0
  │ │ │ ├── sentence-case@2.1.0
  │ │ │ ├── snake-case@2.1.0
  │ │ │ ├── swap-case@1.1.2
  │ │ │ ├── title-case@2.1.0
  │ │ │ ├── upper-case@1.1.3
  │ │ │ └── upper-case-first@1.1.2
  │ │ ├─┬ clean-css@3.4.18
  │ │ │ ├── commander@2.8.1
  │ │ │ └── source-map@0.4.4
  │ │ ├─┬ commander@2.9.0
  │ │ │ └── graceful-readlink@1.0.1
  │ │ ├── he@1.1.0
  │ │ ├─┬ ncname@1.0.0
  │ │ │ └── xml-char-classes@1.0.0
  │ │ └── relateurl@0.2.7
  │ ├─┬ pretty-error@2.0.0
  │ │ ├─┬ renderkid@2.0.0
  │ │ │ ├─┬ css-select@1.2.0
  │ │ │ │ ├── boolbase@1.0.0
  │ │ │ │ ├── css-what@2.1.0
  │ │ │ │ ├─┬ domutils@1.5.1
  │ │ │ │ │ └─┬ dom-serializer@0.1.0
  │ │ │ │ │   ├── domelementtype@1.1.3
  │ │ │ │ │   └── entities@1.1.1
  │ │ │ │ └── nth-check@1.0.1
  │ │ │ ├─┬ dom-converter@0.1.4
  │ │ │ │ └── utila@0.3.3
  │ │ │ ├─┬ htmlparser2@3.3.0
  │ │ │ │ ├── domelementtype@1.3.0
  │ │ │ │ ├── domhandler@2.1.0
  │ │ │ │ ├── domutils@1.1.6
  │ │ │ │ └─┬ readable-stream@1.0.34
  │ │ │ │   └── isarray@0.0.1
  │ │ │ └── utila@0.3.3
  │ │ └── utila@0.4.0
  │ └── toposort@1.0.0
  ├── json-loader@0.5.4
  ├─┬ opn@4.0.2
  │ └─┬ pinkie-promise@2.0.1
  │   └── pinkie@2.0.4
  ├── postcss-loader@0.9.1
  ├── rimraf@2.5.3
  ├── style-loader@0.13.1
  ├─┬ url-loader@0.5.7
  │ └── mime@1.2.11
  ├─┬ webpack@1.13.1
  │ ├── acorn@3.2.0
  │ ├── async@1.5.2
  │ ├── clone@1.0.2
  │ ├─┬ enhanced-resolve@0.9.1
  │ │ └── memory-fs@0.2.0
  │ ├── interpret@0.6.6
  │ ├─┬ memory-fs@0.3.0
  │ │ └─┬ errno@0.1.4
  │ │   └── prr@0.0.0
  │ ├─┬ node-libs-browser@0.5.3
  │ │ ├── assert@1.4.1
  │ │ ├─┬ browserify-zlib@0.1.4
  │ │ │ └── pako@0.2.8
  │ │ ├─┬ buffer@3.6.0
  │ │ │ ├── base64-js@0.0.8
  │ │ │ └── ieee754@1.1.6
  │ │ ├─┬ console-browserify@1.1.0
  │ │ │ └── date-now@0.1.4
  │ │ ├── constants-browserify@0.0.1
  │ │ ├─┬ crypto-browserify@3.2.8
  │ │ │ ├── pbkdf2-compat@2.0.1
  │ │ │ ├── ripemd160@0.2.0
  │ │ │ └── sha.js@2.2.6
  │ │ ├── domain-browser@1.1.7
  │ │ ├── events@1.1.1
  │ │ ├─┬ http-browserify@1.7.0
  │ │ │ └── Base64@0.2.1
  │ │ ├── https-browserify@0.0.0
  │ │ ├── os-browserify@0.1.2
  │ │ ├── path-browserify@0.0.0
  │ │ ├── process@0.11.5
  │ │ ├── punycode@1.4.1
  │ │ ├── querystring-es3@0.2.1
  │ │ ├─┬ readable-stream@1.1.14
  │ │ │ └── isarray@0.0.1
  │ │ ├─┬ stream-browserify@1.0.0
  │ │ │ └─┬ readable-stream@1.1.14
  │ │ │   └── isarray@0.0.1
  │ │ ├── string_decoder@0.10.31
  │ │ ├── timers-browserify@1.4.2
  │ │ ├── tty-browserify@0.0.0
  │ │ ├─┬ url@0.10.3
  │ │ │ ├── punycode@1.3.2
  │ │ │ └── querystring@0.2.0
  │ │ ├── util@0.10.3
  │ │ └─┬ vm-browserify@0.0.4
  │ │   └── indexof@0.0.1
  │ ├─┬ optimist@0.6.1
  │ │ ├── minimist@0.0.10
  │ │ └── wordwrap@0.0.3
  │ ├─┬ supports-color@3.1.2
  │ │ └── has-flag@1.0.0
  │ ├── tapable@0.1.10
  │ ├─┬ uglify-js@2.6.4
  │ │ ├── async@0.2.10
  │ │ ├── uglify-to-browserify@1.0.2
  │ │ └─┬ yargs@3.10.0
  │ │   ├── camelcase@1.2.1
  │ │   ├─┬ cliui@2.1.0
  │ │   │ ├─┬ center-align@0.1.3
  │ │   │ │ ├─┬ align-text@0.1.4
  │ │   │ │ │ ├── longest@1.0.1
  │ │   │ │ │ └── repeat-string@1.5.4
  │ │   │ │ └── lazy-cache@1.0.4
  │ │   │ ├── right-align@0.1.3
  │ │   │ └── wordwrap@0.0.2
  │ │   └── window-size@0.1.0
  │ ├─┬ watchpack@0.2.9
  │ │ ├── async@0.9.2
  │ │ └─┬ chokidar@1.6.0
  │ │   ├─┬ anymatch@1.3.0
  │ │   │ ├── arrify@1.0.1
  │ │   │ └─┬ micromatch@2.3.11
  │ │   │   ├─┬ arr-diff@2.0.0
  │ │   │   │ └── arr-flatten@1.0.1
  │ │   │   ├── array-unique@0.2.1
  │ │   │   ├─┬ braces@1.8.5
  │ │   │   │ ├─┬ expand-range@1.8.2
  │ │   │   │ │ └─┬ fill-range@2.2.3
  │ │   │   │ │   ├── is-number@2.1.0
  │ │   │   │ │   ├── isobject@2.1.0
  │ │   │   │ │   └── randomatic@1.1.5
  │ │   │   │ ├── preserve@0.2.0
  │ │   │   │ └── repeat-element@1.1.2
  │ │   │   ├─┬ expand-brackets@0.1.5
  │ │   │   │ └── is-posix-bracket@0.1.1
  │ │   │   ├── extglob@0.3.2
  │ │   │   ├── filename-regex@2.0.0
  │ │   │   ├─┬ kind-of@3.0.3
  │ │   │   │ └── is-buffer@1.1.3
  │ │   │   ├── normalize-path@2.0.1
  │ │   │   ├─┬ object.omit@2.0.0
  │ │   │   │ ├─┬ for-own@0.1.4
  │ │   │   │ │ └── for-in@0.1.5
  │ │   │   │ └── is-extendable@0.1.1
  │ │   │   ├─┬ parse-glob@3.0.4
  │ │   │   │ ├── glob-base@0.3.0
  │ │   │   │ └── is-dotfile@1.0.2
  │ │   │   └─┬ regex-cache@0.4.3
  │ │   │     ├── is-equal-shallow@0.1.3
  │ │   │     └── is-primitive@2.0.0
  │ │   ├── async-each@1.0.0
  │ │   ├── glob-parent@2.0.0
  │ │   ├─┬ is-binary-path@1.0.1
  │ │   │ └── binary-extensions@1.5.0
  │ │   ├─┬ is-glob@2.0.1
  │ │   │ └── is-extglob@1.0.0
  │ │   └─┬ readdirp@2.1.0
  │ │     └── set-immediate-shim@1.0.1
  │ └─┬ webpack-core@0.6.8
  │   └─┬ source-map@0.4.4
  │     └── amdefine@1.0.0
  └─┬ webpack-dev-server@1.14.1
    ├─┬ compression@1.6.2
    │ ├─┬ accepts@1.3.3
    │ │ └── negotiator@0.6.1
    │ ├── bytes@2.3.0
    │ ├─┬ compressible@2.0.8
    │ │ └── mime-db@1.23.0
    │ ├── on-headers@1.0.1
    │ └── vary@1.1.0
    ├── connect-history-api-fallback@1.1.0
    ├─┬ express@4.14.0
    │ ├── array-flatten@1.1.1
    │ ├── content-disposition@0.5.1
    │ ├── content-type@1.0.2
    │ ├── cookie@0.3.1
    │ ├── cookie-signature@1.0.6
    │ ├── depd@1.1.0
    │ ├── encodeurl@1.0.1
    │ ├── escape-html@1.0.3
    │ ├── etag@1.7.0
    │ ├─┬ finalhandler@0.5.0
    │ │ ├── statuses@1.3.0
    │ │ └── unpipe@1.0.0
    │ ├── fresh@0.3.0
    │ ├── merge-descriptors@1.0.1
    │ ├── methods@1.1.2
    │ ├─┬ on-finished@2.3.0
    │ │ └── ee-first@1.1.1
    │ ├── parseurl@1.3.1
    │ ├── path-to-regexp@0.1.7
    │ ├─┬ proxy-addr@1.1.2
    │ │ ├── forwarded@0.1.0
    │ │ └── ipaddr.js@1.1.1
    │ ├── qs@6.2.0
    │ ├── range-parser@1.2.0
    │ ├─┬ send@0.14.1
    │ │ ├── destroy@1.0.4
    │ │ └── mime@1.3.4
    │ ├── serve-static@1.11.1
    │ ├─┬ type-is@1.6.13
    │ │ └── media-typer@0.3.0
    │ └── utils-merge@1.0.0
    ├─┬ http-proxy@1.14.0
    │ ├── eventemitter3@1.2.0
    │ └── requires-port@1.0.0
    ├─┬ serve-index@1.8.0
    │ ├── batch@0.5.3
    │ ├─┬ http-errors@1.5.0
    │ │ └── setprototypeof@1.0.1
    │ └── mime-types@2.1.11
    ├─┬ sockjs@0.3.17
    │ ├─┬ faye-websocket@0.10.0
    │ │ └─┬ websocket-driver@0.6.5
    │ │   └── websocket-extensions@0.1.1
    │ └── uuid@2.0.2
    ├─┬ sockjs-client@1.1.1
    │ ├─┬ eventsource@0.1.6
    │ │ └─┬ original@1.0.0
    │ │   └── url-parse@1.0.5
    │ ├── faye-websocket@0.11.0
    │ ├── json3@3.3.2
    │ └─┬ url-parse@1.1.1
    │   └── querystringify@0.0.3
    ├── stream-cache@0.0.2
    └─┬ webpack-dev-middleware@1.6.1
      └── mime@1.3.4
@gaearon
Contributor
gaearon commented Jul 27, 2016 edited

Is it the complete list on the screenshot? It’s super weird that your directories didn’t get flattened even though you use npm@3 and don’t have any conflicts. Can you run npm dedupe?

@elsigh
elsigh commented Jul 28, 2016

The screenshot is the complete list.
After npm dedupe I have a motherload of things in node_modules, including eslint-plugin-react

@gaearon
Contributor
gaearon commented Jul 28, 2016

@elsigh

I updated the guide: https://github.com/facebookincubator/create-react-app/blob/master/template/README.md#display-lint-output-in-the-editor

Unfortunately there’s no better way to fix it without global installs until eslint/eslint#3458 if fixed.

@FastNinja

started for a new project but had to eject soon. reason - need to use existing huge CSS file (company wide branding styles) into HTML and could not find the way to do that.

@mxstbr
Member
mxstbr commented Jul 29, 2016

@FastNinja if #226 got merged, would that satisfy your use case?

@FastNinja

@mxstbr looks like yes. I will have to place CSS into static/css and it will be bundled, correct?

@mxstbr
Member
mxstbr commented Jul 29, 2016 edited

Well, not bundled, but you would be able reference it in your index.html:

<link rel="stylesheet" type="text/css" href="static/css/something.min.css" />
@gaearon
Contributor
gaearon commented Jul 29, 2016

What's wrong with importing it from JS? We already have an example of src/index.css, why not put it there (or in another file you import from index.js)?

Please don't rely on referencing anything from HTML now. How that works might change (it's not currently supported officially).

@JacopKane

I just wrote my first react app in few hours thanks to this tool. Perfect for beginners. Would love to see flux,redux etc. integrations in in the future.

@idibidiart

@JacopKane

I don't think they can pick winners and losers as far as things like Redux vs MobX vs Redux+Relay and GraphQL vs Falcor etc.

You have frameworks like Apollo that are opinionated and make it easy to get started. I would recommend going that route when you're ready.

@gaearon
Contributor
gaearon commented Jul 29, 2016

For now we’re trying to solve the problem of build dependencies, not the complete stack.

@JacopKane
JacopKane commented Jul 31, 2016 edited

@idibidiart @gaearon Thanks for the explanations

@williamle8300
williamle8300 commented Aug 1, 2016 edited

What do I do if a npm module needs to use Webpack's plugin "css-loader" to bundle up some css assets?

For example, react-spinkit breaks because create-react-app isn't including the css/gifs for the loading animations.

Edit: Thx for making this by the way gaeron! I second what JacopKane said. Got up and running really fast. Delightful DX.

@gaearon
Contributor
gaearon commented Aug 1, 2016

For example, react-spinkit breaks because create-react-app isn't including the css/gifs for the loading animations.

Can you submit an issue with a reproducing example? It works for me.

@bjnortier

Thanks for this project.

A tip for anyone reading this who is using Atom: there are at least two eslint packages, "linter-eslint" and "fast-eslint".

"linter-eslint" _doesn't_ use the global eslint as recommended in docs:

"linter-eslint will look for a version of eslint local to your project and use it if it's available. If none is found it will fall back to the version it ships with.

and it didn't work for me.

But "fast-eslint" work with the globally installed eslint, and that worked

@gaearon
Contributor
gaearon commented Aug 1, 2016

linter-eslint has an option for this:

screen shot 2016-08-01 at 21 23 04

Would you like to submit a PR to clarify this in the doc?

@bjnortier

Hmmm, I didn't see the global option in the plugin config, but I do now. One would think in the settings that value should be above the "Global Node Installation Path" value, which I did see.

Happy to create a PR as a hint to Atom users

@williamle8300

@gaearon Hm. I created a new project and installed react-spinkit... now everything's working as it ought. Haha oh wellz!

If it happens again I'll bring it up. I'm assuming I probably edited some files in some funky way. Thanks for the help!

@gaearon
Contributor
gaearon commented Aug 1, 2016

@williamle8300 We had a fix for this in 0.2.0 so maybe that’s why.

@williamle8300

@gaeron Ohhhhhh hah. I downloaded this 10ms after it was announced. I should have npm update 'ed dat thang.

@alvincrespo

I am so happy to see this! This adds so much value to the React platform, I can't wait to see where you guys take it.

@dmitriid
dmitriid commented Aug 2, 2016 edited

Also two cents on configurability.

It would probably nice to see some configurability/overridability in the future. The reason for this is quite simple: no tool is perfect for 100% of developers. There's always that pesky 1% of configuration that you want to change/update/remove/override without going through all the config files.

It should be doable for babel and eslint. Both expose settings via a .*rc file. If found in project's root directory, React scripts could merge React's .rc with the project's .rc

Webpack, however, is a weird beast (this was also mentioned in comments above). There are several projects (webpack-merge, webpack-config-merger etc.) that attempt this. But this probably deserves a proper separate discussion.


Also: can we erect a monument to honour the creators of create-react-app? I'm deadly serious.

@HintikkaKimmo
HintikkaKimmo commented Aug 3, 2016 edited

This might be a stupid question, but I just started with React something with the starter app generated with create-app-react confuses me. And it's also feedback that readme should have section to explain what different parts do for example should you CSS be loaded on index.css or app.css for example.

Where is the root component or actually how the index.js gets mounted to <div class="root"></div> in that I see in the index.html file?

I would expect that index.js should be root.js or export component to do that or have I understood something completely wrong?

@williamle8300

Did you follow the "Installation" guide on the README?

Take a look at the index.js file. That's where the mounting happens.

@williamle8300

Did you follow the "installation" guide on the github readme?

If you did look in the src folder. The relevant file you're looking for are

Index.html
Index.js
App.hs

On Aug 3, 2016, at 3:20 AM, Kimmo Hintikka notifications@github.com wrote:

This might be a stupid question, but I just started with React something with the starter app generated with create-app-react confuses me. And it's also feedback that readme should have section to explain what different parts do for example should you CSS be loaded on index.css or app.css for example.

Where is the root component or actually how the index.js gets mounted to

in that I see in the index.html file?

I would expect that index.js should be root.js or export component to do that or have I understood something completely wrong?


You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub, or mute the thread.

@dipetersen
dipetersen commented Aug 3, 2016 edited

I have somewhat of a weird request/issue. I develop applications hosted on Office365 or SharePoint. I'm trying to develop a single page app using React, hosted in a SharePoint site. My problem comes with the path references in the compiled build. Right now, it is all relative to the build folder. If I copy the build folder to my SharePoint site and make a reference to index.html, it can't find the included files because all the references are relative to the root of the web. In my normal deployment I put these files into a path /SiteAssets/build/. I have been successful manually changing the path references but it would be nice to be able to set this path before the build command so all references were correct.

@gaearon
Contributor
gaearon commented Aug 3, 2016

My problem comes with the path references in the compiled build. Right now, it is all relative to the build folder.

I think v0.2.1 should already print instructions for deploying to non-root websites. Did you miss it? Should we make it more prominent?

@dipetersen

Did you miss it? Should we make it more prominent?

Yes - I missed that message. I was looking through the instructions and missed the end of the build notes.

@gaearon
Contributor
gaearon commented Aug 4, 2016 edited

Thanks for feedback. Changed to this on master:

screen shot 2016-08-04 at 14 14 06

@kirkaustin
kirkaustin commented Aug 4, 2016 edited

Glad to see that this project is coming along nicely!

The one sticking point for me is the Webpack config being difficult to extend. What if the script looked in the project directory for a Webpack config file first and if it exists, use that one, otherwise use the one(s) in the node_modules/react-scripts directory tree?

That way it would still have the same out-of-the-box experience for new users, but would allow more advanced users an easy way to customize fully.

@gaearon
Contributor
gaearon commented Aug 4, 2016 edited

@kirkaustin

Please see #339 (comment) and #99 (comment).

We know it’s frustrating but we can’t deliver on the goal of “hassle-free experience with no annoying issues or slight incompatibilities” if we let users override the Webpack config. Additionally we can’t provide painless upgrades this way which defeats the point of the project. So eject is the only option right now.

If you have suggestions about better defaults or if you’re missing some feature, please create an issue, and we will discuss it. You may also want to look at some of the alternatives, many of which, like nwb, allow config overrides.

@SpencerCDixon

I think if you need to 'customize fully' the recommended approach is to eject

@kirkaustin
kirkaustin commented Aug 4, 2016 edited

Using eject seems a bit extreme to me if all I want to do is change a line or two in a couple of config files to support CSSModules. I'll probably just write a script to munge the files in the node_modules/react-scripts directory tree (which seems pretty simple, but smells bad).

@otissv
otissv commented Aug 5, 2016 edited

Loving the CLI, makes starting a new react project so much easier. The eject feature is cool, however I would rather extend the config without ejecting. For example add/remove eslint rules, add babel presets and make changes to webpack eg handle .jsx extension.

Setting up a new project is simply too time consuming this is definitely move in the right direction. Great job as always :)

@duncan1a
duncan1a commented Aug 23, 2016 edited

This is great thanks. It's made getting our junior developer started with react so much easier and ejecting and editing my config to add scss etc was easy enough. Nicely done

Edit: I also like that you've resisted the urge to provide a kitchen sink solution.

@gaearon
Contributor
gaearon commented Sep 2, 2016

For those who asked, 0.3.0 is out with support for testing.
Read the usage guide and the migration instructions.

💜

@gaearon
Contributor
gaearon commented Sep 3, 2016

Closing as this thread has gotten pretty long, and now it’s easier to address concerns on case by case basis.

@gaearon gaearon closed this Sep 3, 2016
@Jairos2015

node version: v6.5.0
npm version: v3.10.3

this works for Windows 10 ?. Not me. mistakes:
c: \ Users \ jairo \ node \ react \ hello \ hello-world> npm start

Hello-world@0.1.0 start c: \ Users \ jairo \ node \ react \ hello \ hello-world
React-scripts start

"React-scripts" is not recognized as an internal or external command,
program or batch file.

npm ERR! Windows_NT 10.0.14393
npm ERR! argv "C: \ Program Files (x86) \ \ nodejs NODE.EXE" "C: \ Program Files (x86) \ nodejs node_modules \ \ \ bin \ npm npm-cli.js" "start"
npm ERR! node v6.5.0
npm ERR! npm v3.10.3
npm ERR! code ELIFECYCLE
npm ERR! hello-world@0.1.0 start: REACT-scripts start
npm ERR! Exit status 1
npm ERR!

npm ERR! Failed hello-world@0.1.0 at the start script 'scripts REACT-start'.
npm ERR! Make sure you Have the latest version of Node.js and npm installed.
npm ERR! If you do, this is most likely to a Problem with the hello-world package,
npm ERR! Not with npm itself.
npm ERR! That esta Tell the author fails on your system:
npm ERR! REACT-scripts start
npm ERR! You can get information on how to open an issue for esta project with:
npm ERR! npm bugs hello-world
npm ERR! Or if That is not available, you can get info via Their:
npm ERR! owner npm ls hello-world
npm ERR! There is likely additional logging output above.

npm ERR! Please include the following file With any support request:
npm ERR! c: \ Users \ jairo \ node \ react \ hello \ hello-world \ npm-debug.log

c: \ Users \ jairo \ node \ react \ hello \ hello-world> npm install --save react, react-dom, react-scripts
npm ERR! addlocal Could not install c: \ Users \ jairo \ node \ react \ hello \ hel
Google Traductor para empresas:Translator ToolkitTraductor de sitios webGlobal Market Finder
Thank you on advance.

@coding102

^ moving the react-scripts to dependencies from devDependencies worked for me.

@gaearon
Contributor
gaearon commented Dec 5, 2016

@coding102 If you have a reliable way of reproducing this please file a new issue.

Locking this one as there’s many subscribed people and we don’t want to bump them all with issue reports. 😄

Thanks to everyone again!

@gaearon gaearon locked and limited conversation to collaborators Dec 5, 2016
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.