如何解决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 举报,一经查实,本站将立刻删除。