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