简体   繁体   中英

How to compile JSX server side

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?

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!!!

在此处输入图片说明

try to add:

resolve: {
  extensions: ['.js', '.jsx']
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM