Горячая перезагрузка Webpack с использованием сервера webpack dev и сервера rails - PullRequest
1 голос
/ 15 июня 2019

Мое текущее приложение настроено с использованием 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. 

Если я изменю сервер webpack на 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' }
  }
};

1 Ответ

1 голос
/ 15 июня 2019

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

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

Настройка сервера webpack dev

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

при использовании сервера разработки веб-пакетов во время разработки пакеты обслуживаются сервером разработки веб-пакетов, и все запросы 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
}

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

Чтобы настроить горячую перезагрузку, я бы рекомендовал использовать реактив-горячий загрузчик Дана Абрамова , так как он менее глючит при исправлении 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"
  }
...