Горячая перезагрузка Webpack с использованием сервера разработки webpack и сервера rails

Мое текущее приложение настроено с использованием Ruby on Rails и React/Typescript. Пытаюсь настроить горячую перезагрузку.

Вот текущая структура папок

Project Root
  - app => all the rails code
  - frontend => all the react code
  - webpack => list of configuration files, like development.js and production.js

В этом проекте не используются react_on_rails или webpacker. Внешний код хранится отдельно от внутреннего кода. Бэкэнд Rails обслуживает html

<div id='root' />

и код реакции будет работать с этим.

Это команда, которую я пытался запустить, чтобы заставить работать горячую перезагрузку

node_modules/.bin/webpack-dev-server --config=./webpack/development.js  --hotOnly --entry=../frontend/Entry.tsx --allowedHosts=localhost:3000

Однако не только горячая перезагрузка не работает, внесенные мной изменения также не отображаются в браузере. Все выглядит как в терминале.

Моя проблема в том, что у меня технически два сервера работают одновременно.

localhost:3000 => Rails server
localhost:8080 => Webpack dev server. 

Если я также изменю сервер веб-пакетов, чтобы он указывал на 3000, приложение rails не будет работать должным образом.

Есть ли способ заставить горячую перезагрузку работать с этой настройкой?

вот версия вебпака

"webpack": "^4.20.1",
"webpack-cli": "^3.1.1",
"webpack-dev-server": "^3.7.1" 

webpack.development.config.js

const webpack = require('webpack');
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin');
const CaseSensitivePathsPlugin = require('case-sensitive-paths-webpack-plugin');

module.exports = {
  context: __dirname,
  entry: '../frontend/Entry.tsx',
  devtool: 'source-maps',
  resolve: {
    extensions: ['*', '.js', '.jsx', '.ts', '.tsx'],
    modules: [
      'node_modules',
      path.resolve(__dirname, '../frontend'),
      path.resolve(__dirname, '../node_modules')
    ]
  },
  output: {
    path: path.join(__dirname, `../public/javascripts/`),
    publicPath: `/javascripts/`,
    filename: '[name]-[hash].js'
  },
  module: {
    rules: [
      {
        test: /\.(t|j)sx?$/,
        loader: 'ts-loader',
        options: {
          // disable type checker - we will use it in fork plugin
          transpileOnly: true
        }
      },
      {
        enforce: 'pre',
        test: /\.(t|j)sx?$/,
        loader: 'source-map-loader'
      },
      {
        test: /\.css$/,
        use: ['style-loader', 'css-loader']
      },
      {
        test: /\.scss$/,
        use: ['style-loader', 'css-loader', 'sass-loader']
      },
      {
        test: /\.(png|svg|jpg|gif)$/,
        use: [
          {
            loader: 'file-loader',
            options: {
              name: '[name]-[hash].[ext]',
              outputPath: 'images/'
            }
          },
          {
            loader: 'image-webpack-loader',
            options: {
              pngquant: {
                quality: '40',
                speed: 4
              }
            }
          }
        ]
      }
    ]
  },
  plugins: [
    new webpack.DefinePlugin({
      'process.env': {
        NODE_ENV: JSON.stringify('development')
      }
    }),
    new HtmlWebpackPlugin({
      template: path.join(__dirname, '..', 'application.html'),
      filename: path.join(__dirname, '..', 'app', 'views', 'layouts', '_javascript.html.erb')
    }),
    // runs typescript type checker on a separate process.
    new ForkTsCheckerWebpackPlugin({
      checkSyntacticErrors: true,
      tsconfig: '../tsconfig.json'
    }),
    new CaseSensitivePathsPlugin()
  ],
  optimization: {
    splitChunks: { chunks: 'all' }
  }
};

person davidhu    schedule 15.06.2019    source источник


Ответы (1)


Поскольку вы настраиваете сервер разработки webpack в первый раз, проблема состоит из двух частей:

  1. Настройка сервера разработки webpack
  2. Настроить горячую перезагрузку

Настройка сервера разработки webpack

Я предполагаю, что ваше приложение является сервером API. Точно так же webpack-dev-server тоже является http-сервером. Это просто оболочка вокруг экспресс-факта.

при использовании сервера разработки webpack во время разработки пакеты обслуживаются сервером разработки webpack, и все запросы xhr отправляются на этот сервер разработки. Чтобы направить эти запросы на ваш сервер приложений, вам нужно добавить правила прокси в конфигурацию вашего веб-пакета.

На высоком уровне поток будет выглядеть следующим образом.

browser ---(xhr requests)-----> webpack-dev-server -----(proxy api requests)--->app server


Чтобы добавить прокси-правило для маршрутизации всех запросов API на ваш сервер rails, ваши маршруты API должны начинаться с /api, например, /api/customers, чтобы все запросы, соответствующие /api, перенаправлялись на сервер rails.

Пример конфигурации для поддержки вышеуказанного потока будет выглядеть следующим образом в вашем конфигурационном файле веб-пакета.

module.exports = {
  // ...your other configs
  devServer: {
    contentBase: path.join(__dirname, 'public/'),
    port: 8080,
    publicPath: 'http://localhost:8080/', // Path of your dev server
    historyApiFallback: true, // add this if you are not using browser router
    proxy: {
      '/api': { // string to look for proxying requests to api
        target: 'http://localhost:3000', // Path of your rails api server
      },
    },
  },
  // ...your other configs
}

Настройка горячей перезагрузки

Для настройки горячей перезагрузки я бы рекомендовал использовать react-hot-loader так как он меньше глючит при патчинге hmr.

Настроить HMR легко

  1. Добавьте зависимость yarn add react-hot-loader
  2. Добавьте плагин babel в свой .babelrc

    {
      "plugins": ["react-hot-loader/babel"]
    }
    
  3. Отметьте свой корневой компонент как горячий экспорт

    import { hot } from 'react-hot-loader/root'; // this should be imported before react and react-dom
    const App = () => <div>Hello World!</div>;
    export default hot(App);
    

Примечание. Безопасно добавлять react-hot-loader в ваши зависимости, потому что в вашей производственной сборке. Пакет горячей перезагрузки будет удален.

Чтобы запустить сервер веб-пакетов в горячем режиме, вы можете добавить скрипт, как показано ниже, в файл package.json.

"scripts": {
    "start": "webpack-dev-server --hot --mode development --config ./webpack.dev.config"
  }
person johnny peter    schedule 15.06.2019