It's recommended to use the .jsx file extension for React components.
So, wouldn't it be great to add .jsx extension in webpack?
This will also help with editors doing syntax highlighting & linting.
Interesting. Where did you get the information that .jsx
is the recommended extension? I did a quick google search but couldn't find any official comments on this. I must admit that my google foo isn't the best.
Yea, I prefer .jsx simply for auto language selection in editors.
From airbnb style guide which is actually the mostly used in JavaScript projects linting.
@7s4r Ok, I know the airbnb style guide. What I was waiting for was a comment directly from facebook or babel. But sure the airbnb style guide is a good point. Maybe supporting both would be the right way to go. You already mentioned this in the description of the issue. So this gets a :+1: from me :).
Another point in favor of supporting the .jsx
extension is that TypeScript compiles to that extension whenever you target ES6/ES2015
airbnb
/ eslint-plugin-react
is complaining about react/jsx-filename-extension rule
Now that the webpack config can be manipulated this is possible https://github.com/zeit/next.js#customizing-webpack-config
Is there an example for how to make this work using next.config.js? As far as I can tell, this would require overwriting at least four loaders produced by the framework (babel-loader
, hot-self-accept-loader
, react-hot-loader/webpack
, and emit-file-loader
) which those docs explicitly calls out as a bad idea and kind of defeats the purpose of the framework.
I'm fine with this not being supported if that's the official stance, but the above comment seems to suggest that it is.
@AlteredConstants something like this:
module.exports = {
webpack: (config, { dev }) => {
config.resolve.extensions = ['', '.js', '.jsx'];
return config;
}
}
_However_, having just tried this, it looks like this approach does not work. I'll have to dig in to figure out why.
@rossipedia, that will only allow Webpack to recognize imported modules with a .jsx extension when the extension is excluded from the import, e.g. import Foo from './Foo'
instead of import Foo from './Foo.jsx'
.
In order to get Webpack to correctly process those modules, you need to (presumably) add .jsx
to the test
property of the loaders mentioned above. That feels a bit heavy-handed and prone to error, and it doesn't handle the pre-rendered case according to the docs linked above. I'm also not sure the automatic page/
importing will even work in that case鈥攖hat appears to happen outside of the Webpack process and/or perhaps as separate entry points?
Understandably, module resolution is more complicated in this framework than a simple Webpack config option. So again, unless I'm mistaken, the resolution to this issue seems to be "won't fix" more so than "workaround", and I just wanted to be clear on the team's stance. @impronunciable, any more insight?
Should add this to FAQ.
module.exports = {
webpack: (config) => {
config.resolve.extensions = ['.js', '.jsx'];
config.module.rules.push(
{test: /\.(js|jsx)$/, use: 'babel-loader'}
);
return config;
}
}
@J-F-Liu not working for me.
I'm getting Error: Cannot find module '../components/Page'
or Module build failed: Error: Couldn't find preset "stage-3" relative to directory "/Users/cla/Projects/with-mobx/node_modules/styled-jsx"
Trying to setup next.js 2-beta + mobx + airbnb
Maybe I miss something? What's your .babelrc
content?
It seems also pages
extensions cannot be .jsx
@foxhound87 yes, that doesn't work, I also give up.
TypeScript 2.2 now supports "jsx": "react-native"
, which will output .js
files but also preserve JSX. See here
same problem here :<, any ideas how to solve this?
I ran into this while writing a bake-off as our company standard is to use .jsx
for any files containing jsx markup. Understanding this is a webpack config and shouldn't impact performance, is there a reason specifically Next.js doesn't support jsx imports?
_Edit:_
As noted above, using the webpack config works well for importing components but files in /pages/
must have a .js extension to be routed correctly. As silly as this issue may seem, large teams must follow the standards/conventions put in place so this may block adoption of this great framework.
I'm really liking everything about Next except for this, which unfortunately precludes our using it.
I'll check back in to see if any progress is made though.
The issue seems to extend far deeper than Webpack and Babel; it is hardcoded in numerous places. :(
The only effort I've made so far is adding a line for "jsx" in server/resolve.js:34
. I'm doing this through modifying files under my project's node_modules/next/dist/
.
Making the modification outputs the below in the console. Note that the console now says Building page: /
, rather than Client pings, but there's no entry for page: /
.
DONE Compiled successfully in 12156ms 8:34:44 PM
> Ready on http://localhost:3000
> Building page: /
DONE Compiled successfully in 10983ms 8:34:58 PM
SyntaxError: Unexpected token m in JSON at position 0
at JSON.parse (<anonymous>)
at _callee$ (/Users/Jason/Repositories/radioapp/node_modules/next/dist/server/read-page.js:48:32)
at tryCatch (/Users/Jason/Repositories/radioapp/node_modules/regenerator-runtime/runtime.js:64:40)
at Generator.invoke [as _invoke] (/Users/Jason/Repositories/radioapp/node_modules/regenerator-runtime/runtime.js:299:22)
at Generator.prototype.(anonymous function) [as next] (/Users/Jason/Repositories/radioapp/node_modules/regenerator-runtime/runtime.js:116:21)
at step (/Users/Jason/Repositories/radioapp/node_modules/babel-runtime/helpers/asyncToGenerator.js:17:30)
at /Users/Jason/Repositories/radioapp/node_modules/babel-runtime/helpers/asyncToGenerator.js:28:13
This issue is actually bearable for me, because I simply created a server
directory with a .eslintrc
file:
{
"parser": "espree",
"parserOptions": {
"ecmaVersion": 6,
},
"env": {
"node": true
},
}
In case it is helps anyone, you can configure different linter and also Sublime settings per directory. You can also create a public
directory that contains your Next.js files and put the appropriate .eslintrc
file there.
I'm using Sublime, with babel-sublime and SublimeLinter-contrib-eslint.
@jasonszhao I agree. But it's unlikely we are going to support .jsx
support. Use .js
extension.
@arunoda That's a shame. Many of us can't use it because of this arbitrary design choice. Guess I'm uninstalling.
Wouldn't it make more sense to make it configurable? Use next.config.js
and have an option that defaults to ['.js']
, or better yet a function that can filter things out such as .test.js
or .spec.js
for Jest.
EDIT: I'm trying to use .tsx
as I cannot use the tsc
approach in the TypeScript example as I'm trying to also run a custom server in TypeScript as well.
Is .jsx
still not supported? I'm also running into an issue that my company would block from using next.js
since our standard is to use .jsx
for React components.
I know this one seems trivial but it's really making it difficult for our team to justify adopting Next :(
Would be awesome if someone from the core team could elaborate a bit on this seemingly non-consequential design decision.
+1 for .jsx extension support
You can easly add .jsx support but... not for SSR. You will get an error with that, but after changing something in the code and hot reload - you will see your page. F5 and boom, error.
Not sure how to fix that.
const originalJS = "/\\.js(\\?[^?]*)?$/";
config.resolve.extensions = [".js", ".jsx", ".json"];
config.module.rules.forEach((rule) => {
if (String(rule.test) === originalJS) {
rule.test = /\.jsx?(\?[^?]*)?$/;
}
});
Like many, I don't get why this can't happen.
Many people use a linter config that says use jsx, editors use it to help differentiate between regular js and jsx and ... well seriously is it that big a deal to add it? If I understood the code well enough I'd just do it myself but...
PLEEEEASE
Just throwing in some more support for the idea that .jsx
can reasonably be expected to work "out of the box". The workaround is trivial once someone figures out what the problem is (and finds this issue), but in my experience it is a _widely adopted convention_ (intentionally side-stepping "recommended" verbiage here) to use the .jsx
extension for files that primarily export a React Component.
I'm about to simply swap extensions and continue on my way, but I'm struggling to understand why there's resistance to this. More importantly than this being a reasonable request, for many devs it's expected behavior, and (marginally) ratchets up the barrier to entry. And while I don't want to spin this off into a debate about the merits of .jsx
as an extension in the first place, suffice it to say that it's not entirely unreasonable to only want valid JavaScript in .js
files, and I would argue that's a sentiment that is held by many existing and potential next.js users.
Btw, just getting started, but loving things so far. Thanks for all the awesome work!
That's probably linked, I couldn't used a .md
extension. I had to use the following trick to make it work on the server (.md.js
):
next.config.js
// ...
{
test: /\.md\.js$/,
loader: 'raw-loader',
},
// ...
I use eslint with airbnb and added another rule to silence the warning
{
"extends": "airbnb",
"rules": {
"react/jsx-filename-extension": [1, { "extensions": [".js", ".jsx"] }]
}
}
Does anyone have a working example where .jsx
files are
pages
directory,?
This would make a great addition to the /examples
directory.
+1 for adding jsx support.
I fixed it by doing something similar to what @rossipedia was suggesting.
If it's not already there, create next.config.js at the root of the project.
Then simply push 'jsx' to the config.resolve.extensions array, it works just fine.
module.exports = {
webpack: function (config, { isServer }) {
config.resolve.extensions.push('.jsx');
return config
}
}
EDIT
Be careful, this modification seems to have a bad impact on performances. Going to investigate further.
If you鈥檙e using next v5 there is no need to change anything whatshowever, the .jsx extension is supported out of the box. If you鈥檙e seeing anything performance related try upgrading to next@canary.
I noticed that, awesome!
Most helpful comment
+1 for .jsx extension support