Reputation: 6213
I'm writing a simple express server with webpack that renders a react app server-side, but I can't get it to compile JSX. Here is the error I see when I run the webpack build:
ERROR in /src/components/Hello.js
Module build failed (from ./node_modules/babel-loader/lib/index.js):
SyntaxError: /Users/xxx/Documents/xxxx/client/src/components/Hello.js: Unexpected token (5:11)
3 | class Hello extends Component {
4 | render() {
> 5 | return <h1>Hi</h1>
| ^
6 | }
7 | }
8 |
I have installed babel and react, here is my package dependencies:
"dependencies": {
"express": "^4.17.1",
"react": "^16.12.0",
"react-dom": "^16.12.0"
},
"devDependencies": {
"@babel/core": "^7.8.4",
"@babel/preset-env": "^7.8.4",
"@babel/preset-react": "^7.8.3",
"babel-loader": "^8.0.6",
"webpack": "^4.41.6",
"webpack-cli": "^3.3.11",
"webpack-node-externals": "^1.7.2"
}
here is my .babelrc
file:
{
'presets': ['@babel/preset-env', '@babel/preset-react']
}
and here is my webpack config:
const path = require('path');
const webpack = require('webpack');
const nodeExternals = require('webpack-node-externals');
module.exports = {
target: 'node',
entry: {
server: './server.js',
},
output: {
path: path.join(__dirname, 'dist'),
publicPath: '/',
filename: '[name].js'
},
node: {
// Need this when working with express, otherwise the build fails
__dirname: false, // if you don't put this is, __dirname
__filename: false, // and __filename return blank or /
},
externals: [nodeExternals()], // Need this to avoid error when working with Express
module: {
rules: [
{
test: /\.js(x?)$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader'
}
}
]
}
}
How can I get my JSX file to compile with the build?
UPDATE
I figured out that the problem is due to my file structure - I have a separate app for the client and a separate app for the server, and I am trying pulling the "Hello" component from the client app.
Here's my file structure:
-/client
-package.json
-/src
-/components
-Hello.jsx
-/server
-package.json
-server.js
I am importing the Hello component in my server.js
file like this:
import Hello from '../client/src/components/Hello.jsx';
I discovered that if I move the components folder into the /server directory and update the import path, it works fine.
So the real question is - how do I import a component that lives outside my project root?
Upvotes: 1
Views: 1763
Reputation: 8528
After playing around with the repo you provided, I was able to get this to work. The trick was getting rid of the .babelrc
and moving those options into the webpack config.
You can check out all the changes I made here
This is the new webpack config
// file: /server/webpack.server.js
const path = require('path');
const nodeExternals = require('webpack-node-externals');
module.exports = {
mode: 'development',
entry: './server.js',
target: 'node',
externals: [nodeExternals()],
output: {
path: path.resolve('dist'),
filename: 'server.js'
},
module: {
rules: [
{
test: /\.(js|jsx)$/,
include: [
path.resolve(__dirname),
path.resolve(__dirname, "../client/src/components")
],
exclude: /node_modules/,
use: {
loader: "babel-loader",
/* --------------- THIS IS WHAT I ADDED --------------- */
options: {
presets: [
require.resolve('@babel/preset-react'),
require.resolve('@babel/preset-env')
]
}
/* ---------------------------------------------------- */
}
}
]
},
resolve: {
alias: {
components: path.resolve(__dirname, "../client/src/components")
}
}
};
Working!!!
Upvotes: 2