使用Webpack Dev Server和Rails服务器实现Webpack热重载

3

我的当前应用程序是使用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' />

然后 React 代码将运行在此之上。

这是我尝试使用的命令,以使热重载起作用。

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的版本信息:

"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个回答

3

由于您第一次设置webpack dev服务器,问题有两个:

  1. 设置webpack dev服务器
  2. 配置热重载

设置webpack dev服务器

我假设您的应用程序是API服务器。同样,webpack-dev-server也是一个HTTP服务器。事实上,它只是expressjs的一个包装器。

在开发过程中使用webpack dev服务器时,捆绑包由webpack dev服务器提供,并且所有xhr请求都发送到该dev服务器。为了将这些请求路由到您的应用程序服务器,您需要向webpack配置添加代理规则。

从高层次上看,流程如下所示。

浏览器 ---(xhr请求)-----> webpack-dev-server -----(代理api请求)--->应用服务器


为了添加代理规则以将所有api请求路由到您的rails服务器,您的api路由应该以/api开头,例如,/api/customers,以便将与/api匹配的所有请求转发到rails服务器

支持上述流程的示例配置在您的webpack配置文件中可能如下所示

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
}

设置热重载

为了设置热重载,我建议使用 Dan Abramov 的 react-hot-loader,因为它在 HMR 补丁方面更少出现错误。

设置 HMR 很容易。

  1. Add the dependency yarn add react-hot-loader
  2. Add babel plugin in your .babelrc

    {
      "plugins": ["react-hot-loader/babel"]
    }
    
  3. Mark your root component as hot exported

    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添加到您的依赖项中是安全的,因为在生产构建中会剥离热重载包。 要启动热模式下的webpack服务器,可以在您的package.json中添加下面这样的脚本。
"scripts": {
    "start": "webpack-dev-server --hot --mode development --config ./webpack.dev.config"
  }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接