Dev

本章节描述了 Rsbuild 中与本地开发有关的配置。

dev.assetPrefix

  • 类型: boolean | string
  • 默认值: '/'

设置开发环境下的静态资源 URL 前缀。

assetPrefix 会影响构建产物中绝大部分静态资源的 URL,包括 JavaScript 文件、CSS 文件、图片、视频等。如果指定了一个错误的值,则在加载这些资源时可能会出现 404 错误。

该配置项仅用于开发环境。在生产环境下,请使用 output.assetPrefix 配置项进行设置。

Boolean 类型

如果设置 assetPrefixtrue,Rsbuild 会使用 http://localhost:port/ 作为 URL 前缀:

export default {
  dev: {
    assetPrefix: true,
  },
};

对应 JS 文件在浏览器中加载的地址如下:

<script defer src="http://localhost:8080/static/js/main.js"></script>

如果设置 assetPrefixfalse 或不设置,则默认使用 / 作为访问前缀。

String 类型

assetPrefix 的值为 string 类型时,字符串会作为前缀,自动拼接到静态资源访问 URL 上:

export default {
  dev: {
    assetPrefix: 'http://example.com/assets/',
  },
};

对应 JS 文件在浏览器中加载的地址如下:

<script defer src="http://example.com/assets/static/js/main.js"></script>

与原生配置的区别

dev.assetPrefix 对应以下原生配置:

它与原生配置的区别在于:

  • dev.assetPrefix 仅在开发环境下生效。
  • dev.assetPrefix 默认会自动补全尾部的 /
  • dev.assetPrefix 的值会写入 process.env.ASSET_PREFIX 环境变量。

dev.beforeStartUrl

  • 类型: () => Promise<void> | void
  • 默认值: undefined

dev.beforeStartUrl 用于在打开 startUrl 前执行一段回调函数,该配置项需要与 dev.startUrl 一同使用。

export default {
  dev: {
    startUrl: true,
    beforeStartUrl: async () => {
      await doSomeThing();
    },
  },
};

dev.client

  • 类型:
{
    /** 指定协议名称 */
    protocol?: string;
    /** 事件流路径 */
    path?: string;
    /** 指定监听请求的端口号 */
    port?: string;
    /** 指定要使用的 host */
    host?: string;
}
  • 默认值:
const defaultConfig = {
  path: '/rsbuild-hmr',
  // By default it is set to the port number of the dev server
  port: '',
  // By default it is set to "location.hostname"
  host: '',
  // By default it is set to "location.protocol === 'https:' ? 'wss' : 'ws'""
  protocol: '',
};

对应 HMR 客户端的配置,通常用于设置 HMR 对应的 WebSocket URL。

dev.compress

  • 类型: boolean
  • 默认值: true

是否对静态资源启用 gzip 压缩。

如果你需要禁用 gzip 压缩,可以将 compress 设置为 false

export default {
  dev: {
    compress: false,
  },
};

dev.devMiddleware

  • 类型:
{
  writeToDisk: boolean | ((filename: string) => boolean);
}
  • 默认值:
{
  writeToDisk: (file: string) => !file.includes('.hot-update.'),
}

devMiddleware 配置项。当前配置是 webpack-dev-middleware 配置项的子集.

dev.headers

  • 类型: Record<string, string>
  • 默认值: undefined

设置自定义响应头。

export default {
  dev: {
    headers: {
      'X-Custom-Foo': 'bar',
    },
  },
};

dev.historyApiFallback

  • 类型: boolean | ConnectHistoryApiFallbackOptions
  • 默认值: false

在需要对一些 404 响应或其他请求提供替代页面的场景,可通过 dev.historyApiFallback 进行设置:

export default {
  dev: {
    historyApiFallback: true,
  },
};

例如,当你使用客户端路由,希望所有页面请求都可以 fallback 到 index.html 时,可以配置成如下方式:

export default {
  dev: {
    historyApiFallback: {
      // 允许对 .html 请求进行 fallback
      rewrites: [{ from: /.*\.html/, to: '/index.html' }],
    },
  },
};

更多选项和详细信息可参考 connect-history-api-fallback 文档。

dev.hmr

  • 类型: boolean
  • 默认值: true

是否开启 Hot Module Replacement 热更新能力。

hmr 设置为 false 时,将不再提供热更新和 react-refresh 功能。

export default {
  dev: {
    hmr: false,
  },
};

dev.host

  • 类型: string
  • 默认值: 0.0.0.0

指定 dev server 启动时监听的 host。

默认情况下,dev server 会监听 0.0.0.0,这代表监听所有的网络接口,包括 localhost 和公网地址。

如果你希望 dev server 只监听 localhost,可以设置为:

export default {
  dev: {
    host: 'localhost',
  },
};

dev.https

  • 类型: boolean | { key: string; cert: string }
  • 默认值: false

配置该选项后,可以开启 Dev Server 对 HTTPS 的支持,同时会禁用 HTTP 服务器。

开启前:

  > Local:    http://localhost:8080/
  > Network:  http://192.168.0.1:8080/

开启后:

  > Local:    https://localhost:8080/
  > Network:  https://192.168.0.1:8080/

自动生成证书

你可以直接将 https 设置为 true,Rsbuild 会基于 devcert 来自动生成 Dev Server 所需的 HTTPS 证书。

使用这种方式时,你需要在当前项目中手动安装 devcert 依赖:

# npm
npm install devcert@1.2.2 -D

# yarn
yarn add devcert@1.2.2 -D

# pnpm
pnpm add devcert@1.2.2 -D

然后配置 dev.httpstrue 即可:

export default {
  dev: {
    https: true,
  },
};

该方式有一定局限性,由于 devcert 目前不支持 IP addresses,因此访问 Network 域名时,会遇到「您的连接不是私密连接」的问题。

此问题的解决方法为:点击 Chrome 浏览器问题页面的「高级」->「继续前往 192.168.0.1(不安全)」。

TIP

https 代理自动安装证书需要获取 root 权限, 请根据提示输入密码即可。 密码仅在信任证书时使用,不会泄漏或者用于其他环节

手动设置证书

你也可以在 dev.https 选项中手动传入 HTTPS 服务器所需要的证书和对应的私钥,这个参数将直接传递给 Node.js 中 https 模块的 createServer。

具体可以参考 https.createServer

import fs from 'fs';

export default {
  dev: {
    https: {
      key: fs.readFileSync('certificates/private.pem'),
      cert: fs.readFileSync('certificates/public.pem'),
    },
  },
};

dev.port

  • 类型: number
  • 默认值: 8080

设置 Dev Server 监听的端口号。

默认情况下,Dev Server 会监听 8080 端口,并在端口被占用时自动递增端口号。

示例

将端口设置为 3000

export default {
  dev: {
    port: 3000,
  },
};

dev.progressBar

  • 类型:
type ProgressBar =
  | boolean
  | {
      id?: string;
    };
  • 默认值: process.env.NODE_ENV === 'production'

是否在编译过程中展示进度条。

默认情况下,Rsbuild 仅会在生产环境构建时开启进度条。

  • 示例: 开启进度条。
export default {
  dev: {
    progressBar: true,
  },
};
  • 示例: 禁用进度条。
export default {
  dev: {
    progressBar: false,
  },
};
  • 示例: 修改进度条 id

如果你需要修改进度条左侧显示的文本内容,可以设置 id 选项:

export default {
  dev: {
    progressBar: {
      id: 'Some Text',
    },
  },
};

dev.proxy

  • 类型: Record<string, string> | Record<string, ProxyDetail>
  • 默认值: undefined

代理请求到指定的服务上。

export default {
  dev: {
    proxy: {
      '/api': 'http://localhost:3000',
    },
  },
};

此时,/api/users 请求将会代理到 http://localhost:3000/api/users。

如果你不想传递 /api,可以通过 pathRewrite 重写请求路径:

export default {
  dev: {
    proxy: {
      '/api': {
        target: 'http://localhost:3000',
        pathRewrite: { '^/api': '' },
      },
    },
  },
};

DevServer Proxy 基于 http-proxy-middleware 实现。你可以使用 http-proxy-middleware 的所有配置项,具体可以查看文档。

DevServer Proxy 完整类型定义为:

import type { Options as HttpProxyOptions } from 'http-proxy-middleware';

type ProxyDetail = HttpProxyOptions & {
  bypass?: (
    req: IncomingMessage,
    res: ServerResponse,
    proxyOptions: ProxyOptions,
  ) => string | undefined | null | false;
  context?: string | string[];
};

type ProxyOptions =
  | Record<string, string>
  | Record<string, ProxyDetail>
  | ProxyDetail[]
  | ProxyDetail;

除了 http-proxy-middleware 的选项外,还支持 bypass 和 context 两个配置项:

  • bypass:根据函数的返回值绕过代理。
    • 返回 nullundefined 会继续用代理处理请求。
    • 返回 false 会返回 404 错误。
    • 返回一个具体的服务路径,将会使用此路径替代原请求路径。
  • context:如果你想代理多个特定的路径到同一个目标,你可以使用 context 配置项。
// 自定义 bypass 方法
export default {
  dev: {
    proxy: {
      '/api': {
        target: 'http://localhost:3000',
        bypass: function (req, res, proxyOptions) {
          if (req.headers.accept.indexOf('html') !== -1) {
            console.log('Skipping proxy for browser request.');
            return '/index.html';
          }
        },
      },
    },
  },
};
// 代理多个路径到同一个目标
export default {
  dev: {
    proxy: [
      {
        context: ['/auth', '/api'],
        target: 'http://localhost:3000',
      },
    ],
  },
};

dev.setupMiddlewares

  • 类型:
Array<
  (
    middlewares: {
      unshift: (...handlers: RequestHandler[]) => void;
      push: (...handlers: RequestHandler[]) => void;
    },
    server: {
      sockWrite: (
        type: string,
        data?: string | boolean | Record<string, any>,
      ) => void;
    },
  ) => void
>;
  • 默认值: undefined

提供执行自定义函数和应用自定义中间件的能力。

中间件的执行顺序是: unshift => 内置中间件 => push

export default {
  dev: {
    setupMiddlewares: [
      (middlewares, server) => {
        middlewares.unshift((req, res, next) => {
          next();
        });

        middlewares.push((req, res, next) => {
          next();
        });
      },
    ],
  },
};

一些特殊场景需求可能需要使用服务器 API:

  • sockWrite。允许向 hmr 客户端传递一些消息,hmr 客户端将根据接收到的消息类型进行不同的处理。如果你发送一个 "content-changed " 的消息,页面将会重新加载。
export default {
  dev: {
    setupMiddlewares: [
      (middlewares, server) => {
        // 添加自定义 watcher 并在文件更新时触发页面刷新
        watcher.on('change', (changed) => {
          server.sockWrite('content-changed');
        });
      },
    ],
  },
};

dev.startUrl

  • 类型: boolean | string | string[] | undefined
  • 默认值: undefined

dev.startUrl 用于设置 Dev Server 启动时自动在浏览器中打开的页面 URL。

默认情况下,Dev Server 启动时不会打开任何页面。

你可以设置为如下的值:

export default {
  dev: {
    // 打开项目的默认页面,等价于 `http://localhost:<port>`
    startUrl: true,
    // 打开指定的页面
    startUrl: 'http://localhost:8080',
    // 打开多个页面
    startUrl: ['http://localhost:8080', 'http://localhost:8080/about'],
  },
};

端口号占位符

由于端口号可能会发生变动,你可以使用 <port> 占位符来指代当前端口号,Rsbuild 会自动将占位符替换为实际监听的端口号。

export default {
  dev: {
    startUrl: 'http://localhost:<port>/home',
  },
};

打开指定浏览器

在 MacOS 上,通过设置环境变量 BROWSER,你可以指定 Dev Server 在启动时打开的浏览器,支持如下的值:

  • Google Chrome Canary
  • Google Chrome Dev
  • Google Chrome Beta
  • Google Chrome
  • Microsoft Edge
  • Brave Browser
  • Vivaldi
  • Chromium

建议设置在.env.local文件中。