Webpack的HMR损坏

问题描述

我按照步骤在我的SSR React + Express APP上添加了webpack-hot-middleware,但是它不起作用。

server.js

import express from "express";
import cors from "cors";
import dotenv from "dotenv";
import webpack from "webpack";
import helmet from "helmet";
import React from "react";
import { searchTrack } from "api/server";
import { renderToString } from "react-dom/server";
import { renderRoutes } from "react-router-config";
import { StaticRouter } from "react-router-dom";
import { Layout } from "components";
import serverRoutes from "../frontend/routes/serverRoutes";
import getManifest from "./getManifest";

dotenv.config();

const { ENV,PORT_DEV,PORT_PRO } = process.env;
const port = ENV === "development" ? PORT_DEV : PORT_PRO;

const app = express();
app.use(
  cors({
    origin: ["*"],})
);

if (ENV === "development") {
  console.log("#########################################");
  console.log("Enviroment: ","Working on develop");

  const webpackConfig = require("../../webpack.config");
  const webpackDevMiddleware = require("webpack-dev-middleware");
  const webpackHotMiddleware = require("webpack-hot-middleware");
  const compiler = webpack(webpackConfig);

  const serverConfig = {
    port: PORT_DEV,hot: true,};

  app.use(webpackDevMiddleware(compiler,serverConfig));
  app.use(webpackHotMiddleware(compiler));
}

if (ENV === "production") {
  app.use((request,response,next) => {
    if (!request.hashManifest) {
      request.hashManifest = getManifest();
    }
    next();
  });
  app.use(express.static(`${__dirname}/public`));
  app.use(helmet.permittedCrossDomainPolicies());
  app.disable("x-powered-by");
}

const setResponse = (html,manifest) => {
  const mainStyles = manifest ? manifest["main.css"] : "assets/main.css";
  const mainBuild = manifest ? manifest["main.js"] : "assets/main.js";
  const vendorBuild = manifest ? manifest["vendors.js"] : "assets/vendor.js";

  return `
      <!DOCTYPE html>
      <html lang="es">
        <head>
          <Meta charset="utf-8" />
          <link href="${mainStyles}" rel="stylesheet" type="text/css">
          <Meta name="viewport" content="width=device-width,initial-scale=1.0">
          <title>Lyrics.io</title>
        </head>
        <body>
          <div id="root">${html}</div>
          <script src="${mainBuild}" type="text/javascript"></script>
          <script src="${vendorBuild}" type="text/javascript"></script>
        </body>
      </html>
    `;
};

const renderApp = (request,response) => {
  const html = renderToString(
    <Layout>
      <StaticRouter location={request.url} context={{}}>
        {renderRoutes(serverRoutes)}
      </StaticRouter>
    </Layout>
  );

  response.send(setResponse(html,request.hashManifest));
};

app.get("/searchTracks/:search/:sort",(req,res) => {
  const { search,sort } = req.params;

  searchTrack(search,sort)
    .then(
      (response) =>
        response.status === 200 &&
        res.send(response.data.message.body.track_list)
    )
    .catch((error) => console.log(error));
});

app.get("*",renderApp);

app.listen(process.env.PORT || port,(error) => {
  if (error) {
    console.log("Error: ","can not run the server.");
  } else {
    console.log(`Server running on port ${port} - ${ENV}`);
    console.log("#########################################");
  }
});

webpack.config.js

const path = require("path");
const webpack = require("webpack");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const CompressionWebpackPlugin = require("compression-webpack-plugin");
const TerserPlugin = require("terser-webpack-plugin");
const ManifestPlugin = require("webpack-manifest-plugin");

require("dotenv").config();

const isDev = process.env.ENV === "development";
const entry = ["./src/frontend/index.js"];

if (isDev) {
  entry.push(
    "webpack-hot-middleware/client?path=/__webpack_hmr&timeout=2000&reload=true"
  );
}

console.log(entry);

module.exports = {
  devtool: !isDev ? "hidden-source-map" : "eval-cheap-source-map",entry,mode: process.env.ENV,output: {
    path: path.resolve(__dirname,"src/server/public"),filename: isDev ? "assets/main.js" : "assets/main-[hash].js",publicPath: "/",},resolve: {
    alias: {
      styles: path.resolve(__dirname,"./src/frontend/assets"),components: path.resolve(__dirname,"./src/frontend/components"),api: path.resolve(__dirname,"./src/api"),extensions: [".js",".jsx"],optimization: {
    minimize: true,minimizer: [new TerserPlugin()],splitChunks: {
      chunks: "async",name: true,cacheGroups: {
        vendors: {
          name: "vendors",chunks: "all",reuseExistingChunk: true,priority: 1,filename: isDev ? "assets/vendor.js" : "assets/vendor-[hash].js",enforce: true,test(module,chunks) {
            const name = module.nameForCondition && module.nameForCondition();
            return chunks.some(
              (chunk) =>
                chunk.name !== "vendors" && /[\\/]node_modules[\\/]/.test(name)
            );
          },module: {
    rules: [
      {
        test: /\.(js|jsx)$/,exclude: /node_modules/,use: {
          loader: "babel-loader",{
        test: /\.styl$/,use: ["style-loader","css-loader","stylus-loader"],{
        test: /\.(s*)css$/,use: [
          {
            loader: MiniCssExtractPlugin.loader,],{
        test: /\.(png|gif|jpg)$/,use: [
          {
            loader: "file-loader",options: {
              name: "assets/[hash].[ext]",devServer: {
    historyApiFallback: true,plugins: [
    isDev ? new webpack.HotModuleReplacementPlugin() : () => {},!isDev
      ? new CompressionWebpackPlugin({
          test: /\.js$|\.css$/,filename: "[file].gz",})
      : () => {},!isDev ? new ManifestPlugin() : () => {},new MiniCssExtractPlugin({
      filename: isDev ? "assets/main.css" : "assets/main-[hash].css",}),};

babel.rc

{
  "presets": [
    "@babel/preset-env","@babel/preset-react"
  ],"plugins": [
    "react-hot-loader/babel","babel-plugin-webpack-alias"
  ]
}

对package.json的依赖

  "dependencies": {
    "@babel/preset-env": "^7.11.5","@babel/preset-react": "^7.10.4","@babel/register": "^7.11.5","@testing-library/jest-dom": "^4.2.4","@testing-library/react": "^9.5.0","@testing-library/user-event": "^7.2.1","asset-require-hook": "^1.2.0","axios": "^0.20.0","babel-loader": "^8.1.0","babel-plugin-webpack-alias": "^2.1.2","compression-webpack-plugin": "^6.0.3","cors": "^2.8.5","dotenv": "^8.2.0","express": "^4.17.1","helmet": "^4.1.1","history": "^5.0.0","husky": "^4.3.0","ignore-styles": "^5.0.1","mini-css-extract-plugin": "^0.12.0","react": "^16.13.1","react-dom": "^16.13.1","react-hot-loader": "^4.13.0","react-icons": "^3.11.0","react-router": "^5.2.0","react-router-config": "^5.1.1","react-router-dom": "^5.2.0","react-scripts": "3.4.3","style-loader": "^2.0.0","stylus": "^0.54.8","stylus-loader": "^4.1.1","terser-webpack-plugin": "^4.2.3","webpack": "^4.44.2","webpack-manifest-plugin": "^2.2.0"
  },"devDependencies": {
    "css-loader": "^4.3.0","eslint": "^7.10.0","eslint-config-prettier": "^6.12.0","eslint-config-standard": "^14.1.1","eslint-plugin-import": "^2.22.1","eslint-plugin-node": "^11.1.0","eslint-plugin-promise": "^4.2.1","eslint-plugin-react": "^7.21.3","eslint-plugin-standard": "^4.0.1","file-loader": "^6.1.0","lint-staged": "^10.4.0","nodemon": "^2.0.4","path": "^0.12.7","prettier": "^2.1.2","webpack-cli": "^3.3.12","webpack-dev-middleware": "^3.7.2","webpack-hot-middleware": "^2.25.0"
  },

这是我启动以在开发模式下启动的命令

“ start-dev”:“ nodemon src / server / index.js”

当我更改样式时,它起作用了,但是当我对某个组件的某些东西不改变时。

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)