创见博客
webpack 开发服务器(devServer)是什么,如何搭建
七崽爱吃小饼干2026/09/15阅读 0专栏 webpack构建基础

在前面的文章里,我们一直在用 npm run build 打包,然后手动打开 dist/index.html 看效果。但真实开发中,改一行代码就要重新构建、再手动刷新浏览器,效率极低。**开发服务器(dev server)**就是为了解决这个问题而存在的。

一、开发服务器是什么

开发服务器本质上是一个跑在本地的 HTTP 服务,它接管了「编译 + 提供页面」这两件事:

  • 它在构建时启动,把 webpack 的打包结果放到内存里(而不是写磁盘)。
  • 它对外提供一个本地地址(如 http://localhost:8080),你直接用浏览器访问就能看到页面。
  • 它监听源码变化,自动重新编译,并通过热更新或自动刷新把最新结果推给浏览器。

换句话说,它把「改代码 → 打包 → 刷新」这一串手动操作全部自动化了。

二、为什么需要它

手动打包使用 dev server
每次改动都要重新 build改动后自动重新编译
产物写到磁盘,频繁 IO产物存内存,读写更快
需要手动刷新浏览器自动刷新 / 热更新
用 file:// 打开,受同源策略限制本地 HTTP 服务,行为接近线上
跨域接口无法直接请求支持代理转发解决跨域
出错要点开 devtools 找错误可直接覆盖在页面上

其中「内存编译」很关键:dev server 使用 memory-fs,产物不落盘,所以速度远快于一次次写 dist。

三、安装与基本配置

webpack 5 中,dev server 由 webpack-dev-server 提供,通过 webpack-cli 的 serve 命令启动:

bash
npm install webpack-dev-server --save-dev

在 webpack.config.js 中配置:

js
module.exports = {
  mode: 'development',
  devServer: {
    static: './dist',
    port: 8080,
    open: true,
  },
};

并在 package.json 添加脚本:

json
{
  "scripts": {
    "dev": "webpack serve --mode development",
    "build": "webpack"
  }
}

之后运行:

bash
npm run dev

浏览器会自动打开 http://localhost:8080,修改源码保存后页面会自动更新。

四、常用配置项

js
module.exports = {
  devServer: {
    // 静态资源目录(即 output.path)
    static: {
      directory: path.resolve(__dirname, 'dist'),
    },
    port: 8080,          // 端口
    host: '0.0.0.0',     // 允许局域网访问
    open: true,          // 启动后自动打开浏览器
    hot: true,           // 开启热更新(HMR)
    compress: true,      // 开启 gzip 压缩
    historyApiFallback: true, // SPA 路由回退
    client: {
      overlay: true,     // 编译错误覆盖到页面上
    },
  },
};

几个重点:

  • static:指定静态文件服务目录。如果用了 HtmlWebpackPlugin,通常指向 output.path。
  • hot:开启模块热替换(详见下一节)。
  • client.overlay:编译报错时在页面上显示红色遮罩,比翻控制台快得多。

五、热更新(HMR)

热更新(Hot Module Replacement)让修改模块时无需刷新整个页面,只替换改动的部分,从而保留页面状态(比如表单内容、组件内部状态)。

配置只需开启:

js
devServer: {
  hot: true,
}

配合 HtmlWebpackPlugin 时,HMR 是开箱即用的。若要让某个模块在更新后执行自定义逻辑,可以监听 module.hot:

js
if (module.hot) {
  module.hot.accept('./utils.js', () => {
    console.log('utils.js 已更新');
  });
}

webpack 5 中,CSS 的 HMR 也是自动生效的,改样式无需刷新页面。若只想用 HMR、拒绝「HMR 失败时整页刷新」的降级行为,可设为 hot: 'only'。

六、代理:解决跨域

开发时前端页面和接口通常不同源,浏览器会拦截跨域请求。dev server 的 proxy 把请求转发到后端服务器,从而绕过跨域限制:

js
devServer: {
  proxy: [
    {
      context: ['/api'],
      target: 'http://localhost:3000',
      changeOrigin: true,
      pathRewrite: { '^/api': '' },
    },
  ],
}

这样前端请求 /api/user,实际会被转发到 http://localhost:3000/user。

注意 webpack 5 中 proxy 推荐写成数组形式,每一项用 context 指定要匹配的路径。

七、单页应用路由回退

使用 React Router、Vue Router 的 history 模式时,刷新 /user/123 会向服务器请求该路径,而服务器上并不存在这个文件,导致 404。historyApiFallback 会把这类请求都回退到 index.html:

js
devServer: {
  historyApiFallback: true,
}

八、与生产构建的区别

开发服务器生产构建
产物位置内存磁盘 dist/
模式developmentproduction
优化无(构建快)Tree Shaking、压缩
用途本地开发调试部署上线

所以 dev server 只用于开发,部署时依然要跑 npm run build。可以把两者配置拆成 webpack.dev.js 和 webpack.prod.js,再用 webpack-merge 合并公共部分。

九、完整配置示例

js
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
  mode: 'development',
  entry: './src/index.js',
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: 'js/[name].js',
  },
  module: {
    rules: [
      { test: /\.css$/i, use: ['style-loader', 'css-loader'] },
    ],
  },
  plugins: [
    new HtmlWebpackPlugin({ template: './public/index.html' }),
  ],
  devServer: {
    static: path.resolve(__dirname, 'dist'),
    port: 8080,
    open: true,
    hot: true,
    compress: true,
    historyApiFallback: true,
    client: { overlay: true },
    proxy: [
      {
        context: ['/api'],
        target: 'http://localhost:3000',
        changeOrigin: true,
      },
    ],
  },
  devtool: 'eval-cheap-module-source-map', // 便于调试
};

小结

开发服务器的价值,在于把开发阶段重复的「编译、刷新、跨域调试」全部自动化:

能力对应配置
本地 HTTP 服务static / port / host
自动刷新与热更新hot / client
解决跨域proxy
SPA 路由回退historyApiFallback
错误可视化client.overlay
便于调试devtool

搭建它只需要 webpack-dev-server + 一段 devServer 配置 + 一个 webpack serve 脚本。掌握这些,开发体验会有质的提升。

评论
0/100