Skip to content
大纲

开发环境

常见需求

开发模式下对更关注构建的效率, 常见的需求有

  • 自动构建: 当模块内容变化时, 期望能监听到变化并自动编译
  • 无刷新响应: 当模块内容变化时, 期望能自动编译但不自动刷新页面
  • 源代码映射: 开发中 debug, 查看输出时, 期望准确定位至源文件中

自动构建

自动构建有以下几种处理方式

  • 使用 webpack 的观察模式 (最易)
  • 使用 webpack-dev-server (常用)
  • 使用 webpack-dev-middleware (灵活)

启用观察模式

观察模式下 webpack 将监听文件内容的变化并进行自动构建,该方式无法自动刷新

package.json

json
"scripts:" {
  "watch": "webpack --watch"
}

使用 webpack-dev-server

webpack-dev-server 将开启一个 web 服务器,并监听文件内容变化并自动构建,同时自动刷新页面; 其相关选项在 devServer 字段中配置

安装依赖

shell
npm i --save-dev webpack-dev-server

package.json

json
"scripts": {
  "start": "webpack-dev-server --open --mode=development"
}

webpack.config.js

js
module.exports = {
  // ...others
  devServer: {
    // 这里列出常见的配置, 大部分配置使用默认值即可

    hot: true, // 模块热替换, 需要同时添加 webpack.HotModuleReplacementPlugin 插件

    https: true,
    host: 'localhost',
    port: 8080,
    allowedHosts: ['.host.com', 'xxoo.host.com'], // 白名单, '.' 表示任意子域名
    proxy: {
      '/router': 'http://localhost:3000/router'
    },

    historyApiFallback: true // history 模式下, 将 404 响应替换为 index.html; 可以指定一个对象进行深度配置
    defore(app) {}, // 在服务内部的所有中间件之前执行
    after(app) {}, // 在服务内部的其他中间件执行后执行

    publicPath: '/assets/', // 此路径下的打包文件可在浏览器中访问, 确保总是以 '/' 开头和结尾 或使用完整的 URL
    contentBase: './dist', // 提供内容的目录, 在提供静态文件时才需要, 优先级低于 publicPath

    open: true, // 自动打开浏览器
    openPage: '/', // 指定打开浏览器的页面

    clientLogLevel: 'info', // 'info' | 'none' | 'error' | 'warning' 控制 console 输出信息内容
    color: true, // 开启命令行彩色输出
    progress: true, // 显示进度

    compress: false, // 关闭 gzip 压缩
  }
}

使用 webpack-dev-middleware

webpack-dev-middleware 是一个中间件模块, 会将 webpack 处理后的内容传递给一个服务器, webpack-dev-server 内部使用了该中间件, 该中间件也可以配合其他服务单独使用。

webpack.config.js

js
// 来自官网的示例, 需要安装 express 和 webpack-dev-middleware

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

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

// Tell express to use the webpack-dev-middleware and use the webpack.config.js
// configuration file as a base.
app.use(
  webpackDevMiddleware(compiler, {
    publicPath: config.output.publicPath,
  })
);

// Serve the files on port 3000.
app.listen(3000, function () {
  console.log("Example app listening on port 3000!\n");
});

package.json

json
{
  "script": {
    "server": "node server.js"
  }
}

无刷新响应

使用 webpack-dev-server 时,每次更新时会自动刷新页面,在大多数情况下期望页面无刷新就能响应模块的变化。

webpack 中使用 模块热替换(HMR) 实现无刷新响应的功能

启用 HMR 插件

在配置文件中添加插件

webpack.config.js

js
const webpack = require("webpack");

module.exports = {
  // others...
  devServer: {
    hot: true, // 开启 HMR
  },
  plugins: [
    // others...
    new webpack.HotModuleReplacementPlugin(), // HMR 插件
    new webpack.NamedModulesPlugin(), // 开启 HMR 时显示模块相对路径
  ],
};

添加处理逻辑

开启 HMR 后需要在相应的模块中添加处理逻辑

index.js

js
//假设需要热替换 test 文件
import test from "test";
module.hot &&
  module.hot.accept("./test.js", function () {
    test();
  });

注意: 若 DOM 绑定了 HMR 中处理的方法, 在处理模块替换时并不会更新对应的监听器, 需要手动重新处理

loader 自处理

一些常用的 loader 内部会自行行使用 module.hot.accept 处理 HMR 的逻辑, 常见的有

  • style-loader, css-loader
  • vue-loader
  • react-hot-loader
  • elm-hot-loader
  • angular-hmr

源代码映射

源代码映射(Source Map)用于将构建后的代码映射至对应的源码, 可以通过以下方式开启

注意

  • SourceMapDevToolPlugin / EvalSourceMapDevToolPlugin 插件提供了更加详细的配置
  • devtool 选项内部使用了 SourceMapDevToolPlugin / EvalSourceMapDevToolPlugin 插件
  • devtoolSourceMapDevToolPlugin / EvalSourceMapDevToolPlugin 不要并用(会重复执行)

基本配置

webpack.config.js

js
module.exports = {
  // ...others
  devtool: "source-map",
};

配置选项

devtool 提供了默认的 false 及其他多种选项,这些选项为以下基本选项的组合

  • inline: 不会生成独立的 map 文件而是以 dataURL 形式插入
  • cheap: 会忽略源文件中列信息, 可以提高构建速度
  • module: 包含了 loader 之间的 source map
  • eval
    • 构建和重新构建速率高
    • 会生成 //@ sourceURL 进行映射关联
    • 不会生成 source-map 文件
    • 只能映射至转换后的代码, 而非源码
  • source-map
    • 为每个打包后模块生成独立的 sorce map 文件

常用选项

对于开发环境

  • eval-source-map: 用于生成最佳品质的 source map
  • cheap-module-eval-source-map: 低开销的 source map , 会忽略列映射

对于生成环境

  • false 或省略
  • source-map: 生成独立的 source map 文件, 应当禁止普通用户访问这些文件
  • hidden-source-map: 用于错误报告工具, 不应当部署至服务器
  • nosources-source-map: 不包含源码内容, 用于映射堆栈跟踪, 可以部署至服务器

推荐的选项

  • 开发环境: cheap-module-eval-source-map
  • 生成环境: cheap-module-source-map