Why build a local server?


Webpack watch


webpack-dev-server

  • cnpm install –save-dev webpack-dev-server
  • Notice that the script is “serve”: “webpack serve”


Webpack-dev – Middleware


Webpack dev – the use of middleware


Understanding module hot Replacement (HMR)


Open the HMR


Framework of HMR


The React of HMR

  • cnpm install -D @pmmmwh/react-refresh-webpack-plugin react-refresh


The Vue HMR

  • cnpm install vue-loader vue-template-compiler -D


The principle of HMR


Schematic diagram of HMR


webpack.config.js

const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const ReactRefreshWebpackPlugin = require('@pmmmwh/react-refresh-webpack-plugin');
const VueLoaderPlugin = require('vue-loader/lib/plugin');

module.exports = {
  // watch: true,
  mode: "development".entry: "./src/index.js".output: {
    filename: "bundle.js".path: path.resolve(__dirname, "./build")},// Specifically configured for webpack-dev-server
  devServer: {
    hot: true
  },
  module: {
    rules: [{test: /\.jsx? $/i,
        use: "babel-loader"
      },
      {
        test: /\.vue$/i,
        use: "vue-loader"
      },
      {
        test: /\.css/i,
        use: [
          "style-loader"."css-loader"]]}},plugins: [
    new HtmlWebpackPlugin({
      template: "./index.html"
    }),
    new ReactRefreshWebpackPlugin(),
    new VueLoaderPlugin()
  ]
}
Copy the code

package.json

{
  "name": "webpack_devserver"."version": "1.0.0"."description": ""."main": "index.js"."scripts": {
    "build": "webpack"."watch": "webpack --watch"."serve": "webpack serve"
  },
  "author": ""."license": "ISC"."devDependencies": {
    "@babel/core": "^ 7.12.17"."@babel/preset-env": "^ 7.12.17"."@babel/preset-react": "^ 7.12.13"."@pmmmwh/react-refresh-webpack-plugin": "^ 0.4.3." "."babel-loader": "^ 8.2.2"."css-loader": "^ 5.0.2"."html-webpack-plugin": "^ 5.2.0." "."react-refresh": "^ 0.9.0"."style-loader": "^ 2.0.0." "."vue-loader": "^ 15.9.6"."vue-template-compiler": "^ 2.6.12." "."webpack": "^ 5.23.0"."webpack-cli": "^ 4.5.0." "."webpack-dev-server": "^ 3.11.2"
  },
  "dependencies": {
    "express": "^ 4.17.1"."react": "^ 17.0.1"."react-dom": "^ 17.0.1"."vue": "^ 2.6.12." "."webpack-dev-middleware": "^ 4.1.0." "}}Copy the code

index.js

/** * Current development mode: * 1. Watch scheme to listen for file changes * 2. Providing local services via live-server plug-ins (automatically refreshing pages when files change) * is not particularly efficient: * 1. 3. Live-server belongs to VSCode plug-in (vim/webstorm) -> does not belong to our solution given by webpack * 4. Live-server rewrites the entire page each time * * webpack-dev-server: Hot Module replacement(HMR) */

import "./math";
import React from 'react';
import ReactDom from 'react-dom';
import ReactApp from './App.jsx';

import Vue from 'vue';
import VueApp from './App.vue';

console.log("Hello hahaha");
console.log("abc");

// module is a global object.
if (module.hot) {
  module.hot.accept("./math.js".() = > {
    console.log("The Math module has been updated ~");
  });
}

// React code
ReactDom.render(<ReactApp/>.document.getElementById("app"));

// Vue code
new Vue({
  render: h= > h(VueApp)
}).$mount("#root");
Copy the code

App.vue

<template>
  <div id="app">
    <h2 class="title">{{ message }}</h2>
  </div>
</template>

<script>
  export default {
    data() {
      return {
        message: "Hello hahaha"}; }};</script>

<style scoped>
  .title {
    color: blue;
  }
</style>
Copy the code

App.jsx

import React, { Component } from "react";

class App extends Component {
  constructor(props) {
    super(props);

    this.state = {
      message: "Hello React"}; }render() {
    return (
      <div>
        <h2>{this.state.message}</h2>
      </div>); }}export default App;
Copy the code

babel.config.js

module.exports = {
  presets: [["@babel/preset-env"],
    ["@babel/preset-react"]],plugins: [["react-refresh/babel"]]}Copy the code

The output of publicPath


The devServer publicPath


The devServer contentBase


HotOnly and host are configured


Port, open, compress



The Proxy agent


ChangeOrigin analytical


historyApiFallback


Resolve module resolution


Files are still folders


Extensions and Alias configurations


The directory structure


webpack.config.js

const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const ReactRefreshWebpackPlugin = require('@pmmmwh/react-refresh-webpack-plugin');
const VueLoaderPlugin = require('vue-loader/lib/plugin');

module.exports = {
  // watch: true,
  mode: "development".entry: "./src/index.js".output: {
    filename: "bundle.js".// The output directory of the packaged file
    path: path.resolve(__dirname, "./build"),
    // publicPath: Concatenates a path in front of the packaged static resource. The default value is an empty string.
    // js/bundle will be spliced into ->./js/bundle.js, accessed via a relative path
    // publicPath: "./"
    // publicPath: "/abc"
  },
  // Specifically for webpack-dev-server
  // devServer starts a local service during development
  devServer: {
    hot: true.hotOnly: true./ / host: "0.0.0.0", / / tested, cannot be accessed through the port/http://0.0.0.0:
    // port: 7777,
    // open: true,
    compress: true.// Static resources entered via SRC will look up in the configured contentBase [local service path is in "./why"]
    contentBase: path.resolve(__dirname, "./why"),
    watchContentBase: true.// The abc.js code changes automatically refresh the browser
    // In the development environment, the publicPath of devServer is the same as that of output
    // publicPath: "/abc",
    proxy: {
      // "/why": "http://localhost:8888"
      "/why": {
        // mapping, "/why" equivalent to "http://localhost:8888"
        target: "http://localhost:8888".pathRewrite: {
          "^/why": ""
        },
        secure: false./ / support HTTPS
        changeOrigin: true // Set to true if the server validates}},// historyApiFallback: true
    historyApiFallback: {
      rewrites: [{from: /abc/, to: "/index.html"}}},resolve: {
    extensions: ['.wasm'.'.mjs'.'.js'.'.json'.'.jsx'.'.ts'.'.vue'].alias: {
      "@": path.resolve(__dirname, "./src"),
      "pages": path.resolve(__dirname, "./src/pages")}},module: {
    rules: [{test: /\.jsx? $/i,
        use: "babel-loader"
      },
      {
        test: /\.vue$/i,
        use: "vue-loader"
      },
      {
        test: /\.css/i,
        use: [
          "style-loader"."css-loader"]]}},plugins: [
    new HtmlWebpackPlugin({
      template: "./index.html"
    }),
    new ReactRefreshWebpackPlugin(),
    new VueLoaderPlugin()
  ]
}
Copy the code

index.js

import axios from 'axios';

import React from 'react';
import ReactDom from 'react-dom';
import ReactApp from './App.jsx';

import Vue from 'vue';
import VueApp from './App.vue';

import "./math";

console.log("Hello Coderwhy");
console.log("abc");

if (module.hot) {
  module.hot.accept("./math.js".() = > {
    console.log("The Math module has been updated ~");
  });
}

// React code
ReactDom.render(<ReactApp/>.document.getElementById("app"));

// Vue code
new Vue({
  render: h= > h(VueApp)
}).$mount("#root");

// Axios network request
// changeOrigin: By default, the value is http://localhost:8080 because of the code used. If the server receives the source without additional configuration, the server will assume that the source of the request is http://localhost:8080. It was supposed to be "http://localhost:8888" for target, but instead of proxy, the request was changed to http://localhost:8080. If the server does not validate the source, there is no problem at this point. If the server verifies that the request is at http://localhost:8888 and finds that the request is 8080 instead of 8888, the server does not return data, so it needs to change the request to 8888. If you use a third-party library, take a proxy server and change the source to the target value http://localhost:8888, the server will authenticate.
axios.get("http://localhost:8080/why/moment").then(res= > {
  console.log(res);
}).catch(err= > {
  console.log(err);
});
Copy the code