zoukankan      html  css  js  c++  java
  • webpack 之 webpack-dev-server自动刷新

    watch

      首先介绍watch选项,参考这里。可实现相关源文件改变后自动更新bundle.js文件的功能。在配置文件中添加 watch:true 或执行 webpack -w,即可开启watch功能;

      测试发现,与(一个或多个)bundle.js有关的所有js、css等模块发生变化,就会自动执行打包,更新硬盘上的bundle.js文件

    webpack-dev-server

      webpack-dev-server默认开启以上的监视功能。但两者监视效果存在差异:

    1. webpack-dev-server自带的监视自动打包功能,新打包的文件存在于内存中,对硬盘上的bundle.js无影响。新文件的内存路径与配置文件中的publicPath相关,如http://localhost:8080/{publicPath}/bundle.js
    2. 手动执行webpack -w来启动的watch效果,会修改硬盘上的bundle.js文件

      假如在配置文件中配置了publicPath(没有配置的话默认是是  /):

        output: {
            path: __dirname + "/dist",
            filename: "bundle.js",
            publicPath: "/p/"
        },

      则webpack-dev-server 的监视功能只会更新内存中的文件,如 以上就是http://localhost:8080/p/bundle.js(该页面不会自动刷新)。但这个 http://localhost:8080/webpack-dev-server/p/bundle.js 这个路径下的文件也会更新,而且会自动刷新。

      到这里可以理解为:

    1. 打包后文件的内存路径 = devServer.contentBase + output.publicPath + output.filename,只能通过浏览器来访问这个路由来访问内存中的bundle
    2. 使用webpack打包更新的文件硬盘路径 = output.path + output.filename
    3. 在路由前加上/webpack-dev-server/,只要源文件发生变化,这个地址下的页面都会自动刷新。以上面的/webpack-dev-server/p/bundle.js为例,自动刷新后页面的内容为/p/bundle.js。(这里实际就是后面会说到的iframe模式)

      对于publicPath,有两个用处:

    1. 像以上的被webpack-dev-server作为在内存中的输出目录。
    2. 被其他的loader插件所读取,修改url地址等。

    自动刷新

      根据文档的提示。自动刷新有两种方式:

    iframe模式

      使用这个模式不需要任何的配置,但需要改变页面的访问路径,比如要访问根目录下的首页,源链接是 http://localhost:8080/index.html 需要换成http://localhost:8080/webpack-dev-server/index.html 。访问这个连接时,查看页面的dom结构,发现页面是嵌入到一个iframe中显示的:

    修改相关联模块文件时,这个页面会自动刷新。

    inline模式

      这个模式中有两种使用方式,分别是node和html方式。inline模式下访问页面不需要像iframe模式那样需要改变访问的路径,inline模式下只需要访问源路径即可

    html方式:在需要自动刷新的页面中添加如下脚本即可,不需要像文档所说那样需要添加 --inline参数 或者 配置添加 devServer: { inline: true }

    <script src="http://localhost:8080/webpack-dev-server.js"></script>

      理解就是当webpack-dev-server自带的watch检测到变化时,会通过以上的这个js来使浏览器自动刷新

    node方式:

      对于这里的理解实际就是,不直接运行webpack-dev-server指令了,而是通过node来启动webpack-dev-server。node代码如下:

    var config = require("./webpack.config.js");
    var webpack = require("webpack");
    var WebpackDevServer = require("Webpack-dev-server");
    config.entry.unshift("webpack-dev-server/client?http://localhost:8080/");
    var compiler = webpack(config);
    var server = new WebpackDevServer(compiler, {});
    server.listen(8080);

      光光运行这段代码是没办法使浏览器自动刷新的,因为这效果仅仅是运行了webpack-dev-server而已,还需要配合以上说的html方式来使浏览器自动刷新。

    总结inline模式

      就是直接或通过node来间接启动webpack-dev-server来检测文件变化,自动打包,然后再html中添加一个额外js来使浏览器自动刷新。以上代码中允许webpack的动态配置,即在js中配置运行,而不需要去修改配置文件。

    回顾一个重点

      webpack-dev-server检测到变化自动打包后,新打包后的文件实际上存在于内存中,而硬盘上的bundle.js依然是旧的。所以就算浏览器自动刷新了,读取的是硬盘上的文件,页面刷新后,还是和刷新前的页面一样。

    解决办法有两个:

    1. 使页面读取内存中的文件。将页面中的bundle.js路径修改为内存路径(上文有提到),不推荐这种方式
    2. 更新硬盘上的文件。即开启webpack-dev-server的同时,开始webpack -w。前者的作用时使浏览器自动刷新,后者的作用是更新硬盘上的文件。
    3. 【推荐】。在webpack的output配置中,使文件的输出路径与内存路径一致。如:
      output: {
          filename: 'bundle.js',
          path: path.resolve(__dirname, 'dist'),
          publicPath:"dist"
      },
      devServer: {
           contentBase: "."
      }
      
      // 或者
      output: {
          filename: 'bundle.js',
          path: path.resolve(__dirname, 'dist'),
      },
      devServer: {
          contentBase: './dist',
          hot: true
      }

      因为webpack-dev-server对于文件请求会优先到内存中查找,没有的话再转到硬盘上。所以这样浏览器访问/dist/bundle.js时,能访问到内存中的文件,而且当没有启动server时,访问的刚好就是对应文件在硬盘上的路径。这样一来,在开发的时候,修改和读取的文件都是内存中的文件,能提升开发效率。

      而且更重要的是,不这么配置的话,hmr会无效的。

  • 相关阅读:
    浏览器渲染
    微信h5页面制作总结
    chrome开发工具指南之综述
    零碎记录
    docker 容器已经启动,但是无法访问
    Docker的安装及使用
    python目录选择
    centos7 设置进程开机自启动
    语句中传入变量
    kafka -> structuredStreaming读取kafka日志 ->自定义输出到mysql
  • 原文地址:https://www.cnblogs.com/hellohello/p/7794392.html
Copyright © 2011-2022 走看看