Как скомпилировать серверную часть JSX - PullRequest
1 голос
/ 23 февраля 2020

Я пишу простой express сервер с веб-пакетом, который рендерит серверную часть реагирующего приложения, но я не могу заставить его скомпилировать JSX. Вот ошибка, которую я вижу при запуске сборки веб-пакета:

    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 |

Я установил babel и реагирую, вот мои зависимости пакета:

 "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"
  }

вот мои .babelrc file:

{
  'presets': ['@babel/preset-env', '@babel/preset-react']
}

и вот мой конфиг веб-пакета:

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'
        }
      }
    ]
  }
}

Как мне получить файл JSX для компиляции со сборкой?

UPDATE

Я выяснил, что проблема связана с моей файловой структурой - у меня есть отдельное приложение для клиента и отдельное приложение для сервера, и я пытаюсь извлечь компонент «Hello» из клиентское приложение.

Вот моя файловая структура:

-/client
 -package.json
 -/src
  -/components
   -Hello.jsx
-/server
 -package.json
 -server.js

Я импортирую компонент Hello в мой server.js файл следующим образом:

import Hello from '../client/src/components/Hello.jsx';

Я обнаружил, что если я переместлю папку компонентов в каталог / server и обновлю путь импорта, он будет работать нормально.

Поэтому реальный вопрос - как мне импортировать компонент, который находится за пределами моего проекта root?

Ответы [ 2 ]

1 голос
/ 23 февраля 2020

Поиграв с предоставленным вами репо, я смог заставить это работать. Хитрость заключалась в том, чтобы избавиться от .babelrc и перенести эти параметры в конфигурацию веб-пакета.

Вы можете проверить все сделанные мной изменения

Это новая конфигурация веб-пакета

// 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")
    }     
  }
};


Работает !!!

enter image description here

0 голосов
/ 23 февраля 2020

попробуйте добавить:

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