首页
/ Modern.js 项目中的 Builder 插件核心机制解析

Modern.js 项目中的 Builder 插件核心机制解析

2025-07-08 06:05:30作者:余洋婵Anita

前言

Modern.js 是一个现代化的前端开发框架,其中的 Builder 模块提供了强大的构建能力。本文将深入解析 Builder 插件系统的核心机制,帮助开发者理解如何创建和使用 Builder 插件来扩展构建功能。

Builder 插件基础

Builder 插件是扩展构建功能的核心方式,每个插件都是一个包含特定属性和方法的对象。插件的基本结构如下:

type BuilderPlugin<API = BuilderPluginAPI> = {
  name: string;          // 插件唯一标识
  pre?: string[];        // 前置插件列表
  post?: string[];       // 后置插件列表
  remove?: string[];     // 需要移除的插件列表
  setup: (api: API) => Promise<void> | void;  // 插件初始化函数
};

插件生命周期

  1. 初始化阶段:当 Builder 启动时,所有插件的 setup 函数会被调用一次
  2. 执行顺序调整:根据 prepost 配置调整插件执行顺序
  3. 插件过滤:根据 remove 配置移除不需要的插件

插件执行顺序控制

Builder 提供了两种方式精确控制插件的执行顺序:

1. 前置插件(pre)

通过 pre 属性可以声明当前插件必须在哪些插件之后执行:

const pluginA = {
  name: 'plugin-a'
};

const pluginB = {
  name: 'plugin-b',
  pre: ['plugin-a']  // 确保 pluginA 在 pluginB 之前执行
};

2. 后置插件(post)

通过 post 属性可以声明当前插件必须在哪些插件之前执行:

const pluginA = {
  name: 'plugin-a'
};

const pluginB = {
  name: 'plugin-b',
  post: ['plugin-a']  // 确保 pluginA 在 pluginB 之后执行
};

插件移除机制

Builder 允许一个插件移除其他插件,这在需要禁用某些默认插件时非常有用:

const defaultPlugin = {
  name: 'default-plugin'
};

const customPlugin = {
  name: 'custom-plugin',
  remove: ['default-plugin']  // 移除 default-plugin
};

插件 API 详解

Builder 为插件提供了丰富的 API,主要通过 setup 函数的参数 api 来访问。

1. 上下文信息

api.context 提供了构建时的上下文信息,包括:

  • 项目根目录路径
  • 构建输出目录路径
  • 当前构建模式(development/production)
  • 其他构建相关配置
setup(api) {
  console.log(api.context.distPath);  // 输出构建目录路径
}

2. 配置获取

Builder 提供了多种获取配置的方式:

获取原始配置

const config = api.getBuilderConfig();

获取标准化后的配置

const normalizedConfig = api.getNormalizedConfig();

标准化配置会对原始配置进行合并和默认值填充,推荐使用这种方式获取配置。

3. 插件状态检查

const exists = api.isPluginExists('plugin-name');

这个方法可以检查特定插件是否已经被注册。

4. HTML 路径获取

const htmlPaths = api.getHTMLPaths();

这个方法返回所有 HTML 入口文件的路径映射,在多页面应用场景下非常有用。

多构建器支持

Builder 支持多种底层构建工具(如 webpack 和 Rspack),因此插件 API 也有不同的变体:

1. Webpack 专用插件

import type { BuilderPluginAPI } from '@modern-js/builder-webpack-provider';

const plugin: BuilderPlugin<BuilderPluginAPI> = {
  setup(api) {
    api.modifyWebpackConfig(config => {
      // 修改 webpack 配置
    });
  }
};

2. Rspack 专用插件

import type { BuilderPluginAPI } from '@modern-js/builder-rspack-provider';

const plugin: BuilderPlugin<BuilderPluginAPI> = {
  setup(api) {
    api.modifyRspackConfig(config => {
      // 修改 Rspack 配置
    });
  }
};

3. 通用插件

如果需要开发同时支持 webpack 和 Rspack 的插件,可以使用通用 API:

import type { DefaultBuilderPlugin } from '@modern-js/builder-shared';

const plugin: BuilderPlugin<DefaultBuilderPlugin> = {
  setup(api) {
    api.modifyBundlerChain(chain => {
      // 修改通用构建配置
    });
  }
};

最佳实践

  1. 命名规范:插件名称应使用 builder-plugin- 前缀,保持一致性
  2. 明确依赖:使用 prepost 明确声明插件依赖关系
  3. 配置访问:优先使用 getNormalizedConfig 获取标准化后的配置
  4. 构建器兼容:如果可能,尽量开发通用插件以支持多种构建器

总结

Modern.js 的 Builder 插件系统提供了灵活强大的扩展机制,通过本文的介绍,开发者应该能够:

  • 理解插件的基本结构和生命周期
  • 掌握控制插件执行顺序的方法
  • 熟悉常用的插件 API
  • 了解如何开发支持多种构建器的插件

合理使用插件系统可以极大地扩展 Builder 的功能,满足各种复杂的构建需求。