webpack——devServer开发环境基本配置

7,553 阅读6分钟

111.jpg

devServer

在除了五大基础模块外呢,webacpk还有一个devServer模块,今天就来分析一下devServer这个模块。

  • 首先为什么需要devServer,他的应用场景是什么呢 ?

       应用场景:
       当我们创建了一个HTML文件,并在里面写入 Hello world, 这个时候我们使用webpack命令,对这个html进行打包,
    并看打包后的html效果,页面中会呈现出 Hello world,但是当我们再次修改原文件html为 Hello Hello world,
    这个时候我们需要重新使用webpack命令进行打包,然后才能看到打包后的html效果。每当我们修改的频率越来越多了,
    这样的重复动作会使我们的效率十分低下,这个时候就需要webpack提供的devServer了
       简单的来说devServer就是帮助我们提高开发效率的一个配置
    

    作用:帮我们自动的打包代码,开发者只需要进行开发源代码就行了,不用多次webpack了

    虽然webpack提供了 webpack --watch 的命令来 动态监听文件的改变并实时打包,输出新bundle.js文件,这样文件多了之后打包速度会很慢,此外这样的打包的方式不能做到hot replace,即每次webpack编译之后,你还需要手动刷新浏览器。

    module.exports = {
         entyr:{},
         output:{},
         module:{},
         plugins:[],
         devServer:{
               //我们在这里对webpack-dev-server进行配置
         }                
    }
    

关于完整的 devServer 我罗列几个常用项做简单介绍。

  • contentBase
    即 contentBase,如下方示例配置为 path.join(__dirname, "src/html"),后续访问 http://localhost:3333/index.html 时,server 会从 src/html 下去查找 index.html 文件
    // 它可以是单个或多个地址的形式:
    contentBase: path.join(__dirname, "public")   
    // 多个:   
    contentBase: [path.join(__dirname, "public"), path.join(__dirname, "assets")]  
    // 若不填写该项,默认为项目根目录。
  • port
    即监听端口,默认为8080。

  • compress
    传入一个 boolean 值,通知 server 是否启用 gzip
    强烈建议使用 : 压缩后通常能帮我们减少响应 70% 左右的大小;

  • hot | hotOnly 传入一个 boolean 值,通知 server 是否启用 HMR。

  • open 传入一个 boolean 值 运行之后自动打开默认浏览器

  • https
    可以传入 true 来支持 https 访问,也支持传入自定义的证书

   https: true   
   //也可以传入一个对象,来支持自定义证书  
   https: {    
         key: fs.readFileSync("/path/to/server.key"),  
         cert: fs.readFileSync("/path/to/server.crt"),  
         ca: fs.readFileSync("/path/to/ca.pem"),  
   }  
  • proxy
    代理配置,适用场景是,除了 webpack-dev-server 的 server(server A) 之外,还有另一个在运行的 server(server B),而我们希望能通过 server A 的相对路径来访问到 server B 上的东西。
举个例子:
    devServer: {
        contentBase: path.join(__dirname, "src/html"),
        port: 3333,
        hot: true,
        proxy: {
            "/api": "http://localhost:5050"
        }
    }

运行 webpack-dev-server 后,你若访问 http://localhost:3333/api/user, 则相当于访问 http://localhost:5050/api/user。

  • setup
    webpack-dev-server 的服务应用层使用了 express,故可以通过 express app 的能力来模拟数据回包,devServer.setup 方法就是干这事的:
 devServer: {
    contentBase: path.join(__dirname, "src/html"),
    port: 3333,
    hot: true,
    setup(app){  //模拟数据
        app.get('/getJSON', function(req, res) {
            res.json({ name: 'vajoy' });
        });
    }
}

然后我们可以通过请求 http://localhost:3333/getJSON 来取得模拟的数据:

热更新

 webpack-dev-sever支持两种自动刷新方式 —— Iframe mode、Inline mode。

Iframe mode和Inline mode最后达到的效果都是一样的,都是监听文件的变化,然后再将编译后的文件推送到前端,完成页面的reload的。

  • Iframe mode

    使用iframe模式不需要配置任何东西,只需要在你启动的项目的端口号后面加上/webpack-dev-server/即可;

    比如:http://localhost:8080/webpack-dev-server/ ,只需使用特定的URL格式访问即可;

    Iframe mode是在网页中嵌入了一个iframe,将我们自己的应用注入到这个iframe当中去,因此每次你修改的文件后,都是这个iframe进行了reload。

  • Inline mode

    设定webpack-dev-server服务的目录,如果不进行设定的话,默认是在当前目录下。

webpack-dev-server 的常用功能之一——静态资源访问

  • webpack-dev-server 默认会将构建结果和输出文件全部作为开发服务器的资源文件,也就是说,只要通过 Webpack 打包能够输出的文件都可以直接被访问到;
    但是如果你还有一些 没有参与打包的静态文件 也需要作为开发服务器的资源被访问,那你就需要额外通过配置“告诉” webpack-dev-server。

  • 具体的方法就是在 webpack-dev-server 的配置对象中添加一个对应的配置。我们回到配置文件中,找到 devServer 属性,它的类型是一个对象,我们可以通过这个 devServer 对象的 contentBase 属性指定额外的静态资源路径。这个 contentBase 属性可以是一个字符串或者数组,也就是说你可以配置一个或者多个路径。

可以选择在命令行中启动的时候加这个参数:

webpack-dev-server --content-base ./public

热替换(HMR)

当我们使用webpack-dev-server的自动刷新功能时,浏览器会整页刷新。 而热替换的区别就在于,当前端代码变动时,无需刷新整个页面,只把变化的部分替换掉。

HMR能够实现在页面不刷新的情况下,代码也可以及时的更新到浏览器的页面中,重新执行,避免页面状态丢失。

开启 HMR 功能实现方法

HMR 已经集成在了 webpack 模块中了,所以不需要再单独安装什么模块。

  1. 使用这个特性最简单的方式就是,在运行 webpack-dev-server 命令时,通过 hot 参数去开启这个特性。

  2. 也可以在配置文件中通过添加对应的配置来开启这个功能。那我们这里打开配置文件,这里需要配置两个地方:

    首先需要将 devServer 对象中的 hot / hotOnly 属性设置为 true; 然后需要载入一个插件,这个插件是 webpack 内置的一个插件,所以我们先导入 webpack 模块,有了这个模块过后,这里使用的是一个叫作 HotModuleReplacementPlugin 的插件。

module.exports = {
  devServer: {
    // 开启 HMR 特性,如果资源不支持 HMR 会 fallback 到 live reloading
    hot: true
    // 只使用 HMR,不会 fallback 到 live reloading
    // hotOnly: true
  },
  plugins: [
    // ...
    // HMR 特性所需要的插件
    new webpack.HotModuleReplacementPlugin()
  ]
}

此时Webpack可以实现css的热替换;但不能实现js、图片等的热替换,此二者需要自己手动通过代码来处理。

!!! 这里注意 我们css的loader会自动处理了样式文件的热更新