二、devServer

196 阅读3分钟

为什么要搭建本地服务器

  • 目前我们开发的代码,为了运行需要有两个操作:
    • 操作一:npm run build,编译相关的代码;
    • 操作二:通过live server或者直接通过浏览器,打开index.html代码,查看效果;
  • 这个过程经常操作会影响我们的开发效率,我们希望可以做到,当文件发生变化时,可以自动的完成 编译 和 展示;
  • 为了完成自动编译,webpack提供了几种可选的方式: p
    • webpack watch mode;
    • pwebpack-dev-server(常用);
    • pwebpack-dev-middleware;

Webpack watch

  • webpack给我们提供了watch模式:

    • 在该模式下,webpack依赖图中的所有文件,只要有一个发生了更新,那么代码将被重新编译;
    • 我们不需要手动去运行 npm run build指令了;
  • 如何开启watch呢?两种方式:

    • 方式一:在导出的配置中,添加 watch: true;
    • 方式二:在启动webpack的命令中,添加 --watch的标识;
  • 这里我们选择方式二,在package.json的 scripts 中添加一个 watch 的脚本:

     "scripts": {
        "build": "webpack --watch"
      },//webpack-cli 会自动处理成方式一
    
  • 上面的方式可以监听到文件的变化,但是事实上它本身是没有自动刷新浏览器的功能的:

    • 当然,目前我们可以在VSCode中使用live-server来完成这样的功能;

    • 但是,我们希望在不使用live-server的情况下,可以具备live reloading(实时重新加载)的功能;

  • 安装webpack-dev-server

    npm install webpack-dev-server -D

  • 修改配置文件,告知 dev server,从什么位置查找文件:

  • webpack-dev-server 在编译之后不会写入到任何输出文件,而是将 bundle 文件保留在内存中:

    • 事实上webpack-dev-server使用了一个库叫memfs(memory-fs webpack自己写的)
    target: "web",
    //...
    devServer: {
    static: { directory: "./public" },
    hot: true,
    },
    

模块热替换(HMR)

  • 什么是HMR呢?
    • HMR的全称是Hot Module Replacement,翻译为模块热替换;
    • 模块热替换是指在 应用程序运行过程中,替换、添加、删除模块,而无需重新刷新整个页面;
  • HMR通过如下几种方式,来提高开发的速度:
    • 不重新加载整个页面,这样可以保留某些应用程序的状态不丢失;
    • 只更新需要变化的内容,节省开发的时间;
    • 修改了css、js源代码,会立即在浏览器更新,相当于直接在浏览器的devtools中直接修改样式;
  • 如何使用HMR呢?
    • 默认情况下,webpack-dev-server已经支持HMR,我们只需要开启即可;
    • 在不开启HMR的情况下,当我·们修改了源代码之后,整个页面会自动刷新,使用的是live reloading;

开启HMR

  • webpack中配置

      devServer: {
        static: { directory: "./public" },
        hot: true,//通过hot开启
        open: true,
      },
    
  • 在对应文件中,使用module.hot来进行HMR

    import "./js/element";
    if (module.hot) {
      module.hot.accept("./js/element.js", () => {
        console.log("element模块发生更新了!");
      });
    }
    

    js文件的热更新不会引起浏览器的重新渲染,如果js有创建dom,不会替换原来元素,而是新增,需要在module.hot中对更新前的dom删除处理

HMR原理

  • 基于WS通信,替换更新模块
  • fs watch监听文件更改

PROXY

    proxy: {
        "/api": {
          target: "http://loaclhost:8888", //目标地址
          pathRewrite: "", //重写路径
          secure: true, //接受在 HTTPS 上运行且证书无效的后端服务器
          changeOrigin: true, //改变主机头的来源
        },
    }