Writing is not easy, without the permission of the author forbid to reprint in any form! If you think the article is good, welcome to follow, like and share!

Webpack-Dev-Server

Why set up a local server

  • The code currently under development requires two operations in order to run

    • npm run buildcompile
    • Open the HTML file through the live-server or directly through the browser to see the effect
  • Webpack provides several options for automatic compilation

    • Webpack watch mode
    • Webpack-dev-server
    • Webpack-dev-middleware

Webpack Watch Mode

  • Webpack provides watch mode

    • In this mode, all files in the WebPack dependency diagram will be recompiled if any of them are updated.
    • You don’t need to manuallynpm run build
  • How do I open it?

    • Method 1: In the exported configuration, add watch:true
module.exports = {
    entry: "./src/index.js".output: {
        filename: "js/bundle.js".path: path.resolve(__dirname, "build"),},watch:true,}Copy the code
  • Method 2: In the command to start the Webapck, add the –watch identifier
npm script:{
 "watch": "webpack --watch"
}
# npm run watch
Copy the code

Webpack Dev Server

  • The above method can listen to file changes, but does not automatically refresh the browser

    • Webpack-dev-server can be implemented
  • The installation

    • npm install --save webpack-dev-server
  • Modify the NPM script and configure the devServer under the devServer property in the configuration file

script:{
    "serve":"webpack serve"
}
Copy the code
  • Webpack-dev-server does not write to any output file after compilation. Instead, the bundle file is kept in memory
    • In fact, webpck-dev-server uses a library called memfs.

Webpack Dev Middleware

  • Webpack-dev-middleware is a wrapper that sends webPack-processed files to a server

    • Webpack-dev-server uses it internally, however it can also be used as a separate package for more custom configuration as required
    • Use it with a server, such as Express.
    • npm install --save express webpack-dev-middleware
  • Write Server. Js

const express = require("express")
const webpack = require("webpack")
const webpackDevMiddleware = require("webpack-dev-middleware")

const  app = express()
const config = require("./webpack.config")
const compiler = webpack(config)

app.use(webpackDevMiddleware(compiler,{
    publicPath:config.output.publicPath
}),() = >{
    console.log("Here's the callback function.")
})

app.listen(3000.() = >{
    console.log("Server running")})Copy the code
  • Nodeserver.js can run a service that listens for file changes and refreshes the browser.

PublicPath

  • Output has two important properties: path and publicPath

    • Path: Specifies the output path of the file. It is a heap path
    • PublicPath: the default is an empty string that specifies a publicPath, publicPath, for the resources in our project
  • So publicPath is a little hard to understand, but it’s basically just giving a path to the resource that we’re packaging

    • Path of the resource = output.publicepath + path of the packaged resource (e.g. “js/[name].bundle.js”)
  • The value of the commonly used

    • ./ : The relative path can be used in the local environment
    • / : Used during server deployment, server address + /js/[name].bundle.js
  • The publicPath of devServer, publicPath of Output, and publicPath of webpackDevMiddleware must be the same

ContentBase

  • The contentBase in The devServer doesn’t have much to do with directly accessing a packaged resource, it does have to do with specifying where to look for it if the packaged resource is dependent on some other resource:

    • For example, in index.html, we need to rely on an abc.js file, which we store in a public file;
    • In index.html, how should we import this file?
      • For example, the code looks like this :;
      • The browser will not be able to find the folder through the relative path;
      • So the code looks like this :;
      • How do I get it to find out if this file exists? Just set contentBase;
  • There is, of course, another property in The devServer that can listen for changes to the contentBase and recompile it: watchContentBase.

The Proxy agent

Proxy is a common configuration option in our development, and its purpose is to set up proxies to solve cross-domain access problems

  • Set up the
    • Target: identify the agent to the destination address, for example, / API/moment will be acting to http://localhost:8888/api/moment
    • PathRewrite: By default, our/API is also written to the URL, which you can use if you want to remove it
    • Secure: Do not accept forwarding to HTTPS servers by default. Set this to false if you want to support this
    • ChangeOrigin: indicates whether to update the host address in the headers request after the agent
    • HistoryApiFallback: Resolve the error 404 when the SPA page is refreshed after the route is redirected
      • Boolean: The default value is false. If this value is set to true, an index. HTML is automatically returned when a 404 error is returned
      • Object value: You can configure the rewrites property
        • You can configure from to match the path, determine which page to jump to, and consult the official documentation for details.

Other Config

  • hotOnly

    • By default, the page will be refreshed after the code compilation failure is fixed. You do not want to refresh the hotOnly:true setting
  • Host Host address

    • The default value is localhost
    • Set 0.0.0.0 if other PCS have access
  • Difference between localhost and 0.0.0.0

    • Localhost is essentially a domain name that is resolved to 127.0.0.1
    • 127.0.0.1 is a loopback address, indicating that packets sent by the host are directly accepted by the host
      • Normal database packets are usually applied layer -> transport layer -> network layer -> data link layer -> physical layer
      • The loopback address, on the other hand, is obtained directly at the network contact layer
      • When listening for 127.0.0.1, hosts in the same network segment cannot be accessed through IP addresses.
    • 0.0.0.0: listens for all IPV4 addresses and finds different applications based on the port.
      • When listening 0.0.0.0, hosts on the same network segment can be accessed through their IP addresses.
  • Port

    • Set the listening port. The default value is 8080
  • Open Whether to open the browser

    • The default is false; true opens the browser
    • You can also set something similar to Google Chrome equivalents
  • Compress Specifies whether to enable GZIP Compression for static files

    • The default is false and can be set to true

Configuration of the sample

devServer: {
    hot: true.hostOnly:true.host:"0.0.0.0".port:8080.open:true.compress:true.proxy: {"/api": {target:"http://localhost:8888".pathRewrite: {"^/api":""
            },
            secure:false.changeOrigin:true}}}Copy the code

Hot Module Replacement

  • What is the HMR?

    • HMR Hot Module Replacement, which translates to Hot Module Replacement
    • Module hot replacement refers to the process of replacing, adding, and removing modules while the application is running without having to refresh the entire page.
  • HMR increases the speed of development in several ways.

    • Not reloading the entire page, so that some application state is not lost;
    • Update only what needs to change, saving development time
    • Changes to CSS and JS source code are immediately updated in the browser, which is equivalent to modifying styles directly in the browser’s DevTools.
  • How to use HMR?

    • By default, webpack-dev-server already supports HMR. You just need to enable it.
    • When HMR is not enabled, the entire page is automatically refreshed after the source code is modified. Live reloading is used.
  • How to open

    • Modify the webpack. Config. Js
module.exports = {
    entry: "./src/index.js".output: {
        filename: "js/bundle.js".path: path.resolve(__dirname, "build"),},watch:true.mode: "development".devServer: {hot:true}},Copy the code
  • Refresh the entire browser after the update, because you need to define modules that use HMR.
if(module.hot){
    module.hot.accept("./App.vue".() = >{
        console.log("Vue has been updated")})}Copy the code

Framework of HMR

One question: do we often need to manually write the MODULE.hot. accpet API when developing other projects?

  • For example, in the development of Vue and React projects, we have modified the components and hope to carry out hot update. How should we operate at this time?

  • The community already has well-established solutions for these:

    • For example, in vUE development, we use vue-Loader, which supports HMR for vUE components, providing out-of-the-box experience.
    • For example, there is a React Hot Loader in react development, which adjusts the React component in real time (now the react official deprecated, changed to use react-refresh).

The Vue HMR

  • Vue loading requires a Vue-Loader, which by default performs HMR processing

  • Install Vue dependencies

    • npm install vue-loader vue-template-compiler
  • Configuration Webpack. Config. Js

const VueLoaderPlugin = require("vue-loader/lib/plugin")

module: {
    rules: [{test: /\.vue$/,
            use: ["vue-loader"]},]},plugins: [new VueLoaderPlugin()]
Copy the code

The React of HMR

  • Previously, React used React Hot Loader to implement HMR. Now it has been changed to use React-Refesh to implement HMR

  • Installation-related Dependencies

    • npm install @pmmmwh/react-refresh-webpack-plugin react-refresh
  • webpack.config.js

const ReactRefreshWebpackPlugin = require("@pmmmwh/react-refresh-webpack-plugin")

plugins: [
    new ReactRefreshWebpackPlugin(),
],
Copy the code
  • babel.config.js
module.exports = {
    presets: [["@babel/preset-env", {
            useBuiltIns: "usage".corejs: 3.8
        }],
        ["@babel/preset-react"],
        ["@babel/preset-typescript"]],plugins: [['react-refresh/babel']]}Copy the code

The principle of HMR

  • So how does HMR work? How can I update only one module?

    • Webpack-dev-server creates two services: a static resource service (Express) and a Socket (net.socket)
    • Express Server is responsible for directly serving static resources (the packaged resources are directly requested and parsed by the browser)
  • The HMR Socket Server is a Socket long connection

    • One of the best benefits of a persistent connection is that both parties can communicate once the connection is established (the server can send files directly to the client).

    • Json (manifest file) and.js (update chunk) files are generated when the corresponding module changes are heard during the service.

    • Through the persistent connection, you can directly send the two files to the client.

    • After the browser gets the two new files, it loads them through the HMR Runtime mechanism and updates them for the modified modules.


  • Nuggets: LeBron on the front end

  • Zhihu: LeBron on the front end

  • Keep sharing technical blog posts, follow wechat public account 👉🏻 front-end LeBron