Eh, the React team in particular is pretty even-handed when it comes to what goes into CRA. This release, for example, adds support for Apollo, which goes head-to-head with Relay.
I’ve been pretty happy with the team’s thoughtful approach to adding a dependency or not.
Speaking for the React team, we have little reason to suggest people use Flow over TypeScript.
I haven’t personally followed the status of TS in CRA closely, but I know it’s a popular request among our users so I would love for us to make it easy.
Really? If anything the move to babel 7 makes it easy, use babel-loader for .tsx?$ files with @babel/preset-typescript
I've setup about 4 projects over the past year, if you feel like you need help feel free to email me any particular pain points you have and I'll try to get you through them, email in profile (not a react contributor, just frequent react/typescript user on financial applications)
I'd actually love to see a good blog post that details the process of, say, upgrading from Babel 6 to Babel 7 for a non-CRA app, and then adding in some form of TS support on top of that. (I've got a couple apps that I'd like to try doing that with myself in the not too distant future.)
Then you'd still need to explicitly do type checking, which is the primary advantage of TypeScript. I guess my IDE can do that, but then I'd still need to add an extra step to my CI server, etc.
Native TypeScript support will be a huge improvement.
Everyone I know who uses it wishes they had gone with TypeScript. Anecdotal for sure, but I wouldn't be surprised if most Flow users felt this way - TS is winning in basically every way.
Flow offers a more sophisticated type system that is designed to express types that correspond with the sort of idioms you see in JavaScript in the wild. TypeScript is simpler and less flexible, but that simplicity can translate into increased productivity since there are less foot-guns and also less bugs. Strange/buggy behavior and odd performances issues are not totally uncommon with Flow whereas TypeScript doesn't seem to suffer from this as much. Since TypeScript is much more popular, IDE support tends to be a lot better out of the box, but the flow-langauge-server gives you all the same IDE-like features (intelligent autocomplete, jump-to-def, module resolution etc).
Personally, I like Flow more, and I also think its easier to integrate into an existing codebase (either as comment annotations or gradually via per-file flow comment header), but at the end of the day, not choosing TypeScript amounts to swimming against the current without much justification.
>Flow offers a more sophisticated type system that is designed to express types that correspond with the sort of idioms you see in JavaScript in the wild. TypeScript is simpler and less flexible, but that simplicity can translate into increased productivity since there are less foot-guns and also less bugs.
Source? That's the primary design principle behind TypeScript too. TypeScript's type system is powerful enough to practically do arbitrary type-level transformation of data structures, and even do some crazy recursive pure functional type level programming.
The only things I'm missing from TypeScript are variadic generics (which can be emulated quite well with TS 3.0) and higher kinded types - and I don't think Flow supports them either.
Most of that can't be achieved out of the box with TypeScript. TypeScript was designed as a language that would bridge the quality of life gap between es5 and more modern languages, Flow was designed exclusively as a type system for annotating standards compliant JS.
$Values should be possible with Typescript 3.0+ conditional infer types, presumably something very similar to the built-in ReturnType<T> conditional infer type.
Untested and off the top my head but maybe something like:
type Values<T> = T extends { [K keyof T]: infer R } ? R : any
Are you aware the TypeScript has mapped types and conditional types[1]? The vast majority of Flow's type utils can be implemented in TypeScript, and many of them are included by default[2]. As far as I can tell all of Flow's utility types are compiler built-ins[3], but TypeScript's built-ins are declared using the type system itself (or are just natural parts of the syntax):
type Keys<T> = keyof T
type Values<T> = T[keyof T]
type Readonly_<T> = Readonly<T>
type Shape<T> = Partial<T>
type NonMaybeType<T> = NonNullable<T>
// Exact<T> cannot be implemented because TS doesn't have exact types as a separate concept,
// It should be noted that object literals are exact by-default if there's a type annotation
// Issue: https://github.com/Microsoft/TypeScript/issues/12936
type Diff<A, B> = Pick<A, Exclude<keyof A, keyof B>>
// Rest<T> should be equal to Diff, because TS doesn't have exact types
type ElementType<T, K extends keyof T> = T[K]
// PropertyType in unnecessary, because T[K] works for everything
// Note that this is variadic - "Args" is an array of arguments
type Call<F, Args extends any[]> = F extends (...args: Args) => infer B ? B : never
// This works for both objects and tuples.
type ObjMap<T, F> = { [K in keyof T]: Call<F, [T[K]]> }
// I couldn't figure out how to implement Class<T>, but you can access the type of a class instance with
// typeof ClassName.prototype
// $SuperType and $Subtype are not documented, so I can't try to replicate them.
// TypeScript doesn't have existential types, but you can emulate them within the type system, or avoid them using e.g "infer"
// Discussion and encoding https://github.com/Microsoft/TypeScript/issues/14466#issuecomment-338045331
I don't agree with your statement about TypeScript's design. Before ES6 TypeScript _was_ quite different from JS, but for the past 3 or 4 years it has followed modern JS very closely. The flavor of JS it supports is fully compliant with ES2018, and the ONLY feature with codegen impact it has in addition to modern JS and JSX are enums - which compile down to simple object literals.
The last time I used Flow it was intended to be used a daemon constantly watching your code. This made it really difficult to use with tools like Webpack which are built for "atomic" operations like tsc.
> Personally, I like Flow more, and I also think its easier to integrate into an existing codebase (either as comment annotations or gradually via per-file flow comment header)
For several versions now, Typescript also supports type annotations in JS comments and an allowJS mode for mixing TS and JS in the same project, or using only JS and JS comment type annotations.
> Sorry. We needed to prioritize to get this release out because it's already been snowballing for about a year.
Why does the project generated by react-native-cli contains some flow syntax by default? this is stupid. Not everybody has a flow plugin for his IDE. And obviously flow type declarations are not valid JavaScript. I understand you want to push your stack onto your users but no need to be that invasive.
TypeScript is fantastic for its IDE support and instant feedback but I'm waiting for the day it's built into CRA as a first class citizen. Sounds like that day will be soon though maybe even this year.
Exactly this. Create React App is awesome except its not TypeScript, and unfortunately the key point of Create Reacte App is that it is opinionated which is its magnificent strength, but it's opinion is not TypeScript as the primary language choice. It's a pity TypeScript isn't the default.
I'd list Create React App as the number one best JavaScript technology of all time, awarded for the massive pain saving it confers. It allows the most fabulous thing in the world, which is to avoid using the JavaScript tooling.
Absolutely - all you've ever needed to do is `npm i redux react-redux`, then add them to the app. They're just libraries, no special behavior needed.
See the "Configuring Your Store" docs page [0] for copy-pasteable examples of adding Redux to a React project.
Also, we're working on a `redux-starter-kit` project [1] that will soon become an official Redux-branded tool to help with common pain points, like setting up the store properly, simplifying immutable reducer update logic, and more. I talked about it in my React Boston "State of Redux" presentation [2] over the weekend. Please try it out, and let us know how it works and what else we should add!
The Create-React-App tool hides all of the Babel and Webpack configuration by default. The only dependency you have in your app is the `react-scripts` package.
This drastically simplifies things for your app, and means you can get the latest build system updates with a single update command whenever a new version of `react-scripts` comes out. However, it also means that if you _do_ need to modify the configuration in some way, it's normally inaccessible.
CRA includes a one-time `npm run eject` command that copies over all of the actual dependencies and config files into your project. "Ejecting" means you're taking ownership of those config files, and also means you lose the ability to easily upgrade with a single command.
Thanks. That sounds like a pretty elegant way to hide all that complexity. Let's hope things continue to converge and simplify into a more universal set of standards, defaults, and built ins.
You can even change some webpack configs without ejecting using react-app-rewired. Its pretty nice if you only care to change one or 2 simple settings. (like name of build files, babel plugins, etc...)
I'm not sure with what you mean by staging environment in this context. You can run your app in a webpack-devServer or build it then use your own server.
> More styling options: you can use Sass and CSS Modules out of the box.
This is what I'm most excited about. Emotion is great but I've heard a lot of great things about CSS Modules, just haven't gotten around to trying them out yet because it's been so complicated to do. I'll definitely be giving it a try now.
I wrote a bit[1] about CSS Modules with React, but interestingly it looks like CRA isn't using babel-plugin-react-css-modules so I'm trying to figure out what they're doing instead.
I started my engineering career as a front-end developer when being front-end developer meant slicing PSDs to HTML trying to figure out the best way to implement crazy glassy and shadowy designs without transparent PNG support in IE6.
Starting using CSS Modules "properly" with custom built UI components library was definitely the biggest single improvement in easiness of delivering stuff I've experienced across the "whole stack", from the hosting situation, DBs, through popularization of MVC on the server and client side, micro-services to react itself.
Please do give a try. :)
One rule of thumb I passed on my friend learning working with CSS Modules: Never share styles between components.
Sometimes it's very tempting but instead try to compose your components in different ways.
You might want to share style or create mixin for white box with a border and shadow for 2 very similar components. Creating WhiteShadowedBox component even if it's a div with 3 lines of CSS is fine and will save a some headache later. Of course needs a better name. ;)
It's fine to use variables and mixins for "style config" like colors, font definitions, margin scales (0.8rem, 1.2rem, 1.6rem) etc but in my experience not much more.
I can't imagine using anything other than styled-components... Are there advantages to using CSS Modules instead?
Every time I look at the docs for another styling solution I just see unnecessary complexity for no clear benefit. Styled components are so easy to reason about and organize, especially when doing conditional / state based styling.
> If you previously ejected but now want to upgrade, one common solution is to find the commits where you ejected (and any subsequent commits changing the configuration), revert them, upgrade, and later optionally eject again.
That seems insane to be honest, yet it's seems to be the norm to upgrade a framework in JavaScript (same with React Native). Is that the best solution there is? In many other languages, you can upgrade a framework without reverting commits or trying to figure out what to keep or change in huge diffs. Surely there should be a way to keep the base config untouched, and have user changes in a separate config that overrides the base on?
Create React App is not a framework, it is more similar to a scaffolding system that sets up a group of tools and processes. You can upgrade React normally without issue.
The equivalent to what you suggest would be to autogenerate some files with a tool, modify the location and structure or those by hand and then expect the tool to be able to modify then again seamlessly.
I'd say 'multiple smaller tools' is actually what Babel has become. It started out as a tool to compile ES6 to ES5 (6to5 it was called), but now it's a kind of framework(?) that you can add various smaller packages to for various 'transpiling' purposes.
I see Facebook’s React team is in the comments. Please keep in mind that the open source aspect of React is part of Facebook’s hiring strategy. While I believe the React team are genuine in their friendliness and passion for their work, they also represent and are payed handsomely by one of the worst offenders in surveillance capitalism.
(I realize some might feel a comment like this is out of place here, but considering the recent news about enormous leaks and privacy violations, I think it would be more strange if it wasn’t brought up.)
I decided to finally bite the bullet and learn React yesterday. Every time they mentioned "we do it like this at Facebook" in the tutorial/docs, my eagerness died a little more. Even little tongue-in-cheek things, like their shopping list app consisting of companies they've acquired (Instagram, Oculus, WhatsApp) felt like a bummer.
Regarding "we do it like this at Facebook" -- could you point out examples where this isn't useful, and we could remove them? I wrote some of these, mostly to highlight that if something works for a massive codebase with 50,000+ components, it will probably work for yours, even if it doesn't look familiar. I don't know what's an alternative way to say it without losing the core of the message.
Regarding the tongue-in-cheek one. Well. I don't feel strongly about changing it if many people feel this way.
74 comments
[ 3.8 ms ] story [ 81.8 ms ] threadI’ve been pretty happy with the team’s thoughtful approach to adding a dependency or not.
I haven’t personally followed the status of TS in CRA closely, but I know it’s a popular request among our users so I would love for us to make it easy.
Sometimes it gets confusing connecting the negative news of these large companies to their cool open source projects.
I've setup about 4 projects over the past year, if you feel like you need help feel free to email me any particular pain points you have and I'll try to get you through them, email in profile (not a react contributor, just frequent react/typescript user on financial applications)
Add typescript, babel typescript, add the plugin in babelrc, and update the Babel cli build command in package.json to look for ts file extensions.
That enabled me to start incrementally adding typescript into an existing node.js codebase, I was surprised how easy it was.
package.json (scripts)
package.json (add property) package.json (dev depenencies) babelrc (add with env) tsconfig (example)Native TypeScript support will be a huge improvement.
We actually did have "TypeScript support" on a nice-to-have list for this two week sprint but unfortunately didn't get to it:
https://i.imgur.com/l0CpdZy.png (I promise I'm not making this up :-)
I'm confident we'll ship it by the end of this year though.
https://github.com/facebook/create-react-app/pull/4837
Personally, I like Flow more, and I also think its easier to integrate into an existing codebase (either as comment annotations or gradually via per-file flow comment header), but at the end of the day, not choosing TypeScript amounts to swimming against the current without much justification.
Source? That's the primary design principle behind TypeScript too. TypeScript's type system is powerful enough to practically do arbitrary type-level transformation of data structures, and even do some crazy recursive pure functional type level programming.
The only things I'm missing from TypeScript are variadic generics (which can be emulated quite well with TS 3.0) and higher kinded types - and I don't think Flow supports them either.
Most of that can't be achieved out of the box with TypeScript. TypeScript was designed as a language that would bridge the quality of life gap between es5 and more modern languages, Flow was designed exclusively as a type system for annotating standards compliant JS.
Untested and off the top my head but maybe something like:
[1] https://www.typescriptlang.org/docs/handbook/advanced-types.... [2] https://github.com/Microsoft/TypeScript-Handbook/blob/master... [3] https://github.com/facebook/flow/blob/cf03c08109014c4503a392...
For several versions now, Typescript also supports type annotations in JS comments and an allowJS mode for mixing TS and JS in the same project, or using only JS and JS comment type annotations.
Why does the project generated by react-native-cli contains some flow syntax by default? this is stupid. Not everybody has a flow plugin for his IDE. And obviously flow type declarations are not valid JavaScript. I understand you want to push your stack onto your users but no need to be that invasive.
Oh wow, that statement is so much more than I'd have expected - there's something to look forward to!
I'd list Create React App as the number one best JavaScript technology of all time, awarded for the massive pain saving it confers. It allows the most fabulous thing in the world, which is to avoid using the JavaScript tooling.
See the "Configuring Your Store" docs page [0] for copy-pasteable examples of adding Redux to a React project.
Also, we're working on a `redux-starter-kit` project [1] that will soon become an official Redux-branded tool to help with common pain points, like setting up the store properly, simplifying immutable reducer update logic, and more. I talked about it in my React Boston "State of Redux" presentation [2] over the weekend. Please try it out, and let us know how it works and what else we should add!
[0] https://redux.js.org/recipes/configuringyourstore
[1] https://github.com/markerikson/redux-starter-kit
[2] https://blog.isquaredsoftware.com/2018/10/presentation-state...
This drastically simplifies things for your app, and means you can get the latest build system updates with a single update command whenever a new version of `react-scripts` comes out. However, it also means that if you _do_ need to modify the configuration in some way, it's normally inaccessible.
CRA includes a one-time `npm run eject` command that copies over all of the actual dependencies and config files into your project. "Ejecting" means you're taking ownership of those config files, and also means you lose the ability to easily upgrade with a single command.
https://github.com/timarney/react-app-rewired/
How does staging fit in here ?
This is what I'm most excited about. Emotion is great but I've heard a lot of great things about CSS Modules, just haven't gotten around to trying them out yet because it's been so complicated to do. I'll definitely be giving it a try now.
[1] https://dev.to/daveirvine/postcss-with-css-modules-andreact-...
Starting using CSS Modules "properly" with custom built UI components library was definitely the biggest single improvement in easiness of delivering stuff I've experienced across the "whole stack", from the hosting situation, DBs, through popularization of MVC on the server and client side, micro-services to react itself.
Please do give a try. :)
One rule of thumb I passed on my friend learning working with CSS Modules: Never share styles between components.
Sometimes it's very tempting but instead try to compose your components in different ways.
You might want to share style or create mixin for white box with a border and shadow for 2 very similar components. Creating WhiteShadowedBox component even if it's a div with 3 lines of CSS is fine and will save a some headache later. Of course needs a better name. ;)
It's fine to use variables and mixins for "style config" like colors, font definitions, margin scales (0.8rem, 1.2rem, 1.6rem) etc but in my experience not much more.
Every time I look at the docs for another styling solution I just see unnecessary complexity for no clear benefit. Styled components are so easy to reason about and organize, especially when doing conditional / state based styling.
That seems insane to be honest, yet it's seems to be the norm to upgrade a framework in JavaScript (same with React Native). Is that the best solution there is? In many other languages, you can upgrade a framework without reverting commits or trying to figure out what to keep or change in huge diffs. Surely there should be a way to keep the base config untouched, and have user changes in a separate config that overrides the base on?
The equivalent to what you suggest would be to autogenerate some files with a tool, modify the location and structure or those by hand and then expect the tool to be able to modify then again seamlessly.
If you didn't "eject", upgrading is as simple as 'npm update react-script'. This is the norm in JavaScript.
I also didn't understand why so much functionality for different languages are harbored by a single tool, instead of multiple smaller tools.
(I realize some might feel a comment like this is out of place here, but considering the recent news about enormous leaks and privacy violations, I think it would be more strange if it wasn’t brought up.)
Regarding "we do it like this at Facebook" -- could you point out examples where this isn't useful, and we could remove them? I wrote some of these, mostly to highlight that if something works for a massive codebase with 50,000+ components, it will probably work for yours, even if it doesn't look familiar. I don't know what's an alternative way to say it without losing the core of the message.
Regarding the tongue-in-cheek one. Well. I don't feel strongly about changing it if many people feel this way.