簡體   English   中英

使用 express 服務器在 React 應用程序中熱重載

[英]Hot reloading in a React app with express server

到目前為止,我已經為 MERN 應用程序設置了一個樣板,該應用程序在后端有一個快速服務器並在前端做出反應。 我打算在我的應用程序中設置熱重載——只要反應代碼有任何變化,而無需刷新整個應用程序(HMR)。

我安裝了webpack-dev-serverHotModuleReplacementPlugin 我還嘗試在--hotwebpack腳本中使用package.json 如果我運行npm run webpack ,代碼編譯,服務器在localhost:8080啟動。 它給了我這樣的東西,這不是我真正想要的。 我不知道它看起來像是在向我顯示根目錄。

在此處輸入圖像描述

另一方面,如果我運行npm start ,服務器將啟動並顯示我想要的反應組件,但需要熱重新加載。 現在,我必須刷新頁面才能看到更改。

在此處輸入圖像描述

所以,我試圖了解到底發生了什么? 當我輸入npm start時,有沒有辦法添加熱重載?



客戶端/index.js

import React from "react"
import ReactDOM from "react-dom"
import App from "./containers/App"

ReactDOM.render(<App />, document.getElementById("root"))


客戶端/容器/App.js

class App extends Component {
  render() {
    return (
      <div>
        <Router>
          <Switch>
            <Route exact path="/" component={HomePage} />
          </Switch>
        </Router>
      </div>
    )
  }
}

export default App


客戶端/組件/HomePage.js

const HomePage = () => {
  return (
    <div>
      <h1>React HomePage</h1>
    </div>
  )
}

export default HomePage


路線/index.js

var express = require('express');
var router = express.Router();

/* GET home page. */
router.get('/*', function(req, res, next) {
  res.render('index', { title: 'Travel Forum' });
});

module.exports = router;


意見/index.ejs

<!DOCTYPE html>
<html>
  <head>
    <title><%= title %></title>
  </head>
  <body>
    <div id="root"></div>
    <script src="/static/bundle.js"></script>
  </body>
</html>


package.json

  "scripts": {
    "start": "NODE_ENV=development nodemon ./bin/www",
    "webpack": "webpack-dev-server --config ./webpack.config.js --mode development --hot"
  },


webpack.config.js

/* eslint-disable */
var webpack = require("webpack")
var path = require("path")
const MiniCssExtractPlugin = require("mini-css-extract-plugin")

module.exports = {
  mode: "development",
  devtool: "inline-source-map",
  entry: ["./client/index.js"],
  module: {
    rules: [
      {
        test: /\.(js|jsx)$/,
        exclude: /node_modules/,
        use: { loader: "babel-loader" },
      },
      {
        test: /\.(scss|css)$/,
        use: [
          { loader: MiniCssExtractPlugin.loader },
          {
            loader: "css-loader",
          },
          { loader: "sass-loader" },
        ],
      },
      {
        test: /\.(png|jpg|gif|jpeg)$/,
        use: [
          {
            loader: "file-loader",
            options: {},
          },
        ],
      },
    ],
  },
  resolve: {
    extensions: [".js", ".jsx"],
  },
  output: {
    filename: "bundle.js",
    path: __dirname + "/dist/bundle/",
    publicPath: "/static/",
  },
  plugins: [
    new webpack.HotModuleReplacementPlugin(),
    new webpack.DefinePlugin({
      "process.env": {
        NODE_ENV: JSON.stringify("development"),
      },
    }),
    new MiniCssExtractPlugin({
      filename: "bundle.css",
    }),
  ],
}


應用程序.js

const createError = require("http-errors")
const express = require("express")
const bodyParser = require("body-parser")
const path = require("path")
const cookieParser = require("cookie-parser")
const logger = require("morgan")
const mongoose = require("mongoose")

const indexRouter = require("./routes/index")
const userRouter = require("./routes/users")

const app = express()

// view engine setup
app.set("views", path.join(__dirname, "views"))
app.set("view engine", "ejs")

app.use(logger("dev"))
app.use(express.json())
app.use(bodyParser.json())
app.use(express.urlencoded({ extended: false }))
app.use(cookieParser())
app.use(express.static(path.join(__dirname, "public")))

if (process.env.NODE_ENV === "development") {
  const webpack = require("webpack")
  const webpackConfig = require("./webpack.config")
  const compiler = webpack(webpackConfig)

  app.use(
    require("webpack-dev-middleware")(compiler, {
      noInfo: true,
      publicPath: webpackConfig.output.publicPath,
    })
  )

  app.use(require("webpack-hot-middleware")(compiler))
}

mongoose.connect(
  "mongodb://localhost:27017/travel-forum",
  { useNewUrlParser: true, useUnifiedTopology: true, useFindAndModify: false },
  function (err) {
    if (err) {
      console.log("Not connected to the database")
    } else {
      console.log("Connected to the database")
    }
  }
)

app.use("/api/v1/users", userRouter)
app.use("/*", indexRouter)

// catch 404 and forward to error handler
app.use(function (req, res, next) {
  next(createError(404))
})

// error handler
app.use(function (err, req, res, next) {
  // set locals, only providing error in development
  res.locals.message = err.message
  res.locals.error = req.app.get("env") === "development" ? err : {}

  // render the error page
  res.status(err.status || 500)
  res.render("error")
})

module.exports = app


**我通過以下方式解決了它:**

express 有兩個模塊,你可以安裝熱刷新而不刷新瀏覽器,它會自動刷新:我把我的配置留給你。

npm i livereload

npm i connect-livereload

const livereload = require('livereload');

const connectLivereload = require('connect-livereload');

const liveReloadServer = livereload.createServer();

liveReloadServer.watch(path.join(__dirname, '..', 'dist', 'frontend'));

const app = express();

app.use(connectLivereload());

在此處輸入圖像描述

請注意,您要監視的文件夾位於 dist/frontend。 更改要監視的文件夾以使其正常工作:要監視我正在使用 NODEMON 的后端

livereload在后端為瀏覽器打開一個端口以公開更改:連接是如何發生的? 這很簡單; express 使用“ connect-livereload ”並注入一個監視該端口的腳本:如果發生更改,則通過 express 通知瀏覽器,並且瀏覽器將為您刷新

我將信息盡可能簡單地留給測試,我不建議這樣使用它:要使用它,您必須將開發環境和生產環境分開。 我保持簡單,以便於理解。

在這里,我留下了我找到的最相關的鏈接:我希望它也會有所幫助。

https://bytearcher.com/articles/refresh-changes-browser-express-livereload-nodemon/

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM