-
Notifications
You must be signed in to change notification settings - Fork 26.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Proposal: [react][breaking] Only .js files should contain JSX. #985
Proposal: [react][breaking] Only .js files should contain JSX. #985
Conversation
Thanks, but no. At Airbnb we believe that only JavaScript should ever go in You never need extensions whether it's The reason to differentiate is the same reason we only use stage 3 and above proposals: if it's not standard, it is not javascript. In that comment on the react repo, "What people are actually doing… that's may not match." - which is indeed the case. It's far more common to put JSX in |
Not intended to argue with your decision here, but just to share a differing view on this point:
Although true in the past, I think this is starting to change, for reasons pointed out here: facebook/create-react-app#87 (comment) This is also something I'm seeing when looking at other people's new projects, but certainly could be selection bias. |
The reality is that whether it's common isn't really relevant. JS is JS. We've chosen |
Oh ok. |
our linter config requires (or will soon require) that you omit file extensions in all cases. @ljharb do you have an estimate as to when this might be the case? |
@merlinpatt it's blocked on import-js/eslint-plugin-import#390 - so, as soon as that's implemented. Yes, |
@merlinpatt .jsx isn't picked up by the webpack
|
If you are already using something like JSX, keeping JS separate from JSX hurts ergonomics in my experience. It feels silly to have to rename a single file just because you need a single line of JSX there. A similar argument can be made for Flow annotations. If you already decided on using Flow, it feels silly to ask team members to rename When you add a non-standard syntax extension, you usually do this because it provides enough convenience to your project to justify the non-standardness. Now that you’ve added it, having to do extra work bookkeeping and renaming files one by one is frustrating and defeats the purpose. From this follows that if you decided to adopt a non-standard extension, you might as well allow it globally in your project anyway. Therefore there should be just one file extension. The remaining question is which one.
So I guess we could call it (I would like to add that we are in a unique point in time where one of the most popular languages in the world is being actively extended through transpilers. Our usual strategies and rules of thumb might not apply in this situation. Whether it’s good or bad, time will tell.) |
How often does this happen though? Usually you'll have files that will clearly contain JSX (components) and those that don't (app state code, helpers, etc). I've found that using Redux, in contrast to a more es6 class inheritance based Flux implementation, will result in having reducers with the same name as component, for example reducer in somePage.js and a SomePage.jsx component. Having different extensions helps differentiate the files without looking at the whole path. |
For Flow (or stage 0 extensions), it happens pretty much every day. |
Afaik, they said they've chosen And if for any reason you have to change the extension of a file (what I think you should not do during a project), you can do it in 2 steps in order to keep the git history (1: change the extension; 2: modify the file the way you want). In the end, the extension doesn't matter. Use whatever you want to use. |
So absolutely annoyed by the “But AirBnB/Twitter/Facebook/Google/Paypal/Netflix/Mom&Pop.com do it that way!” fallacious argument that seems to be _constantly_ tossed about in software engineering.. No one company (or even a handful) has exclusive knowledge on solutions. If one is a serious professional, they'll make decisions based off of actual knowledge and experience, not just because "everyone else does it that way" |
@RavenHursT I think you misread - nobody is saying "X is right because $bigCompany chooses it", @tleunen was just pointing out that since this is Airbnb's style guide, Airbnb will put in it what works for Airbnb. That said, that shouldn't be used to shut down this healthy discussion, but it's useful context if by discussing you're hoping to effect a change in this part of Airbnb's style guide. |
No one is attempting to "shut down" the discussion.. Simply making a point is all. I understand this is AirBnb's style guide. Unfortunately/fortunately many have taken this guide on as their own as well, based simply on "but AirBnb uses it" and along w/ it come the justifications for what is/is not in the guide. It's those justifications that I'm referring to, grounded in the fallacy. |
Can you clarify a bit more what this will mean in practice? Does it mean controversial community PRs will only be discussed and not actually seriously considered? Does whatever Airbnb does trump community suggestions, generally? Obviously this is Airbnb's config and what Airbnb says goes, but I wonder what you think the balance ought to be. |
@bradencanderson oh no, not at all. Airbnb has adapted its internal style based on repo discussions many times. If a persuasive case is made here, we could change this as well - but we haven't as of yet been persuaded. |
@bradencanderson my favorite part of our style guide being open source is how it continues to get better with feedback from the community, so we welcome, enjoy, and encourage discussions like this. We've had 251 contributors since we open sourced our guide back in 2013. I guesstimate 20 or so are/were Airbnb employees. It's mostly reasonable... and sometimes opinionated. Currently we do find ourselves with opinions on semicolons and file extensions 😄 On to the topic at hand. There are great points on both sides of this discussion and some existential thoughts around what JS is, which is quite fun. @gaearon's follow up thoughts on Twitter are lovely (h/t Sgt Pepper): https://twitter.com/dan_abramov/status/763712190272667648
So the grand experiment continues! We've got an opinion that works for us at Airbnb right now, but we'll report back if things get unwieldy.
As long as an opinion stays consistent throughout a project/codebase/team we've found efficiency increases even if there isn't consensus.jsx
Thanks to everyone that has participated in this discussion so far! |
I think it is silly to name ALL files containing jsx with This allows easy fuzzy searching if I have multiple files named "component" within modules, test, story, route etc...also with file-icons plugin in Atom it gives a pretty little blue jsx icon to represent it, and overall just makes it easy to spot which file name is actually the component itself |
I'm finding it happens more and more often. In 'model' type objects:
..or dispatching a component in a thunk
It's very liberating once you realize components are just function calls and you can put them anywhere. Having to switch file extensions just for this purpose is rather annoying. |
@alex-wilmer although it's nice to have the freedom of placing jsx tags anywhere, I would usually keep them separated from the js. Architecturally it just feels better to me but also because I know at some point react might be replaced with something else. So for me the jsx extension is telling me the code is in a different "layer" to my js code. |
So everyone should configure Sublime Text or Atom to handle Update By the way, this is already a solved problem. Back in the days in Rails used to name HTML with Embedded Ruby So In this naming convention, a plain JavaScript file that needs to be preprocessed by flow, then by jsx would be called |
@mlangenberg I have a gut feeling a large majority of users building React apps use the Babel syntax extension for JS, which handles JSX by default. |
jsx is the file extensions are source files for babel. it should be industry standard. totally disagree to use js extension for everything else. would NEVER do that. |
I've adopted a similar approach to @colbycheeze on various projects over the past couple years. Components get the The |
|
The distinction between .js and .jsx files was used to mean something before Babel, but nowadays the concept and meaning are different.We can't be conservative, follow the time. |
@dorsywang i'm not aware there was jsx before babel. The distinction remains forever relevant, and will be even more relevant as node.js ships ES Modules support that requires the file extension be |
@ljharb there was JSX before Babel. Non-Facebook use of React with JSX predates Babel and even 6to5 (what Babel used to be called), React provided its own compiler which included support for JSX and a small number of other ES6 features. |
@AndrewIngram ah, thanks - that was a long time ago :-) The advent of babel still didn't erase the purpose of file extensions; otherwise we'd all just use extensionless files instead of |
TypeScript has Seems like there is no reason like this for vanilla JS, though. Just my $0.02. |
@markspolakovs yes, that's precisely because different parsing goals are required for the two files, so TypeScript has done the proper thing and assigned each parsing goal its own file extension. That's what we're doing here with JS vs "JS plus extra stuff". |
@ljharb Thing is, JSX doesn't need different parsing goals. TypeScript uses the same syntax for two different things, that's why it needs the disambiguation. JSX syntax isn't used anywhere else in JavaScript, neither is Flow for example. The syntax is enabled by your configuration ( |
Of course it does; jsx isn't valid JS. "parsing goal" means "different rules", which doesn't require that there be conflicts. |
I meant different parsing goals in the same project. It's because of the fact that TS uses the same syntax for two different things that it needs this "selector" by file extension, but since there isn't anything else in JS that uses JSX syntax, it's impossible for there to be two files with different parsing goals (in terms of JSX syntax) in the same project, so you don't need an explicit JSX specifier on your files, it can be global. |
@markspolakovs yes, I know what you mean, but the point of file extensions is to answer the question "across the entire universe of parseable things, not just this project, what's the parsing goal of this file?" The fact that you can parse a .js file and decide, at parse time, if you're parsing it as JSX, or as normal JS, doesn't make the extension meaningless; it's just a property of the combination of two similar parsing goals. |
I see your point about the entire universe of parseable things, but I wonder how often that's relevant. The only instances I can think of off the top of my head are IDEs and GitHub's syntax highlighting, and those seem to be able to detect JSX even inside of vanilla .js files. Therefore I think putting the JSX in the extension is redundant. |
* Tweaks to support component directory bundles - Storybook now also finds stories in frontend/src/app/**/stories.js - `npm run test` now also finds tests in frontend/src/app/**/tests.js - New /static/app/app.js.css stylesheet built from Sass styles imported by components - Hacks to ignore .scss imports when using component modules outside Webpack for static page build & tests - Update flowconfig to ignore .scss imports - Small eslint upgrade so CLI matches gulp-eslint * Reorganize ExperimentRowCard component into bundle directory * Reorganize UpdateList component into bundle directory * Begin to extract IncompatibleAddons component from ExperimentPage container * Rename stories.jsx -> stories.js; See also: airbnb/javascript#985 (comment) * Quick & dirty revision to Storybook docs to incorporate new component bundle proposal Issue #2807
Every programming language uses the same extension for different versions of the language. I've never seen .py2, .py3, .java6, etc. although a lot of it is incompatible between the versions of the interpreter/compiler/transpiler. Same goes with .js with a small specialty of having some unofficial albeit very popular transpilers that are de facto industry standards and their features should be supported as standard functionality. .jsx is dead, long live .js |
Heavily debated here: airbnb/javascript#985
https://github.com/facebook/create-react-app/releases/tag/v0.4.1 |
LOLz! ☝️ this is awesome. |
CRA’s recommendation isn’t relevant (or new). This thread is long enough; I’m going to lock it. |
Opening this for comments and discussion. I would like to suggest only using JSX inside of .js files. Here is a short rationale for doing so:
require('./MyComponent');
vsrequire('./MyComponent.jsx');
Additional discussion: facebook/react#3582 (comment)