Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Warn about JSX file extension #290

Closed
gaearon opened this issue Jul 29, 2016 · 30 comments
Closed

Warn about JSX file extension #290

gaearon opened this issue Jul 29, 2016 · 30 comments

Comments

@gaearon
Copy link
Contributor

gaearon commented Jul 29, 2016

Update

We support JSX extension since 0.4.1 even though we don’t recommend it.
Read the release notes.


Original Thread

We don’t support it. AFAIK there is no good reason to: #87 (comment).

We should do two things:

  • Document that.
  • Provide a descriptive error when you attempt to import a JSX file. This should be fairly easy to do with a Webpack plugin. You can look at this project for inspiration (although obviously the solution will be different).
@tizmagik
Copy link
Contributor

I'd like to work on this. I imagine the best way would be to publish a webpack plugin that takes some regex and error message as options to keep it configurable and potentially useful in other contexts. Does that approach make sense?

@gaearon
Copy link
Contributor Author

gaearon commented Jul 30, 2016

Sounds reasonable.

@stephenkingsley
Copy link

I fix it~

@tizmagik
Copy link
Contributor

tizmagik commented Aug 4, 2016

Submitted #353

@gaearon
Copy link
Contributor Author

gaearon commented Aug 4, 2016

@stephenkingsley Since @tizmagik first offered to work on this, let’s give him the opportunity to finish it?

@tizmagik I think it’s not just importing .jsx that we want to warn about. We want to warn if user imports ./App but only App.jsx exists. This is the most likely case—not that they will import ./App.jsx. So we should warn in that case. (We can check the imported extension with an ESLint rule instead, so it’s not as important.) You would want to hook into resolve mechanism like this plugin does and throw a different error.. I think.

@stephenkingsley
Copy link

We want to warn if user imports ./App but only App.jsx exists

I review @tizmagik code. when the webpack compile jsx file that we warn it. this is not you want? If had ./App.js and ./App.jsx, I think nodejs will importing ./App.js. I am a newbie, so I want to know what you want~

@gaearon
Copy link
Contributor Author

gaearon commented Aug 4, 2016

I want the following to work:

  • App.jsx exists but App.js does not
  • User writes import App from './App' in another file
  • We should warn

@stephenkingsley
Copy link

thx! I think @tizmagik is work too easy to fix this problem.

@stephenkingsley
Copy link

If have a solution that both have ./App.js and ./App.jsx in webpack compile? I think only have js or jsx file. so @tizmagik work I think it is ok. I want your suggestion again, please.

@gaearon
Copy link
Contributor Author

gaearon commented Aug 4, 2016

I’m not sure I understand what you’re asking.

@stephenkingsley
Copy link

Sorry, my english is not good. User writes import App from './App'. if App.js exists and App.jsx also exists, I think webpack will import App.js file. I think this solution is right, we should not warn the User.but if App.jsx exists, App.js does not. we should warn the User. it's right?

@stephenkingsley
Copy link

checking the file that webpack compiling whether is the jsx file. I do not know what's wrong? and I think this is done what your want.

@stephenkingsley
Copy link

compiler.plugin('normal-module-factory', function (nmf) {
    nmf.plugin('after-resolve', function (data, done) {
      var pathName = data.resource.split('?')[0];
      if (pathName.match(/\/[A-Za-z0-9]+\.jsx$/)) {
        done(new Error('do not require .jsx file in ', pathName));
      } else {
        done(null, data);
      }
    });
  });

this is my idea, I need your suggestion. please help me.

@tizmagik
Copy link
Contributor

tizmagik commented Aug 4, 2016

@gaearon thanks for reviewing my PR. I think the way this is currently written is the cleanest/most correct way.

That is, because of these lines in webpack.config.dev.js:

resolve: {
  extensions: ['', '.js', '.json'],
  // ...
}

If a user just does import App from './App' and only App.jsx exists, Webpack will error with:

Module not found: Error: Cannot resolve 'file' or 'directory' ./App

Since .jsx was not listed as one of the resolve.extensions[]

So, instead, this plugin guards against a user specifying the .jsx extension in the import path: import App from './App.jsx' in which case they would get the configured error.

If, however, you want webpack to auto-resolve the .JSX extension, then you can add .jsx to resolve.extensions[] in the webpack config, and then this plugin will warn on import App from './App' when only App.jsx exists, as you described. However, I wouldn't recommend doing this, as it seems a roundabout way to warn about a particular file extension (e.g. allow Webpack to auto-resolve the extension, only to disallow it with a plugin).

Does that make sense?

@gaearon
Copy link
Contributor Author

gaearon commented Aug 4, 2016

If a user just does import App from './App' and only App.jsx exists, Webpack will error with:
Module not found: Error: Cannot resolve 'file' or 'directory' ./App
Since .jsx was not listed as one of the resolve.extensions[]

I understand, and this is exactly the problem I want to solve with this issue. My proposal is a resolve plugin that checks if a .jsx file with the same name exists when Webpack can’t resolve a file, and throws a more descriptive error.

@stephenkingsley
Copy link

hahaha, I exactly knew what your means!

@tizmagik
Copy link
Contributor

tizmagik commented Aug 4, 2016

In that case, I wonder if it's any more or less correct to add ".jsx" to resolve.extensions[] and then have this plugin warn about using JSX files? I think it would achieve the same result. Curious to hear your thoughts...

@gaearon
Copy link
Contributor Author

gaearon commented Aug 4, 2016

Yeah, I guess this would technically work.

@tizmagik
Copy link
Contributor

tizmagik commented Aug 4, 2016

Alright, in that case, I'll push up a new commit to add ".jsx" to resolve.extensions[]

@tizmagik
Copy link
Contributor

tizmagik commented Aug 4, 2016

I left it out of the prod webpack config, which I think makes sense.

#361 ready for review.

Thanks.

@navarrorc
Copy link

navarrorc commented Aug 8, 2016

Just a question. Why all the fuzz about .jsx. Isn't it the desired extension when working with JSX? I was wondering why create-react-app uses the .js file extension for all files even if the file contains JSX. I'm just curious, thanks in advance for any explanation. 😃

Found my answer here: #87 (comment)

@gaearon
Copy link
Contributor Author

gaearon commented Aug 8, 2016

I think that if people only use "JSX" theme in component files, they miss out on all the ES6 + beyond highlighting that "Babel" themes (often marketed as JSX) usually implement.

Ideally we should just include proper instructions on installing a Babel syntax theme.

@tizmagik
Copy link
Contributor

tizmagik commented Aug 8, 2016

Ideally we should just include proper instructions on installing a Babel syntax theme.

+1 for that!

Anyway, any other feedback here @gaearon or is this good to merge? #361

@gaearon
Copy link
Contributor Author

gaearon commented Aug 8, 2016

I’ll get back to it as soon as I’m done with other things. 😉

@atellmer
Copy link

I use jsx extension because my editor( VS Code) support Emmet only for jsx files.

@tomitrescak
Copy link

If there is no support for jsx, also all typescript users are not in play as TS compiles TSX to JSX :/ It would be great to have the possibility to set the resolve. extensions bit.

@chaffeqa
Copy link

chaffeqa commented Aug 15, 2016

Having had a similar discussion on .jsx extensions in general, can I offer this opinion and then a solution based on it:

  • Including different extensions should be a developers choice, so an opinion
  • As a technology that is quickly changing, its easy to say just throw .babel.js, or .es6.js..., but when you think down the road, introducing more complexity into an already complex environment just adds more unsure-ness to those trying to keep up / pick up
  • Most of the boilerplate react projects I've seen out there just use .js, makes it all less scary to someone jumping in
  • Editor highlighting should not dictate the direction of a tool, it should be the other way around

Therefore, my proposed solution would be:

  1. Once this tool's webpack config is extendable, allow for those extensions
  2. Document how to add .jsx, .tsx, or any other extensions to babel plugins / resolvers

PS: this is coming from someone who has had to learn react from scratch in the last month and use it to inceptualize a large project's codebase

@gaearon
Copy link
Contributor Author

gaearon commented Sep 2, 2016

Okay, let’s add support for .jsx. Will merge a PR that does that.

@tizmagik
Copy link
Contributor

tizmagik commented Sep 3, 2016

@gaearon #563

@gaearon
Copy link
Contributor Author

gaearon commented Sep 3, 2016

We support JSX extension since 0.4.1 even though we don’t recommend it.
Read the release notes.

@gaearon gaearon closed this as completed Sep 3, 2016
mrtnzlml added a commit to mrtnzlml-archive/connector-frontend that referenced this issue Dec 6, 2016
@lock lock bot locked and limited conversation to collaborators Jan 22, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

7 participants